从零开始搭建react项目(一)

article/2025/7/29 7:43:14

自学react有一段时间了,官网文档基础的看了一遍,然后便把之前公司做的一个vue项目用react搭建了下,顺便整理下一些知识点。

项目大概效果:

一、利用create-react-app搭建项目

1、全局安装create-react-app,执行:npm install -g create-react-app 命令进行安装

2、进入要安装项目的文件夹,执行:npx create-react-app my-app 创建一个my-app项目

3、进入项目cd my-app,执行:npm start 编译启动项目即可

二、引入公用的css和脚本(rem.js移动端适配用)

一开始我是直接在src文件夹下新建了个assets文件夹,用来放置各种资源文件,然后直接在public文件下的index.html文件中直接用link和script引入css和脚本,但是引入脚本却报错了(Uncaught SyntaxError: Unexpected token < )百度了下也没明白是什么原因,然后解决办法就是:把assets文件夹放到和index.html同级目录下再引入就可以了。

搭建页面(以首页为例)

1、在src文件夹下新建assets(放置资源文件)、component(放置公用的组件)、pages(放置页面)文件夹。

2、创建页面及对应的样式文件,并通过import '路径',直接引入,然后ClassName=“类名”来引用。

3、创建组件:可以通过es5原生方式React.createClass定义的组件,或者 es6形式的extends React.Component定义的组件(需要手动绑定this),这边采用后者来创建

//es5
const MyComponent=React.createClass({render:function () {return <h1>mycomponent</h1>}})//es6
class MyConponent extends React.Component{constructor(props){super(props);}render() {return (<h1>mycomponent</h1>);}}

四、遇到的几个问题如下:

(1)import直接引入css样式的话,会导致css样式成为全局样式,容易产生类名冲突,样式互相覆盖。

解决方法:把css文件命名成xxx.module.css文件,然后通过import styles from ‘路径’ 引入,再通过styles.xxx来引用对应的类名,对于main-box之类的类名可通过styles['main-box']来引用,但是并不是很方便,所以可以使用驼峰法mainBox来命名类

import styles from './home.module.css'<div className={styles['user-box']+' flex-h flex-hsb'}><div className="flex-h flex-vc"><img className={styles.photo} src={require('../../assets/images/default.png')} /><span className={styles.user}>{this.state.username}</span></div><span className={styles.signin}>签到</span></div>

(2)如何使用swiper轮播

解决方法:执行:npm install swiper --save 安装依赖包;然后在要使用的页面上导入对应的css文件和js文件:

import Swiper from 'swiper/dist/js/swiper.js'
import 'swiper/dist/css/swiper.min.css'

接下来就是和平时使用swiper是一样的了,html:

<div className="banner swiper-container"><div className="swiper-wrapper"><div className="swiper-slide"><img className="banner-img" src={require('../../assets/images/home/banner1.jpg')} /></div><div className="swiper-slide"><img className="banner-img" src={require('../../assets/images/home/banner2.jpg')} /></div><div className="swiper-slide"><img className="banner-img" src={require('../../assets/images/home/banner3.jpg')} /></div></div><div className="swiper-pagination"></div></div>

初始化(在组件生命周期componentDidMount里面调用初始化):

initSwiper(){let banner = new Swiper ('.banner', {loop: true,  //循环slidesPerView: "auto",centeredSlides:true,autoplay: {   //滑动后继续播放(不写官方默认暂停)disableOnInteraction: false,},pagination: {  //分页器el: '.swiper-pagination'}})}

(3)图片的引入

解决方法:a、导入图片路径:

import Img from "./images/1.png"
<img src={Img} alt=""/>

b、直接获取图片路径:

<img src={require("./images/1.png")} alt=""/>

c、作为背景图片使用,可以直接写在css文件上或者如下

style={{background:`url(${require("./images/1.png")})` }}

首页具体代码如下:

/*首页*/
import React from 'react'
import Swiper from 'swiper/js/swiper.js'
import 'swiper/css/swiper.min.css'
import styles from './home.module.css'import './homeSwiper.css'import Tabbar from '../../components/tabbar/tabbar'import activity_img from '../../assets/images/home/home_activity.png'
import menu_icon1 from '../../assets/images/home/menu_icon1.png'
import menu_icon2 from '../../assets/images/home/menu_icon2.png'
import menu_icon3 from '../../assets/images/home/menu_icon3.png'
import menu_icon4 from '../../assets/images/home/menu_icon4.png'class Home extends React.Component{constructor(props){super(props)this.state = {username: 'Helen',menu: [{ id: 0,title: '资讯快递',icon: menu_icon1,descript: '了解行业动态'},{id: 1,title: '财经要闻',icon: menu_icon2,descript: '最新财经资讯'},{id: 2,title: '新手引导',icon: menu_icon3,descript: '轻松玩转币赚'},{id: 3,title: '了解区块链',icon: menu_icon4,descript: '全球数字经济'}],notice: [1,1,1,1,1,1,1,1,1],usdt: []}this.initSwiper = this.initSwiper.bind(this)}initSwiper(){let banner = new Swiper ('.banner', {loop: true,  //循环slidesPerView: "auto",centeredSlides:true,autoplay: {   //滑动后继续播放(不写官方默认暂停)disableOnInteraction: false,},pagination: {  //分页器el: '.swiper-pagination'}})}initNoticeSwiper(){let banner = new Swiper ('.notice-swiper', {loop: true,  //循环direction : 'vertical',   observer:true,//修改swiper自己或子元素时,自动初始化swiperobserveParents:true,//修改swiper的父元素时,自动初始化swiperautoplay: {   //滑动后继续播放(不写官方默认暂停)disableOnInteraction: false,},})}getUsdtData(usdt){let send_data = {"event":"subscription","data":"market.price."+usdt}let that = thisthis.sendMsg(send_data,ev=>{//console.log(JSON.parse(ev.data),'订阅数字货币最新价格')let data = JSON.parse(ev.data);if(data.currency === 'BTCUSDT')that.state.usdt[0] = data.dataelse if(data.currency === 'ETHUSDT')that.state.usdt[1] = data.dataelse if(data.currency === 'LTCUSDT'){that.state.usdt[2] = data.data}if(usdt==='stop')return falsethat.setState({usdt: that.state.usdt})})}componentDidMount(){this.initSwiper()this.initNoticeSwiper()this.getUsdtData('all')}componentWillUnmount(){this.getUsdtData('stop')}render(){const up_color = styles['color-05AC8B'],down_color = styles['color-D94F65'];const is_up1 = (this.state.usdt[0]&&this.state.usdt[0].rpt.toString().indexOf('-')!=-1)?down_color:up_color;const is_up2 = (this.state.usdt[1]&&this.state.usdt[1].rpt.toString().indexOf('-')!=-1)?down_color:up_color;const is_up3 = (this.state.usdt[2]&&this.state.usdt[2].rpt.toString().indexOf('-')!=-1)?down_color:up_color;return (<div className={styles['home-wrap']}><div className={styles['user-box']+' flex-h flex-hsb'}><div className="flex-h flex-vc"><img className={styles.photo} src={require('../../assets/images/default.png')} /><span className={styles.user}>{this.state.username}</span></div><span className={styles.signin}>签到</span></div><div className="banner swiper-container"><div className="swiper-wrapper"><div className="swiper-slide"><img className="banner-img" src={require('../../assets/images/home/banner1.jpg')} /></div><div className="swiper-slide"><img className="banner-img" src={require('../../assets/images/home/banner2.jpg')} /></div><div className="swiper-slide"><img className="banner-img" src={require('../../assets/images/home/banner3.jpg')} /></div></div><div className="swiper-pagination"></div></div><div className={styles['notice-box']+' flex-h'}><i className={styles['horn-icon']}></i><div className={styles['notice-swiper']+' notice-swiper swiper-container swiper-no-swiping'}><div className="swiper-wrapper">{this.state.notice.map((item,index)=>{return <div className="swiper-slide" key={index}><p>全球币交易全新升级,等你来体验!---{index+100}</p></div>})}</div></div></div><div className={styles['usdt-box']+' flex-h'}><div className={styles['usdt-item']}><p className={styles['color-fff']}>BTC/USDT</p><p className={styles['font-32']+' '+is_up1}>{this.state.usdt[0]?this.state.usdt[0].p.toFixed(2):'1221.12'}</p><p className={is_up1}>{this.state.usdt[0]?(this.state.usdt[0].rpt*100).toFixed(2):'0.26'}%</p><p>¥{this.state.usdt[0]?this.state.usdt[0].pr.toFixed(2):'223.45'}</p></div><div className={styles['usdt-item']}><p className={styles['color-fff']}>ETH/USDT</p><p className={styles['font-32']+' '+ is_up2}>{this.state.usdt[1]?this.state.usdt[1].p.toFixed(2):'1115.22'}</p><p className={is_up2}>{this.state.usdt[1]?(this.state.usdt[1].rpt*100).toFixed(2):'-0.12'}%</p><p>¥{this.state.usdt[1]?this.state.usdt[1].pr.toFixed(2):'3212.11'}</p></div><div className={styles['usdt-item']}><p className={styles['color-fff']}>LTC/USDT</p><p className={styles['font-32']+' '+is_up3}>{this.state.usdt[2]?this.state.usdt[2].p.toFixed(2):'2201.13'}</p><p className={is_up3}>{this.state.usdt[2]?(this.state.usdt[2].rpt*100).toFixed(2):'0.12'}%</p><p>¥{this.state.usdt[2]?this.state.usdt[2].pr.toFixed(2):'323.11'}</p></div></div>			<div className={styles['activity']}><img className="wh100" src={activity_img} /></div><div className={styles['notice-box']+ ' flex-h '+styles['border-none']}><i className={styles['horn-icon']+' '+styles['recharge-text']}></i><div className={styles['notice-swiper']+' notice-swiper swiper-container swiper-no-swiping '+styles['recharge-swiper']}><div className="swiper-wrapper">{this.state.notice.map((item,index)=>{return <div className="swiper-slide" key={index}><p>相见不如怀恋 成功充值2000元---{index+10}</p></div>})}</div></div></div><div className={styles['menu-box']+' flex-h'}>{this.state.menu.map((item,index)=>{return <div className={styles['menu-item']+' flex-h flex-vc'} key={item.id}><img className={styles['menu-icon']} src={item.icon} /><div><p className={styles['menu-title']}>{item.title}</p><p>{item.descript}</p></div></div>})}</div><Tabbar /></div>)}
}export default Home
.home-wrap{color: #fff; background-color: #0C1537;}
.user-box{padding: .4rem;}
.signin{padding: 0 .36rem;height: .6rem;line-height: .6rem;background-color: #3975F9;font-size: .28rem;border-radius: 27px;
}
.user{position: relative;font-size: .32rem; margin-left: .28rem;}
.user:before{position: absolute;right: -18px;top: 8px;content: '';width: 0;height: 0;border-width: 6px;border-style: solid;border-color: #fff transparent transparent transparent;
}
.photo{width: .65rem;height: .65rem;border: 2px solid #fff;border-radius: 50%;
}.notice-box{margin: 0 .31rem;padding: .28rem 0;border-bottom: 1px solid #353F61;
}
.horn-icon{width: .34rem;height: .3rem;background-image: url(../../assets/images/home/icon_horn.png);background-repeat: no-repeat;background-size: 100%;margin-right: .28rem;
}
.notice-swiper{width: 90%;font-size: .24rem;color: #fff;height: .3rem;line-height: .3rem;
}
.usdt-box{padding-top: .5rem;padding-bottom: .5rem;font-size: .24rem;color: #69748D;
}
.usdt-item{width: 33.33%;text-align: center;
}
.activity{margin: 0 .2rem; height: 1.56rem;}
.recharge-text{width: 1.1rem;height: .27rem;background-image: url(../../assets/images/home/recharge_text.png);
}
.recharge-swiper{width: 78%;}
.border-none{border: none}
.menu-box{margin: 0 .15rem; -webkit-flex-wrap: wrap; flex-wrap: wrap;}
.menu-item{width: 3.4rem;padding: .36rem 0;background-color: #04092C;-webkit-border-radius: 8px;border-radius: 8px;font-size: .24rem;color: #737FA1;margin: 0 .1rem .2rem;
}
.menu-icon{width: .8rem; height: .8rem; margin-left: .4rem; margin-right: .3rem;}
.menu-title{font-size: .28rem; color: #fff; font-weight: bold;}.font-32{font-size: .32rem; font-weight: bold; margin-top: .12rem;}
.color-fff{color: #fff;}
.color-05AC8B{color: #05AC8B;}
.color-D94F65{color: #D94F65;}


http://chatgpt.dhexx.cn/article/nFRUy4NL.shtml

相关文章

React项目搭建

一、创建项目 1、cmd切换到目标文件夹 2、初始化项目 npx create-react-app init-mobile 3、切换到对应目录根据提示启动项目 二、配置项目文件目录 调整项目中src目录结构如下&#xff1a; 三、引入组件库antd-mobile 1、安装 npm install --save antd-mobilenext 2、在…

思科路由器开启DNS解析

一、DNS服务端、DNS中继 R2(config)# interface FastEthernet0/0 R2(config-if)# ip address 192.168.1.254 255.255.255.0 R2(config)# interface FastEthernet0/1 R2(config-if)# ip address 22.1.1.2 255.255.255.0 R2(config)# router ospf 1 R2(config-router)# net…

IIS DNS服务器搭建

1——IIS&#xff08;因特网信息服务&#xff09;&#xff0c;IIS意味着你能发布网页&#xff0c;在没有配置服务器之前就用IP访问。步骤步骤 开始---》控制面板---》添加或删除程序---》双击应用程序服务器---》选择IIS、控制台 我这里&#xff0c;顺便双击了网络服务---》添加…

Wireshark实验 - DNS

Wireshark实验 - DNS 官方英文文档&#xff1a;Wireshark_Intro_v6.01.pdf Wireshark 实验: DNS v6.01 《计算机网络&#xff1a;自顶向下方法&#xff08;第6版&#xff09;》补充材料&#xff0c;J.F. Kurose and K.W. Ross “不闻不若闻之&#xff0c;闻之不若见之&#…

内网DNS重要使用作用

DNS服务简介&#xff1a; DNS(Domain Name System–域名系统),是因特网的一项服务。它作为将域名和IP地址相互映射的一个分布式数据库&#xff0c;能够使人更方便地访问互联网。是一个应用层的协议DNS使用TCP和UDP端口53。 DNS是一个分布式数据库,命名系统采用层次的逻辑结构…

DNS和SMTP

目录 SMTP 因特网中的电子邮件 ​一个简单的例子 什么是SMTP SMTP的缺点 用SMTP传输一个邮件的过程 SMTP是如何将一个报文从发送邮件服务器传送到接收邮件服务器的。 SMTP与HTTP的区别 共同点 不同点 邮件报文格式 邮件访问协议 POP3 IMAP 基于Web的电子邮件 D…

什么是DNS?为什么选择UDP?详细的DNS解析过程?

DNS DNS1、DNS是什么&#xff1f;2、因特网的域名结构3、缓存&#xff08;Cache)4、 DNS请求实例 DNS 1、DNS是什么&#xff1f; DNS ( Domain Name Systme)简单理解就是解析器、域名服务器的组合&#xff0c;比如大家访问知乎&#xff0c;会输入http://www.zhihu.com&#x…

怎么选最快dns服务器,dns设置(dns设置哪个最好最快)

dns设置(dns设置哪个最好最快)我们知道影响上网速度的因素有很多&#xff0c;硬件、软件等都是高速上网的基础&#xff0c;每个人都希望自家的网速越来快&#xff0c;在相同的硬件、带宽固定的情况下&#xff0c;如何来择优选择上网参数中的DNS服务器呢&#xff1f; DNS服务是网…

如何查找最近最快的dns服务器,如何可以选择适合自己的最快的DNS服务器?

应邀回答本行业问题。 使用三大运营商的宽带网络&#xff0c;默认的DNS就是最快的DNS。访问DNS的快慢&#xff0c;和DNS服务器的响应速度&#xff0c;以及往返时延有关。 我们访问一个DNS的时延&#xff0c;是DNS服务器的响应时延&#xff0c;加上终端到服务器的往返时延&#…

DNS 域名解析

介绍域名 网域名称&#xff08;英语&#xff1a;Domain Name&#xff0c;简称&#xff1a;Domain&#xff09;&#xff0c;简称域名、网域。 域名是互联网上某一台计算机或计算机组的名称。 域名可以说是一个 IP 地址的代称&#xff0c;目的是为了便于记忆。例如&#xff0c…

DNS 服务器选择

DNS 服务器选择 重要的事情写到前面&#xff0c;因为现在是快餐文化&#xff0c;快餐阅读&#xff0c;没有人愿意静下心研究和和阅读了。 本文主要介绍了一些DNS的测试速度&#xff0c;不介意直接拿去使用&#xff0c;如需使用还需要自己测试才行&#xff0c;就算我们找到了最…

怎么选最快dns服务器,如何选择适合自己的最快的DNS服务器?-

DNS在平时上网扮演着重要的角色&#xff0c;如果不注意DNS的话&#xff0c;可能会导致网速慢、弹出广告、网址打不开等一系列问题。那么有哪些比较好的DNS服务器呢&#xff1f;参考下图。 默认情况下&#xff0c;我们使用运营商分配的DNS&#xff0c;也可以使用公共DNS&#xf…

设置正确的DNS

上网或下载软件慢问题&#xff0c;除去少数设备陈旧、感染病毒、网卡硬件故障和网卡驱动错误方面的因素&#xff0c;绝大部分原因是由于部分上网电脑或家用无线路由器设置了错误的DNS造成的&#xff0c;正确的方法是应该在电脑或路由器上使用本地互联网营运商&#xff08;以下简…

将字符串转换为数字(a_to_i)

大部分人看到这样的题目&#xff0c;觉得很简单&#xff0c;很多人就会写出如下程序&#xff1a; int My_atoi(const char* str) { int val 0; while(*str ! \0) { val val * 10 *str - 0; str; } return val; } 这个程序是没有问题的…

java 如何将数值型字符转换为数字_Java 如何将字符串转换为数字 专家详解

在编程中我们经常需要进行各种数据类型之间的转换操作,下面将为您介绍如何将字符串转换为数字。首先我们需要了解各种数据类型的表示,String在java中为字符串类型,int在java中为整数类型,大小在-2147483648到2147483647 之间,long为长整形,可以表示的数值大小比int大很多…

C++中将字符串转换为数字

C中将字符串转换为数字 法一&#xff1a; int t s[len - 1]-0;//减去一个 0 是 将最后一位字母转换成数字例如&#xff1a;这个判断基偶性就是为了防止越界所以将数组转换为数组传入&#xff0c;再将最后一位字母转换位数字判断其基偶性 #include<iostream> using n…

C语言将字符串转换为数字

最近做了一些需要使用字符串形势获取数字的程序&#xff0c;这里就牵扯到了字符串类型和数字类型的转换问题&#xff0c;以下是C语言中&#xff0c;字符串类型转换为数字类型的方法。 1.问题描述 数字既能以字符串形式储存&#xff0c;也能以数值形式储存&#xff0c;把数字储…

C/C++编程笔记:如何将字符串转换为数字,数字转换为字符串?

通常&#xff0c;或更具体地说&#xff0c;在竞争性编程中&#xff0c;有许多情况需要将数字转换为字符串或将字符串转换为数字。但是缺乏某些必不可少的工具的知识使我们不得不这样做。本文介绍了一些实现此任务的方法。 将字符串转换为数字 方法1&#xff1a;使用stringstr…

32程序员面试被拒,嫌弃太老,“大龄程序员”将何去何从

随着互联网的高速发展变革&#xff0c;大龄恐惧症越来越多地在技术圈被人讨论。很多程序员在工作5-10年以后&#xff0c;都会开始思考5年、10年甚至更久以后的自己&#xff0c;会是怎样一种生活工作状态&#xff0c;以及是否会被时代抛弃。 随着前段时间一位32的程序员被拒面试…

大龄程序员的未来在何方,该何去何从?

大龄程序员的界定 老早网上有人说&#xff0c;软件开发干不过30岁&#xff0c;后来又有人说干不过35岁&#xff0c;后来又有人说干不过40岁&#xff0c;后来又有人说干不过45岁……各种说法很多&#xff0c;这里我采取通俗的说法&#xff0c;认为过了30岁的程序员算是大龄程序…