React学习
React学习
两个重要的概念:虚拟DOM,diff算法
虚拟DOM:用js对象模拟HTML的DOM树,为了方便比较,减少渲染
diff算法由3种组成:
tree diff DOM树按层对比
component diff 在每层里按组件对比
element diff:在每个组件中 按元素进行对比
工程启动流程:
创建webpack:npm init -y 创建dist 和 src文件夹,创建文件src/index.html src/main.js
安装webpack:npm -i webpack -D
yarn add web-dev-server --dev
自动编译js
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "webpack-dev-server --port 8080 --hot --host"// 最佳实践
},
html-webpack-plugin 将页面生成到内存中去
webpack.config.js文件中的配置
// 向外暴露一个打包的对象
module.exports = {
mode: 'development',// production develoment 设置压缩文件的方式
// webpack 4.0 中约定大于配置,默认 src/index.js 是入口文件
}
react 专门用来创建组件和虚拟DOM,同时组件的生命周期都在这个包里
react-dom 专门进行DOM操作,最主要的应用场景,就是ReactDOM.rander()
实例代码:
// 1. 导入
// 2. 创建虚拟DOM元素
// 3. 使用ReactDOM把虚拟DOM渲染到屏幕上
// 导入react的别名必须这么写
import React from 'react';
import ReactDOM from "react-dom";
// 参数1 创建的元素的类型,字符串,表示元素名称
// 参数2 一个对象或者null,表示这个DOM的属性
// 参数3 子节点 包括其他虚拟DOM获取文本子节点
// 参数n 其他子节点
// <h1 id="myh" title="这是一个h1">这是一个没有感情的h1</h1>
const myh1 = React.createElement('h1', {
id: 'myh1',
title: '这是一个h1'
}, "这是一个没有感情的h1")
const mdiv = React.createElement('div',null,'这是一个div',myh1)
// 参数1 目标虚拟DOM
// 参数2 指定页面的容器,一个DOM元素
ReactDOM.render(mdiv, document.getElementById('app'))
JSX = js + xml
JSX 语法本质是通过babel转换成 React.createElement()形式
依赖包:babel-core babel-loader babel-plugin-transform-runtime –dev
关于语法解析的:babel-preset-env babel-preset-stage-0 babel-preset-react –dev
@babel/core、@babel/preset-env、@babel/runtime、@babel/plugin-transform-runtime、@babel/plugin-proposal-class-properties、@babel/preset-react这几个包安装一下,然后在.babelrc文件中添加{“presets”:["@babel/preset-env","@babel/preset-react"], “plugins”:["@babel/transform-runtime","@babel/plugin-proposal-class-properties"]}
注:react中需要把key添加给被 foreach 或map 或 for循环直接没控制的那些元素(也就是最外层的元素)
jsx 注释:jsx的{}中可以写任何合法的js代码,包括注释
{/* 注释单行 */}
{
// 注释多行
}
为jsx添加类名,需要用className代替class;htmlFor代替label的for属性
组件创建和使用
为组件传递数据
// 第一种创建组件方式,组件名称首字母必须大写
function Hello(props) {// 在Props 上获取dog对象
// react 和Vue 中的 props 对象所有属性都是 只读 read only的
console.log(props.name);
// 返回一个 虚拟DOM
return <div>这是Hello组件 -- {props.name}-- {props.age} -- {props.gander}</div>
}
{/* 直接将组件名称以标签的形式,丢到页面上 */}
<Hello name={dog.name} age={dog.age} gander={dog.gander}></Hello>
react chrome开发插件 react developer tools
注:组件名称首字母必须大写
默认不做单独的配置的话,不能省略后缀名 可以配置webpack.config.js 省略后缀名
@代表src目录 配置webpack的alias 字段
import Hello from '@/components/Hello'
class 属性
this.props 只读
this.state 可读可写
class 有私有属性state 和生命周期
JSX style 样式
{/* jsx中的样式写法{{color: ‘red’}} */}
css文件
.title{
color: red;
}
-----
webpack 配置 解析css ,依赖包 style-loader css-loader
{test: /\.css$/,use: ['style-loader','css-loader?modules']}// 打包处理css样式表,从右向左 处理,css处理完交给style处理
// style-loader loader不嫩省略,webpack 1.0 用的是 style,后边都加-loader了,搜blog不要被误导
自定义 样式对象的名称
css-loader?modules&localIdentName=[path][name]-[local]-[hash:3]
path src-css
name 文件name
local css中的样式名称
hash 默认全length
-----
使用
import cssObj from "@/css/cssList.css";
<h1 className="title">这是评论列表组件</h1>
cssObj是全局的,整个项目都生效
解决样式冲突:vue <style scoped>
css 模块化只针对 class和id 不作用于标签
:global 全局,不模块化
自己的样式用scss结尾
第三方的用css结尾,这样就区分了个人和其他
sass-loader node-sass
绑定事件
最佳实践
<button onClick={()=>{this.myClickHandler()}}>按钮</button>
myClickHandler = ()=>{ console.log('点击事件'); }
箭头函数本身是一个匿名函数,和匿名函数不同的是会改变this指针的指向,它会根据环境选择箭头外部的那个对象。
修改数据使用this.setState({msg:‘改’}), 是异步执行的
JSX注释折叠
//#region
// 我是JSX注释
//#endregion
实现双向数据绑定
<input type="text" value={this.state.msg} onChange= {(e)=>this.txtChanged(e)} />
txtChanged = (e)=>{
// console.log(this.refs.txt.value);
// console.log(e.target.value);
// 实现双向数据绑定
const newValue = e.target.value
this.setState({
msg: newValue
})
}
第三方库使用 ant
插件 react-app-rewired 替换 react-scripts 实现按需加载css
babel-plugin-import