企业模板网站vue,做电工的有接单的网站吗,漳浦县建设局网站,深圳产品设计公司有哪些一、创建项目并启动
第一步#xff1a;全局安装#xff1a;npm install -g create-react-app 第二步#xff1a;切换到想创建项目的目录#xff0c;使用命令create-react-app hello-react 第三步#xff1a;进入项目目录#xff0c;cd hello-react 第四步#xff1a;启…一、创建项目并启动
第一步全局安装npm install -g create-react-app 第二步切换到想创建项目的目录使用命令create-react-app hello-react 第三步进入项目目录cd hello-react 第四步启动项目npm start
二、目录结构
1、目录结构
其中public/index.htmsrc/App.jssrc/index.js 三个是最重要的文件。 node_module ------ 第三方资源public ------ 静态资源文件夹 favicon.ico ------ 网站页面图标 index.html ------ 主页面 logo192.png ------ logo 图 logo512.png ------ logo 图 manifest.json ------ 应用加壳的配置文件 robots.txt ------ 爬虫协议文件src ------ 源码文件夹 App.css ------ App 组件的样式 App.js ------ App 组件 App.test.js ------ 用于给 App 组件做测试 index.css ------ 全局样式 index.js ------ 入口文件 logo.svg ------ logo 图 reportWebVitals.js ------ 页面性能分析文件需要 web-vitals 库的支持 setupTests.js ------ 组件单元测试的文件需要 jest-dom 库的支持2、文件内容说明
public/index.html
!DOCTYPE html
html langenheadmeta charsetutf-8 /link relicon href%PUBLIC_URL%/favicon.ico /!-- 开启理想窗口用于做移动端网页的适配 --meta nameviewport contentwidthdevice-width, initial-scale1 /!-- 用于配置浏览器页签地址栏的颜色仅支持安卓手机浏览器兼容性较差 --meta nametheme-color content#000000 /meta namedescription contentWeb site created using create-react-app/!-- 用于指定网页添加到手机主屏幕后到图标仅支持 apple 手机 --link relapple-touch-icon href%PUBLIC_URL%/logo192.png /!-- 应用加壳时到配置 --link relmanifest href%PUBLIC_URL%/manifest.json /titleReact App/title/headbodynoscriptYou need to enable JavaScript to run this app./noscriptdiv idroot/div/body
/htmlsrc/index.js
import React from react;
import ReactDOM from react-dom/client;
import ./index.css;
import App from ./App;
import reportWebVitals from ./reportWebVitals;const root ReactDOM.createRoot(document.getElementById(root));
// React.StrictMode 标签会自动校验 react 语法遇到一些将要遗弃或不推荐使用的语法会提示
// 不加 React.StrictMode 标签直接使用 App 组件也没啥影响
root.render(React.StrictModeApp //React.StrictMode
);
reportWebVitals();注意旧版本的 src/index.js 中渲染组件是通过方法ReactDOM.render(App/,el)实现的
import React from react;
import App from ./App
// 旧版本引入 ReactDOM 然后 执行 ReactDOM.render()
import ReactDOM from react-dom
ReactDOM.render(App /, document.getElementById(root))而新版本18.0.2是通过ReactDOM.createRoot(el).render(App/)实现的
import React from react;
import App from ./App
// 新版本引入方式利用 ReactDOM.createRoot() 创建节点然后执行 render 函数
import ReactDOM from react-dom/client
ReactDOM.createRoot(document.getElementById(root)).render(App/)三、开发注意事项
1、组件命名
组件可以以js为后缀也可以以 jsx 为后缀以 jsx 为后缀可以明显区别于其他功能性的 js 文件。
2、引入 React 和 Component
1只引 React定义类组件时使用 React.Component
import React from react;
// 定义类式组件
export default class Hello extends React.Component {render() {return (h1 className{hello.title}Hello 组件/h1)}
}2解构引入 Component定义类组件时直接使用 Component
// React 中使用了默认暴露和分别暴露所以可以使用下面的引入方式
// import React, { Component } from react;
import { Component } from react;
// 定义类式组件
export default class Welcome extends Component {render() {return (h1 classNametitleWelcome组件/h1)}
}能使用以上引用方式是因为 React 中使用了 默认暴露 和 分别暴露
class React {
}
// 分别暴露 Component
export class Component {
}
React.Component Component
// 默认暴露 React
export default React
--------------------------------------
// 其他文件引用时可以这样
import React, { Component } from react;
import { Component } from react;3、引入 ReactDOM
1新版本18.0.2中要从 react-dom/client中引入 ReactDOM用法如下
import React from react;
// 新版本引入 ReactDOM渲染节点时使用 ReactDOM.createRoo(el).render(App/)
import ReactDOM from react-dom/client
import App from ./App;
ReactDOM.createRoot(document.getElementById(root)).render(App/)2旧版本中要从 react-dom 中引入 ReactDOM用法如下
import React from react;
import ReactDOM from react-dom
import App from ./App;
ReactDOM.render(App /, document.getElementById(root))4、css 模块化
为什么
按照截图方式在同一个组件中引用多个组件如果 Hello 和 Welcome 组件存在相同类的不同样式时后者会覆盖前者所以需要模块化样式使其互不影响。
怎么做
将 .css 文件改为 .module.css 文件引入 css 文件时使用 import hello from ./Hello.module.css 代替 import ./Hello.module.css组件标签中使用 hello.title, h1 className{hello.title}Hello 组件/h1 编译出来是如下效果
5、组件通信
父子通信直接通过组件标签的属性进行传值子组件中通过 props 可以接受 祖孙通信遵循状态在哪里操作状态的方法就在哪里的原则将所有修改 state 数据的方法都定义在 state 所在的组件中给子组件标签添加方法属性funcName{funcName} -》孙组件标签添加方法属性funcName{funcName} -》孙组件内部根据需要调用传过来的方法this.props.funcName()
6、跨域
前提本地前端项目地址http://localhost:3000
1法一配置在 packge.json 中
在 package.json中配置proxy: http://localhost:5000组件中使用axios.get(http://localhost:3000/students).then() 接口请求时会先在 3000 端口服务上找 /students 接口找不到就去配置好的 5000 端口上找
说明 1、优点配置简单前端请求资源时可以不加任何前缀 2、缺点不能配置多个代理 3、工作方式上述方式配置代理当前请求了3000不存在的资源时那么该请求会转发给 5000优先匹配前端资源
axios.get(http://192.168.31.229:3000/students).then((res) {console.log(学生接口调用成功,res)},(err) {console.log(学生接口调用失败, err)})2法二配置在 setupProxy.js 中
1第一步创建代理配置文件在 src 下创建配置文件src/setupProxy.js 2编写 setupProxy.js 配置具体代理规则
const { createProxyMiddleware } require(http-proxy-middleware)module.exports function (app) {app.use(createProxyMiddleware(/api1, { // api1 是需要转发的请求所有带有 /api1 前缀的请求都会转发给5000target: http://localhost:5000, // 配置转发目标地址能返回数据的服务器地址changeOrigin: true, // 控制服务器接收到的请求头中 host 字段的值/*changeOrigin 为true时服务器收到的请求头中的 host 为 http://localhost:5000changeOrigin 为false时服务收到的请求头中的 host 为前端工程的服务器的host(http://localhost:3000)changeOrigin 默认为false但我们一般将changeOrigin的值设为true*/pathRewrite: {^/api1:} // 去除请求前缀保证交给后台服务器的是正常请求地址必须配置}),createProxyMiddleware(/api2, {target: http://localhost:5001,changeOrigin: true,pathRewrite: {^/api2:}}))
}使用
axios.get(http://192.168.31.229:3000/api1/students).then((res) {console.log(学生接口调用成功,res)},(err) {console.log(学生接口调用失败, err)})说明 1.优点可以配置多个代理可以灵活控制是否走代理 2.缺点配置繁琐前端请求资源时必须加前缀
7、组件通信
1、动态初始化列表如何确定将数据放在哪个组件的state中
某个组件使用放在自身的state中某些组件使用放在他们共同的父组件的state中官方称此操作为状态提升
2、关于父子组件通信
【父组件】给【子组件】传递数据通过props传递【子组件】给【父组件】传递数据通过props传递要求父组件提前给子组件传递一个函数func子组件通过this.props.func调用
3、状态在哪里操作状态的方法就在哪里
8、消息订阅与发布个组件间进行通信
1下载 pubsub-js
npm i pubsub-js2消息订阅
componentDidMount() {// 消息订阅// 消息订阅回调里面接收两个参数第一个是消息名这里也就是 updateState第二个是消息发布时携带的参数this.token PubSub.subscribe(updateState,(_, stateObj) {this.setState(stateObj)})
}3消息发布
PubSub.publish(updateState, {users: res.data.items, isLoadding: false})4取消订阅
componentWillUnmount() {// 取消订阅PubSub.unsubscribe(this.token)
}9、路由 react-router-dom
基本使用
a 标签改为 Link 标签或者 NavLink Link classNamemenu-item to/homehome/Link NavLink classNamemenu-item to/homehome/NavLink NavLink标签与Link相比当前页面匹配的菜单会自动增加一个 active 类或者可以使用 activeClassName 修改为需要的类名展示区用 Route 标签进行路径的匹配 Route path/home component{Home}/Route 的最外侧包裹一个 BrowserRouter 或 HashRouter
10、路由组件与一般组件
写法不同 一般组件 路由组件存放位置不同 一般组件components 路由组件pages接收到的props不同 一般组件写组件标签时传递了什么就能接收到什么 路由组件接收到三个固定属性
history: go, goBack, goForward, push, replace (方法)location: pathname:“”, search:“”, state: “”match: params: {}, path: “”, url: “”
11、路由
路由渲染时若有多个相同 path不同 component 路由取并集也就是如下代码没有 Switch 标签包裹时/home 路由同时显示 Home 组件和 Test 组件。 Switch 包裹时/home 路由显示第一个匹配到的组件也就是 Home 组件。
SwitchRoute path/about component{About}/RouteRoute path/home component{Home}/RouteRoute path/home component{Test}/Route
/Switchreact 封装组件
标签体内容是一个特殊的标签属性子组件可以通过 this.props.children 可以获取标签体内容可以直接通过属性方式写入标签体内容。 !-- 这里的 to/about 和 内容 about 会以 props 传入到组件 MyNavLink 中形式是{to:/about, children:about} --
MyNavLink to/aboutabout/MyNavLink
MyNavLink to/homehome/MyNavLinkimport React from react;
import { NavLink } from react-router-dom;
export default class MyNavLink extends React.Component {render() {console.log(this.props) //{to: /about, children: about}return (NavLink activeClassNameactive-menu classNamemenu-item {...this.props}/)}
}1多层路由时样式丢失
link relstylesheet href./css/base.css场景例如路由前要加前缀为 /qiao/about如果页面通过相对路径引入了 public 目录中的样式 base.css页面刷新时base.css 样式会丢失。 原因开发模式默认打开 http://192.168.31.229:3000/这时候 public/css/base.css 从 public 中能正常拿到此时样式是正常的。点击路由跳转到 http://192.168.31.229:3000/qiao/about此时刷新页面因为从 public 下找不到 qiao/about会默认渲染 index.html 页面而且样式文件因为使用相对路口路径转化为 public/qiao/css/base.css样式路径有误所以样式获取不到。
解决方法
index.html 中引入样式使用绝对路径将 ./XXX改为 /XXXindex.html 中引入样式使用 %PUBLIC_URL%将./XXX改为%PUBLIC_URL%/XXX使用 hash HashRouter模式代替 history 模式BrowserRouter
2路由的严格匹配和模糊匹配
默认使用的是模糊匹配简单记输入的路径 必须要包含 匹配的路径且顺序要一致开启严格匹配 严格匹配不要随便开启需要时再开有些时候开启会导致无法继续匹配二级路由
MyNavLink to/home/a/bhome/MyNavLink Route exact path/home component{Home}/Route
3Redirect
一般写在所有路由注册的最下方当所有路由都无法匹配是跳转到 Redirect 指定的路由。
SwitchRoute path/about component{About}/RouteRoute path/home component{Home}/RouteRedirect to/about/
/Switch4嵌套路由
注册子路由时要写上父路由的 path 的值/home/news路由的匹配是按照注册路由的顺序进行的 先匹配home路由的组件在匹配news路由的组件
5路由传参
params 参数 路由链接携带参数Link to{/home/message/detail/tom/18}详情/Link 注册路由声明接收Route path/home/message/detail/:name/:age component{Detail}/ 接收参数this.props.match.paramssearch 参数 路由链接携带参数Link to{/home/message/detail?nametomage18}详情/Link 注册路由无需声明正常注册即可Route path/home/message/detail component{Detail}/ 接收参数this.props.location.search 备注获取到的 search 是 urlencoded 编码字符串需要借助 qs 解析state 参数 路由链接携带参数Link to{{pathname: /home/message/detail, state: {name: tom, age: 18}}}{item.title}/Link 注册路由无需声明正常注册即可Route path/home/message/detail component{Detail}/ 接收参数this.props.location.state 备注刷新也可以保留参数但是清除缓存history所有数据就会被清空刷新无法获取参数
6push和replace
Link 标签默认是 push 默认要打开 replace 模式需要在标签中增加属性 replace{true}或者简写 replace Link replace{true} to{{pathname: /home/message/detail, state: {id: item.id, title: item.title}}}{item.title}/Link
Link replace to{{pathname: /home/message/detail, state: {id: item.id, title: item.title}}}{item.title}/Link!-- 默认是push、 --
Link to{{pathname: /home/message/detail, state: {id: item.id, title: item.title}}}{item.title}/Link