vue、react、webpack、babel
0 条评论vue,react,webpack,babel 要点总结
掘金大牛:「历时8个月」10万字前端知识体系总结(基础知识篇)
Vue
基本使用
v-html
原始html内容,有xss风险
computed
- 有缓存,data不变不会重新计算
watch
监听引用类型,使用下面方法深度监听,但是拿不到oldVal
1 | watch:{ |
class 写法
1 | data () { |
或者
1 | :class=[black, red] |
style
object 类型,驼峰写法
v-if 和 v-show 区别
v-if 是否渲染,更新不频繁使用
v-show 是通过 css 的 display 控制显示与隐藏,频繁切换使用
v-for
- 也可以遍历对象
- key,不能乱写,尽量不用index,不用random
v-for
优先级比v-if
高
事件
event参数,自定义参数
- 没有参数,直接可以获取
- 有参数,用
$event
event
是原生对象
事件修饰符,按键修饰符
1 | @click.stop.prevent |
!(观察)事件被绑定到哪里
event.target
的值表明事件是挂在当前元素上的
表单
v-model
v-model.trim
v-model.lazy
v-model.number
组件使用
props
简写
1 | props:['list'] |
复杂写法,常用,可以定义类型和默认值
1 | props: { |
$emit
父组件
1 | <Input @add="clickhandler"/> |
子组件
1 | methods:{ |
组件通信 - 自定义事件(兄弟组件通信)
vue 具有自定义事件能力 $on、$off、$emit
组件卸载时,解除事件绑定,销毁子组件,定时器等
组件生命周期
- 挂载阶段
- 更新阶段
- 销毁阶段
单个组件
created:vue实例化完成
mounted:渲染完成
父子组件
组件实例创建: 先父后子
组件渲染: 先子后父【子组件渲染完,才能挂载】
高级特性
自定义 v-model
父组件中
1 | <CunstomVModal v-model={name}> |
子组件中 CunstomVModal
1 | <template> |
$nextTick、refs
- vue 是异步渲染
- data 改变之后,dom不会like渲染
- $nextTick 会在dom渲染之后被处罚,以获取最新的dom节点
slot
- 基本使用
- 作用于插槽
- 具名插槽
动态组件
- :is=”component-name”
- 需要根据数据,动态渲染的场景。即组件类型不确定
1 | <template> |
异步组件
- import()
- 按需加载,异步加载大组件
1 | export default { |
keep-alive
- 缓存组件
- 频繁切换,不需要重复渲染
- vue常见性能优化
1 | // 每个组件只渲染一次,且不会销毁。 |
mixin
- 多个组件有相同的逻辑,抽离出来
- mixin并不是完美的解决方案,会有一些问题
- vue 3 提出的 composition API 旨在解决这些问题
问题
- 变量来源不明确,不利于阅读
- 多个mixin可能会造成命名冲突
- mixin和组件可能会出现多对多的关系,复杂度较高
1 | <sript> |
vuex 使用
- 基本概念、基本使用、API
- state的数据结构设计
vuex基本概念
- state
- gettters
- action
- mutation
用于vue组件
- dispatch
- commit
- mapstate
- mapGetters
- mapActions
- mapMutations
vue-router
- 路由模式:
- hash
- window.onhashchange
- 会出发网页跳转,
- 可前进后退,
- 不会提交到server端,强制刷新也不会
- 可刷新
- H5 history
- history.pushState
- window.onpopstate
- 不可刷新(需要后端支持)
- hash
- 路由配置:
- 动态路由 {path: ‘/user/:id?’, component: User}
- 懒加载 {path: ‘/user/:id?’, component: () => import(‘./user’)}
Vue原理
如何里面MVVM
- 很久以前的视图
- asp jsp php 已经有组件化了
- 传统组件,只是静态渲染,更新依赖于操作dom
- 数据驱动视图(vue MVVM,react setState)
vue 响应式
- 组件data的数据一旦变化,立刻出发视图更新
- 核心API - Object.defineProperty
- get
- set
- Object.defineProperty 的一些缺点 (Vue3.0 使用 Proxy)
- proxy 兼容性不太好,且无法 polyfill
Object.defineProperty 缺点
- 深度监听,需要递归到底,一次性计算量大
- 新增,删除 无法监听,需要用 Vue.set 和 Vue.delete
- 无法监听数组,需要专门处理
Proxy 实现响应式
- 基本使用
- Reflect
- 实现响应式
- 对比 defineProperty 提高性能
- set第一层属性的时候,触发set
- set第二层属性的时候触发第一层属性的get
- 所以在get的时候,返回一个 新的proxy对象即可 深度监听,而且是惰性监听
- 所以性能比defineProperty好
虚拟DOM 和 diff
- DOM操作非常耗性能,js是执行非常快的
- vue和react是数据驱动视图
vdom
用js模拟dom结构,计算出最小的变更,操作dom
snabbdom
h函数,返回vnode(js)
patch(container, vnode) 初次渲染
patch(oldVnode, newVnode) 更新,新旧vnode都有children,那么updateChildren
patch(oldVnode, null) 销毁清空
diff
- 只比较同一层级,不跨级比较
- tag不相同,直接删掉重建,不再深度比较
- tag和key都相同,则认为是相同节点,不再深度比较
模板编译
- vue将模板编译为render函数
- 执行render函数生成vnode,patch
- 触发响应式,监听data属性getter setter
- with语法
- vue组件可以用render代替template
初次渲染过程
- 解析为render函数
- 触发响应式,监听data属性getter setter
- 执行render函数,生成vnode,patch
更新过程
- 修改data,触发setter,(此前在getter中已被监听)
- 重新执行render函数,生成newVnode
- patch(oldVnode, newVnode)
组件异步渲染
- $nextTick
- 汇总data修改,一次性更新视图
- 减少dom操作次数,提高性能
Vue3
新功能
createApp
1
2
3
4
5
6
7
8
9
10
11
12// vue2
const app = new Vue({})
Vue.use()
Vue.mixin()
Vue.component()
Vue.directive()
// vue3
const app = Vue.createApp({})
app.use()
app.mixin()
app.component()
app.directive()emits属性
1
emits: ['onClickhandler'] // 建议 onXxx
生命周期
- beforeDestroy 改为 beforeUnmount
- destroyed 改为 unmounted
多事件处理, @click=”one($event),two($event)”
Fragment, 模板不需要包在一个根组件中了,template下面可以写多个标签
移除.sync改为v-model参数
异步组件的引用方式, defindAsyncComponent
移除filter,如:v-if=”boolA | boolB”
Teleport,
Suspense
1 | <Suspense> |
- Composition API
- reactive
- ref toRef toRefs
- readonly
- computed
- watch watchEffect
- 钩子函数生命周期
原理
- proxy 实现响应式
- 对值类型无能为力,所以要用 ref
- 编译优化
- PatchFlag 静态标记
- hoistStatic 静态提升
- cacheHandler 缓存事件
- SSR 优化
- Tree-shaking 优化
Vue3 比 vue2 优势
- 性能更好
- 体积更小
- 更好的ts支持
- 更好的代码组织
- 更好的逻辑抽离
- 更多的新功能
生命周期
- beforeDestroy 改为 beforeUnmount
- destroyed 改为 unmounted
- 其他沿用vue2的生命周期
- setup等于 beforeCreate 和 created
1 | import { onBeforeMount } from 'vue' |
Composition API 对比 Options API
- 更好的代码组织
- 更好的逻辑复用(options api 分散于生命周期中,代码越多越明显)
- 更好的类型推导(直接this.a 和 this.fn,不利于类型判断 )
- 不建议共用
1 | export default { |
ref toRef toRefs
- toRef 将一个响应式对象中的某个属性变为ref
- toRefs 将一个响应式对象变为普通对象,这个普通对象的每个属性变为ref
1 | <template> |
为什么要用 Ref
- 返回 值类型,会丢失响应式
- 如在setup、computed、合成函数,都有可能返回 值类型
- vue如果不定义ref。用户将自造ref,反而更混乱
为什么要.value
- ref 是个对象(不丢失响应式),value存储值
- 通过.value属性的get和set实现响应式
- 用于模板、reactive时,(vue可以自己控制)不需要.value,其他情况都需要
Composition API 实现逻辑复用
- 抽离逻辑代码到一个函数
- 函数命名约定为 useXxx 格式
- setup中引用 useXxx 函数
Proxy 实现响应式
- 基本使用
- Reflect
- 实现响应式
- 对比 defineProperty 提高性能
- set第一层属性的时候,触发set
- set第二层属性的时候触发第一层属性的get
- 所以在get的时候,返回一个 新的proxy对象即可 深度监听,而且是惰性监听
- 所以性能比defineProperty好
watch 和 watchEffect 的区别
- 两者都可以监听data属性变化
- watch 需要明确监听哪个属性
- watchEffect会根据其中的属性,自动监听其变化
1 | // watch 默认不会立即执行 |
setup中如何获取组件实例
- 在setup 和 Composition API 中没有this
- 可通过 getCurrentInstance 获取当前实例
- 若使用 options API 可照常使用 this
vue3 为何比 vue2 快
- Proxy 响应式
- PatchFlag // 标记节点类型
- hoistStatic // 缓存静态节点,多个节点合并
- cacheHandler //
- SSR 优化
- tree-shaking
PatchFlag
- 编译模板时,动态节点做标记
- 标记分为不同类型,如 TEXT PROPS
- diff算法时,可以区分静态节点,以及不同类型的节点
hoistStatic
- 将静态节点的定义,提升到父作用域,缓存起来
- 多个相邻的静态节点,会被合并起来
- 典型的拿空间换时间的优化策略
cacheHandler
- 将事件缓存起来
vite - ES6 module
React
基本使用
setState
- 不可变值,为了SCU
- 可能异步可能同步
- 可能会被合并
是同步还是异步
- 直接使用是异步的
- 在setTimeout或者自定义的dom事件中是同步的
何时会合并
- 对象形式,会被合并
- 函数形式,不会合并
1 | this.setState((state, props) => {}) |
- 直接修改state的值,影响性能
事件为何要bind this
- class生成的实例中,this是undefined
Reaact 高级特性
- 函数组件
- 非受控组件
- Portals ReactDOM.createPortals()
- context
- 异步组件,import() React.lazy React.Suspense
- 性能优化,SCU 核心问题是 不可变值
- 高阶组件HOC
- render props
jsx 本质是什么
- React.createElement 函数,执行返回 vnode
事件合成机制
- div 冒泡至 document,合成统一的react event,dispatchEvent事件派发交由对应的处理器执行
- 更好的兼容性和跨平台
- 挂载到根节点,减少内存消耗,避免频繁解绑
- 方便统一管理(如事务机制)
transaction 事务机制
Transaction类的主要作用使用提供的包装(Wrapper)来包装一个函数。
Transaction会接受一个方法 func,和一组Wrapper。Transaction会在func执行之前,执行一组Wrapper中的initialize方法。而后执行func方法,在func方法执行完了之后,执行Wrapper提供的所有close方法。
fiber
- props state
- render 生成 vnode
- patch(ele, vnode)
- reconciliation 执行diff算法,纯js计算
- 进行任务拆分
- DOM需要渲染时暂停,空闲时恢复
- window.requestIdleCallback
- commit 阶段,将diff结果渲染到dom中
- reconciliation 执行diff算法,纯js计算
react 性能优化
- 渲染列表key
- 及时销毁事件
- 合理使用异步组件
- 减少 bind 次数
- 合理使用 scu pure memo
- 合理使用 immutablejs
- 打包webpack优化
- 前端通用优化 图片懒加载等
- SSR
React 和 Vue 区别
1、共同
- 支持组件化
- 数据驱动视图
- vdom操作dom
2、不同
- React 使用 jsx 拥抱js(文件都是.js结尾),Vue使用模板拥抱html(文件是.vue结尾)
- React 函数式编程,Vue 声明式编程
- React 更多需要自力更生,Vue 把想要的都给你
Webpack
升级webpack5 级周边插件后。需要做的调整
- package.json的dev-server命令改了,
- 4: “dev”:”webpack-dev-server –config build/webpack.dev.js”
- 5: “dev”:”webpack serve –config build/webpack.dev.js”
- webpack-merge
- 4: const { smart } = require(‘webpack-merge’)
- 5: const { merge } = require(‘webpack-merge’)
- CleanWebpackplugin
- 4: const CleanWebpackplugin = require(‘clean-webpack-plugin’)
- 5: const { CleanWebpackplugin } = require(‘clean-webpack-plugin’)
- modules.rules
- 4: loader: [‘xxx-loader’]
- 5: use: [‘xxx-loader’]
- filename hash h小写
- 4: filename: ‘bundle.[contentHash:8].js’
- 5: filename: ‘bundle.[contenthash:8].js’
基本配置
拆分配置 和 merge
启动本地服务 webpack-dev-server
处理 ES6
1
2
3
4
5
6
7
8
9
10
11
12
13modules.exports = {
entry: path.join(srcPath, 'index'),
modules: {
rules: [
{
test: /\.js$/,
loader: ['babel-loader'],
include: srcPath,
exclude: /node_modules/
}
]
}
}1
2
3
4{
"presets": ["@babel/preset-env"],
"plugins": []
}处理样式
处理图片
- file-loader 将图片变为url形式
- url-loader 将图片变为base64形式,减少http请求,很小没必要再进行http请求
模块化
高级配置
多入口
1 | entry: { |
抽离css文件
1 | coonst MiniCssExtracctplugin = require('mini-css-extract-plugin') |
压缩 optimization
1 | const TerserJSPlugin = require('terser-webpack-plugin') |
抽离公共代码
1 | module.exports = { |
异步加载
1 | // 定义 chunk |
module chunk bundle 区别
- module:就是写的代码,只要可以引入的都是module
- chunk:多模块合并成的,比如:index.js以及它引入的其他文件的集合
- bundle:最终的输出文件
性能优化,构建速度
- 优化babel-loader
- IgnorePlugin
- noParse
- happypack
- parallelUglifyPlugin
- 自动刷新
- 热更新
- DllPlugin
优化babel-loader
1 | { |
IgnorePlugin,直接不引入,代码中没有
1 | // 不引入所有语言包 |
noParse,引入,但不打包
1 | modules.exports={ |
happyPack 多线程打包
1 | const HappyPack = require('happypack') |
ParallelUglifyPlugin 多进程压缩js
new ParallelUglifyPlugin({
uglifyJS: {
// 还是使用 uglifyjs 压缩,只是开启了多进程
output: {
beautify: false, // 最紧凑的输出
comments: false // 删除所有注释
},
compress: {
// 删除所有 console 语句,可兼容ie
drop_console: true,
}
}
})
自动刷新
1 | module.exports = { |
DllPlugin
- 前端框架如 vue react , 体积大,构建慢
- 较稳定,不常升级版本
- 同一个版本只构建一次即可,不用每次都重新构建
- webpack 内置
- 打包出dll文件
- DllReferencePlugin - 使用dll文件
1、打包dll配置 webpacl.dll.js
1 | module.exports = { |
2、修改index.html模板
添加
3、配置webpack.dev.js
1 |
|
webpack 优化构建速度 (可用于生产环境)
- 优化 babel-loader
- IgnorePlugin
- noParse
- happyPack
- parellelUglifyPlugin
webpack 优化构建速度 (不可用于生产环境)
- 自动刷新
- 热更新
- DllPlugin
webpack性能优化 - 产出代码
体积更小
合理分包,不重复引用
速度更快,内损使用更少
小图片base64编码
bundle + hash
懒加载 import 语法
提取公共代码 splitChunks
IgnorePlugin
cdn加速
使用 production
Scope Hosting 改变打包作用域
使用 production
- 自动开启代码压缩
- Vue React 等会自动删除调试代码(如开发环境的warning)
- 启动 Tree-Shaking
Scope Hosting
- 代码体积更小
- 创建函数作用域更少
- 代码可读性更好
1 | const ModuleConcatenationPlugin = require('webpack/lib/optmize/ModuleConcatenationPlugin') |
babel
- 环境搭建 , 基本配置
- .babelrc 配置
- presets 和 plugins
- babel-polyfill
- babel-runtime
1 | { |
babel-polyfill
- babel 7.4 之后弃用 babel-polyfill
- 推荐直接使用 core-js 和 regenerator
babel-polyfill 问题
- 污染全局环境,使用babel-runtime解决
。babelrc中
1 | plugins: [ |
- 本文链接:https://xuehuayu.cn/article/9c3c56c.html
- 版权声明:① 标为原创的文章为博主原创,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接。② 标为转载的文章来自网络,已标明出处,侵删。