REACT(一)
React
是一个用于构建用户界面的JavaScript库
。
React
由Facebook
开发,并已被开放源代码社区维护和发展。它是一个流行的前端开发工具,广泛用于构建复杂的 Web 应用程序和网站。React
的核心概念包括组件化、声明式编程和函数式编程。它允许开发人员创建可重用和独立的组件,这些组件可以组合在一起构建复杂的用户界面。React
的视图层通常采用包含自定义HTML
标记的组件渲染,它支持高效和快速的用户界面渲染,适合构建大型的前端项目。
关键词
JSX
- 概念:
JSX
是JavaScript XML(HTML)
的缩写,表示在JS
代码中书写HTML
结构。简单理解就是:JSX=javascript xml
,是JavaScript
的语法扩展,只要你把HTML
代码写在JS
里,那就是JSX
。 - 作用:在
React
中创建HTML
结构(页面 UI 结构) - 优势:
- 采用类似于
HTML
的语法,降低学习成本,会HTML
就会JSX
- 充分利用
JS
自身的可编程能力创建HTML
结构 JSX
执行更快,因为它在编译为JavaScript
代码后进行了优化。- 它是类型安全的,在编译过程中就能发现错误。
- 使用
JSX
编写模板更加简单快速。
- 采用类似于
- 基本语法
// 1、JSX中使用js表达式: { JS 表达式 }
// 2、可使用的表达式:
// a、字符串、数值、布尔值、null、undefined、object( [] / {} )
// b、1 + 2、'abc'.split('')、['a', 'b'].join('-')
// c、fn()
// 3、特别注意:if 语句/ switch-case 语句/ 变量声明语句,这些叫做语句,不是表达式,不能出现在 {} 中!!
- 列表渲染
// map方法
const arr = [
{ id: 1, name: "张三" },
{ id: 2, name: "李四" },
{ id: 3, name: "王五" },
];
function App() {
return (
<div>
<ul>
{arr.map((item) => (
<li>{item.name}</li>
))}
</ul>
</div>
);
}
export default App;
// 注意:需要为遍历项添加key属性
/*
* 1、key 在 HTML 结构中是看不到的,是 React 内部用来进行性能优化时使用
* 2、key 在当前列表中要唯一的字符串或者数值(String/Number)
* 3、如果列表中有像 id 这种的唯一值,就用 id 来作为 key 值
* 4、如果列表中没有像 id 这种的唯一值,就可以使用 index(下标)来作为 key 值
*/
- 条件渲染
// 作用:根据是否满足条件生成HTML结构,比如Loading效果
// 实现:可以使用三元运算符或逻辑与(&&)运算符
// 布尔值
const flag = true;
function App() {
return (
<div className="App">
{/* 条件渲染字符串 */}
{flag ? "前端真难" : "前端简单"}
{/* 条件渲染标签/组件 */}
{flag ? <span>this is span</span> : null}
</div>
);
}
export default App;
- 样式处理
// 1、行内样式:
function App() {
return (
<div className="App">
//最外面{}是表达式,内部{}是对象,驼峰写法,用','隔开
<div style={{ color : 'red' , fontSize : '24px' }}>this is a div</div>
</div>
)
}
export default App
// 2、行内结合声明变量:(常用写法,推荐)
const styleObj = {
color:red
}
function App() {
return (
<div className="App">
<div style={ styleObj }>this is a div</div>
</div>
)
}
export default App
// 3、使用className动态类名控制:
/* app.css */
.title{
color : #E13500;
}
// 引入样式文件
import './app.css'
const showTitle = true
function App() {
return (
<div className="App">
// 表达式+三元 使用class会报错,必须使用className
<div className={ showTitle ? 'title' : ''}>this is a div</div>
</div>
)
}
export default App
-
注意事项
jsx
必须有一个根节点,如果没有根节点则使用<></>
(幽灵节点)代替根节点,相当于vue
中的<template></template>
标签- 所有标签必须形成闭合,双标签闭合或者单标签闭合都可
jsx
语法更贴近js
语法,属性名采用驼峰命名法,例:className
,htmlFor
jsx
支持多行(换行),如需换行,使用()
包裹,防止bug
出现
-
格式化配置
// 1、安装vsCode prettier插件
// 2、修改配置文件 setting.json (全选覆盖原先的即可)
{
"git.enableSmartCommit": true,
// 修改注释颜色
"editor.tokenColorCustomizations": {
"comments": {
"fontStyle": "bold",
"foreground": "#206f42"
}
},
// 配置文件类型识别
"files.associations": {
"*.js": "javascript",
"*.json": "jsonc",
"*.cjson": "jsonc",
"*.wxss": "css",
"*.wxs": "javascript"
},
"extensions.ignoreRecommendations": false,
"files.exclude": {
"**/.DS_Store": true,
"**/.git": true,
"**/.hg": true,
"**/.svn": true,
"**/CVS": true,
"**/node_modules": false,
"**/tmp": true
},
// "javascript.implicitProjectConfig.experimentalDecorators": true,
"explorer.confirmDragAndDrop": false,
"typescript.updateImportsOnFileMove.enabled": "prompt",
"git.confirmSync": false,
"editor.tabSize": 2,
"editor.fontWeight": "500",
"[json]": {},
"editor.tabCompletion": "on",
"vsicons.projectDetection.autoReload": true,
"editor.fontFamily": "Monaco, 'Courier New', monospace, Meslo LG M for Powerline",
"[html]": {
"editor.defaultFormatter": "vscode.html-language-features"
},
"editor.fontSize": 16,
"debug.console.fontSize": 14,
"vsicons.dontShowNewVersionMessage": true,
"editor.minimap.enabled": true,
"emmet.extensionsPath": [""],
// vue eslint start 保存时自动格式化代码
"editor.formatOnSave": true,
// eslint配置项,保存时自动修复错误
"editor.codeActionsOnSave": {
"source.fixAll": true
},
"vetur.ignoreProjectWarning": true,
// 让vetur使用vs自带的js格式化工具
// uni-app和vue 项目使用
"vetur.format.defaultFormatter.js": "vscode-typescript",
"javascript.format.semicolons": "remove",
// // 指定 *.vue 文件的格式化工具为vetur
"[vue]": {
"editor.defaultFormatter": "octref.vetur"
},
// // 指定 *.js 文件的格式化工具为vscode自带
"[javascript]": {
"editor.defaultFormatter": "vscode.typescript-language-features"
},
// // 默认使用prettier格式化支持的文件
"editor.defaultFormatter": "esbenp.prettier-vscode",
"prettier.jsxBracketSameLine": true,
// 函数前面加个空格
"javascript.format.insertSpaceBeforeFunctionParenthesis": true,
"prettier.singleQuote": true,
"prettier.semi": false,
// eslint end
// react
// 当按tab键的时候,会自动提示
"emmet.triggerExpansionOnTab": true,
"emmet.showAbbreviationSuggestions": true,
"emmet.includeLanguages": {
// jsx的提示
"javascript": "javascriptreact",
"vue-html": "html",
"vue": "html",
"wxml": "html"
},
// end
"[jsonc]": {
"editor.defaultFormatter": "vscode.json-language-features"
},
// @路径提示
"path-intellisense.mappings": {
"@": "${workspaceRoot}/src"
},
"security.workspace.trust.untrustedFiles": "open",
"git.ignoreMissingGitWarning": true,
"window.zoomLevel": 1
}
JSX
并不是标准的JS
语法,是JS
的语法扩展,浏览器默认是不识别的,脚手架中内置的babel/pulign-transform-react-jsx
包,用来解析该语法。
虚拟 DOM
-
概念:
- 在浏览器中,
虚拟DOM
是指用js
对象来表示页面上的元素,并提供了操作DOM
对象的API
; - 在框架中,
虚拟DOM
是指用js
对象来模拟 页面上DOM
和DOM
嵌套。 - 在
React
中,render
执行的结果得到的并不是真正的DOM
节点,结果仅仅是轻量级的JavaScript
对象,我们称之为virtual DOM
。
- 在浏览器中,
-
本质:一个
虚拟DOM
(元素)是一个一般的js
对象,准确的说是一个对象树(倒立的);虚拟DOM
保存了真实DOM
的层次关系和一些基本属性,与真实DOM
一一对应;如果只是更新虚拟DOM
,页面是不会重绘的。 -
目的:实现页面上的元素高效更新。
-
基本原理:用
JS
对象树表示DOM树
的结构;然后用这个树构建一个真正的DOM树
插到文档当中;当状态变更的时候,重新构造一棵新的对象树。然后用新的树和旧的树进行比较,记录两棵树差异;把差异应用到真实DOM树
上,视图就更新了。 -
实现过程:
DOM树
:由文档及文档中的所有的元素(标签)组成的一个树形结构图,叫树状图
(DOM 树
)。- 简单流程
- 通过原生
js
生成DOM
// 原生 js 创建(基本不使用) let virtualDom1 = createElement('ul', {class: 'list'}, [ createElement('li', {class: 'item'}, ['a']), createElement('li', {class: 'item'}, ['b']), createElement('li', {class: 'item'}, ['c']), ]) // jsx 语法创建 <div className="confirm"> <Mask onClick={()=> cancel('123')}/> <div className='cf_box'> <div className='cf_feild'> <h6>{title || '提示'}<Icon type="close" onClick={()=> cancel('123')} /></h6> </div> </div> </div> let patchs = diff(virtualDom1, virtualDom2);
- 渲染到页面上
// 原生js let el = render(virtualDom); renderDom(el, window.root); // jsx 直接写在render函数即可 render() { const {onclick} = this.props; return ( <div className='mask_box' onClick={()=> onclick && onclick()}> </div> ) }
- 更新时,使用
diff
算法比较,改变虚拟DOM
- 按需更新
- 通过原生
diff
算法Tree Diff
:新旧两颗dom树,逐层对比的过程,就是Tree Diff
;当整棵DOM
逐层对比完毕,则所有需要被按需更新的元素,必然能够找到。Component Diff
:在进行tree Diff
的时候,每一层中,组件级别的对比,叫做Component Diff
。Element Diff
:在进行组件对比的时候,如果两个组件类型相同,则需要进行元素级别的对比,这叫做Element Diff
。