Vue
# vuex
dispatch 触发 actions,commit 触发 mutations,在 mutation 里修改 state
- state 使用,this.$store.state.变量名
- mutations 使用,同步更新,this.$store.commit('increment')
- actions 使用,可以同步也可以异步,this.$store.dispatch('函数名')
- modules 使用,分模块,加 namespace 进行区分。 this.$store.state.模块名.变量名 this.$store.commit('模块名/increment') this.$store.dispatch('模块名/increment')
- 辅助函数 mapActions,mapMutations,mapState
# 路由守卫
- beforeRouteEnter 组件路由被确认前调用,不能只用 this,可以用 next 解决
- beforeRouteUpdate 当前路由改变,组件被复用时调用
- beforeRouteLeave 离开组件路由调用
- this.$router.go(): 原页面表单中的内容会丢失
- this.$router.go(-1) // 后退+刷新
- this.$router.go(0) // 刷新
- this.$router.go(1) // 前进
- this.$router.back(): 原页表表单中的内容会保留
- this.$router.back() // 后退
- this.$router.back(0) // 刷新
- this.$router.back(1) // 前进
# 组件 data 为什么要写成函数形式
如果是对象形式,每次引入组件指向的地址都是同一个,会遭横数据混乱
# 渲染大量数据的优化
无论是浏览器的 dom 和 bom,还是 nodejs,都是基于 js 引擎开发的,bom 和 dom 最终都要转化成 js 引擎能处理的数据,这个过程很耗时,所以在浏览器中操作 dom 很消耗性能
- 使用 createDocumentFragment 文档片段创建虚拟节点,当所有节点创建完毕后,一次性把虚拟节点里的 li 全部渲染出来
- 使用分段渲染,一次渲染部分数据
- 使用 requestAnimationFrame 逐帧渲染
# 列表组件中 key 的作用
- 对于大多数场景来讲,列表组件都有自己的状态,不带 key 会复用之前的状态
- key 的作用是更新组件时,判断两个节点是否相同,如果相同就复用,不同就删除重新创建
# 双向数据绑定的实现
- vue2 通过 defineProperty 数据劫持监听数据的 get 和 set,需要深度克隆数据作为中间值,因为 get 里操作数据本身会陷入死循环
- vue3 通过 proxy 进行数据代理,可以操作数据本身
- 数据更改触发 set,在 set 里修改页面数据
- 视图更改监听 input 和 change 事件,更改数据
- defineProperty
- 采用数据劫持结合发布订阅方式,通过 Object.defineProperty()来劫持各个属性的 setter、getter,当数据变化时发布消息给订阅者触发相应监听回调,
- 将 MVVM 作为数据的入口,整合 Observer、compile、Watcher,通过 Observer 来监听 model 的数据变化,通过 compile 来编译模板指令,最终通过 Watcher 搭建 Observer 和 Compile 之间的通信桥梁,达到数据变化-视图更新、视图变化-数据更新的双向绑定效果
# 父子组件传值
- ref
- $parent,$children
- props,$emit 属性传递
- provide,inject 上下文。这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效
- $attrs,$listeners
# 非父子组件传值
- 本地存储,vuex,localStorage
- 使用 eventBus,创建一个事件中心,可以用它来传递事件和接收事件
# 生命周期的理解
- updated 对所有数据的变化进行统一处理
- watch 对具体某个数据变化做统一处理
- nextTick 是对某个数据的某一次变化进行处理
# 父子组件生命周期顺序
# 首屏加载优化
- 减少公共资源模块打包体积
- 骨架屏
- 服务端渲染
# koa 原理剖析
# 路由 hash、history
- 再浏览器中有#,用 window.location.hash 获取。hash 虽然在 URL 中,单不背包含在 http 请求中,不会重新加载页面
- history 采用 html5 的特性,pushState、replaceState 可以对浏览器历史记录栈进行修改,以及 popState 事件的监听到状态变更
# proxy 路由代理
在 vue.config.js 里配置
- target,请求地址
- pathRewrite,地址重写规则
# keep-alive
切换路由可以缓存组件
- 生命周期,activated,deactivated
# nuxt.js 服务端渲染
- 路由,根据 pages 目录自动生成路由
- 入口页面,layouts/default.vue
- 优点,利于 SEO,加快首屏渲染
# 多页面
- public 文件夹添加入口文件
- vue.config.js 配置入口文件
- views 文件夹分模块配置 vue 项目
# computed 实现
- 遍历 computed 里的每个属性,每个 computed 属性都是一个 watch 实例,每个函数提供的函数作为属性的 getter,使用 Object.defineProperty 转化,用于数据发生变化时触发重新计算属性
- 若出现当前 computed 嵌套其他 computed 时,优先计算其他属性
- computed 能实现的,watch 都能实现,反之则不行
# watch 深度监听
// 监听 c
- 'a.b.c': function(new, old) { } //
- a: { deep: true, // 为 true 开启深度监听,a 对象里任何数据的变化都会触发 handler 函数 handler() { } }
# complier 实现
- 模板解析,将 template 转化成 render 字符串
- parse 过程,将 template 用正则转化成 AST 抽象语法树
- optimize 过程,标记静态节点,diff 过程跳过静态节点,提升性能
- generate 过程,生成 render 字符串
# 虚拟 dom
# 静态图片打包后的路径
- css 中的静态路径
- img 标签的 src
- import()
- require()
- URL // new URL(
./assets/1.jpg
, import.meta.url) // vue3
# 其他
- v-for 优先级高于 v-if,使用 computed 过滤掉需要不需要循环的数据