react框架学习笔记(⼀)
先清楚⼏个概念:
library(库):⼩⽽巧,只提供特定api;优点船⼩好掉头,易于切换,代码修改较⼩;
framework(框架):⼤⽽全,提供⼀整套解决⽅案,项⽬想切换⽐较困难;
模块化:从代码的⾓度进⾏分析;把可复⽤的代码,抽离为单个的模块,便于维护和开发
组件化:从ui界⾯来进⾏分析;把⼀些可复⽤的ui元素,抽离为单独的组件,便于项⽬的维护和开发。
组件化的好处:项⽬越⼤,组件越多,更加⽅便;
与Vue.js的区别
Vue:
通过.vue创建vue的组件,包括 templete(结构),script(⾏为),style(样式),需要webpack进⾏编译整合。
React:
react中,有组件化的概念,但并没有模板⽂件,⼀切都是以js来表现的。
React的⼏个核⼼概念
虚拟DOM(virtual Document Object Model)
DOM的本质:浏览器的概念,⽤js对象来表⽰页⾯的元素,并提供操作dom的api。
虚拟DOM:框架开发提供的概念,⽤js对象来模拟DOM元素和嵌套关系,为了是实现DOM的⾼效更新。
Diff算法
tree diff :新旧两棵DOM树,逐层对⽐的过程
react开发框架componnent diif:进⾏tree diff的时候,组件的对⽐。如果类型相同,则认为暂时不需要更新。
element diff:组件类型相同,进⾏元素级别的对⽐。
⼿动创建基本的基于webpack4.0的react项⽬
1.运⾏ npm init -y ,快速初始化项⽬。
2.在项⽬根⽬录创建src源代码⽬录和dist产品⽬录
3.在src⽬录下创建index.html,main.js或者App.js
4.使⽤npm安装webpack,运⾏npm i webpack -D,运⾏npm i webpack-cli -D
5. 4.x版本,需要分开安装。提供了约定⼤于配置的概念,减少了配置⽂件的体积。
默认打包⼊⼝"/src/index.js",输出⽂件时dist⽂件夹下的main.js
jsx语法
js代码中混合使⽤htnl标签的⼀种语⾔规范,默认浏览器不识别,需要⽤到插件来转换成js代码。本质是在打包运⾏的时候,转换成atElement的形式来执⾏的。
配置babel
安装插件
npm i babel-loader @babel/core @babel/plugin-transform -D
npm i @babel/preset-env @babel/preset-stage-0 @babel/present-react -D
添加.babelrc配置⽂件
在项⽬根⽬录新建.babelrc⽂件,代码如下
{
"presets":["@babel/preset-env","@babel/preset-react"],
"plugins":["@babel/plugin-transform-runtime"]
}
保存后重新运⾏,可以发现,写⼊的混合语法jsx⽣效了。
例如在页⾯中遍历⼀个数组,给每个元素添加h1标签
import React from"react"
import ReactDOM from"react-dom"
const myroot = ElementById("root")
/
/安able来转换js中的标签
//混合写⼊html的语法叫做jsx语法
let arr =["james","wade","iving","curry"]
{arr.map(item =><h1 key={item}>{item}</h1>)}
</div>,myroot)
//注意。遍历数组⼀定要加key
抽离组件的两种⽅法
1.构造函数法
使⽤构造函数来创建组件,如果要接收外界传递的数据,需要在 构造函数的参数列表中使⽤props来接收;
必须要向外return⼀个合法的JSX创建的虚拟DOM;
创建组件:
function Hello(){
// return null
return<div>Hello 组件</div>
}
为组件传递数据:
// 使⽤组件并为组件传递 props 数据
<Hello name={dog.name} age={dog.age} gender={der}></Hello>
// 在构造函数中,使⽤ props 形参,接收外界传递过来的数据
function Hello(props){
// props.name = 'zs'
console.log(props)
// 结论:不论是 Vue 还是 React,组件中的 props 永远都是只读的;不能被重新赋值;
return<div>这是 Hello 组件---{props.name}---{props.age}---{der}</div>
}
1. ⽗组件向⼦组件传递数据
2. 使⽤{…obj}属性扩散传递数据
3. 将组件封装到单独的⽂件中
4. 注意:组件的名称⾸字母必须是⼤写
5. 在导⼊组件的时候,如何省略组件的.jsx后缀名:
// 打开 fig.js ,并在导出的配置对象中,新增如下节点:
resolve:{
extensions:['.js','.jsx','.json'],// 表⽰,这⼏个⽂件的后缀名,可以省略不写
alias:{
'@': path.join(__dirname,'./src')
}
}
6. 在导⼊组件的时候,配置和使⽤@路径符号
2.class抽离组件
1. 最基本的组件结构:
// 如果要使⽤ class 定义组件,必须让⾃⼰的组件,继承⾃ React.Component
class 组件名称 extends React.Component {
// 在组件内部,必须有 render 函数,作⽤:渲染当前组件对应的虚拟DOM结构
render(){
// render 函数中,必须返回合法的 JSX 虚拟DOM结构
return <div>这是 class 创建的组件</div>
}
}
2. 两种创建组件⽅式的对⽐
注意:使⽤ class 关键字创建的组件,有⾃⼰的私有数据(this.state) 和 ⽣命周期函数;
注意:使⽤ function 创建的组件,只有props,没有⾃⼰的私有数据和 ⽣命周期函数;
1. ⽤构造函数创建出来的组件:叫做“⽆状态组件”【⽆状态组件今后⽤的不多】
2. ⽤class关键字创建出来的组件:叫做“有状态组件”【今后⽤的最多】
3. 什么情况下使⽤有状态组件?什么情况下使⽤⽆状态组件?
1. 如果⼀个组件需要有⾃⼰的私有数据,则推荐使⽤:class创建的有状态组件;
2. 如果⼀个组件不需要有私有的数据,则推荐使⽤:⽆状态组件;
3. React官⽅说:⽆状态组件,由于没有⾃⼰的state和⽣命周期函数,所以运⾏效率会⽐ 有状态组件稍微⾼⼀些;
有状态组件和⽆状态组件之间的本质区别就是:有⽆state属性、和 有⽆⽣命周期函数;
4. 组件中的 props 和 state/data 之间的区别
1. props 中的数据都是外界传递过来的;
2. state/data 中的数据,都是组件私有的;(通过 Ajax 获取回来的数据,⼀般都是私有数据);
3. props 中的数据都是只读的;不能重新赋值;
4. state/data 中的数据,都是可读可写的;
设置样式
1. 使⽤普通的 style 样式
<h1 style={ {color: 'red', fontWeight: 200} }></h1>
2. 启⽤ css-modules
1. 修改 fig.js这个配置⽂件,为 css-loader 添加参数:
{ test:/\.css$/, use:['style-loader','css-loader?modules']}// 为 .css 后缀名的样式表启⽤ CSS 模块化
2. 在需要的组件中,import导⼊样式表,并接收模块化的 CSS 样式对象:
import cssObj from'../css/CmtList.css'
3. 在需要的HTML标签上,使⽤className指定模块化的样式:
<h1 className={cssObj.title}>评论列表组件</h1>
3. 使⽤localIdentName⾃定义⽣成的类名格式,可选的参数有:
1. [path] 表⽰样式表 相对于项⽬根⽬录 所在路径
2. [name] 表⽰ 样式表⽂件名称
3. [local] 表⽰样式的类名定义名称
4. [hash:length] 表⽰32位的hash值
5. 例⼦:{ test: /\.css$/, use: ['style-loader', 'css-loader?modules&localIdentName=[path][name]-[local]-[hash:5]'] }
3. 使⽤ :local() 和 :global()
1. :local()包裹的类名,是被模块化的类名,只能通过className={cssObj.类名}来使⽤
同时,:local默认可以不写,这样,默认在样式表中定义的类名,都是被模块化的类名;
2. :global()包裹的类名,是全局⽣效的,不会被 css-modules 控制,定义的类名是什么,就是使⽤定义的类名className="类名" 4. 注意:只有.title这样的类样式选择器,才会被模块化控制,类似于body这样的标签选择器,不会被模块化控制;
在项⽬中启⽤模块化并同时使⽤bootstrap
1. 把 ⾃⼰的样式表,定义为 .scss ⽂件
2. 第三⽅的 样式表,还是 以 .css 结尾
3. 我们只需要为⾃⼰的 .scss ⽂件,启⽤模块化即可;
4. 运⾏cnpm i sass-loader node-sass -D 安装能够解析scss⽂件的loader
5. 添加loader规则:
{ test:/\.scss$/, use:['style-loader','css-loader?modules&localIdentName=[path][name]-[local]-[hash:5]','sass-loader']}// 打包处理 scss ⽂件的 load er
5. React 中绑定事件的注意点
1. 事件的名称都是React的提供的,因此名称的⾸字母必须⼤写onClick、onMouseOver
2. 为事件提供的处理函数,必须是如下格式
onClick= { function }
3. ⽤的最多的事件绑定形式为:
<button onClick={ () => this.show('传参') }>按钮</button>
// 事件的处理函数,需要定义为⼀个箭头函数,然后赋值给函数名称
show = (arg1) => {
console.log('show⽅法' + arg1)
}
4. 在React中,如果想要修改 state 中的数据,推荐使⽤ this.setState({ })
6. 绑定⽂本框与state中的值(单向数据流)
1. 在 Vue 中,默认提供了v-model指令,可以很⽅便的实现 数据的双向绑定;
2. 但是,在 React 中,默认只是单向数据流,也就是 只能把 state 上的数据绑定到 页⾯,⽆法把 页⾯中数据的变化,⾃动同步回
state ; 如果需要把 页⾯上数据的变化,保存到 state,则需要程序员⼿动监听onChange事件,拿到最新的数据,⼿动调⽤this.setState({ }) 更改回去;
3. 案例:
<input type="text" style={{ width: '100%' }} value={this.state.msg} onChange={() => Changed()} ref="mytxt" />
// 响应⽂本框内容改变的处理函数
textChanged = () => {
// console.log(this);
// console.fs.mytxt.value);
this.setState({
msg: value
})
}
7. 使⽤ref获取DOM元素引⽤
和 Vue 中差不多,vue 为页⾯上的元素提供了 ref 的属性,如果想要获取 元素引⽤,则需要使⽤this.$refs.引⽤名称
在 React 中,也有 ref, 如果要获取元素的引⽤fs.引⽤名称
8. 组件的⽣命周期
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论