# Vue 2 生命周期
每个 Vue 实例在创建时都会经历从创建、初始化、编译模版、挂载 Dom -> 渲染、更新 -> 渲染、卸载等一系列过程,这就是 Vue 的生命周期。
vue 生命周期钩子,在某一阶段时去触发的函数,目的是为了完成一些动作或者事件
create 阶段:vue 实例被创建
- beforeCreate: 创建前,此时 data 和 methods 中的数据都还没有初始化
- created: 创建完成,属性已经绑定, 但还未生成真实 dom
mount 阶段: vue 实例被挂载到真实 DOM 节点
- beforeMount:模板编译/挂载之前
- mounted: 组件已挂载,此时可以操作 Dom
update 阶段:当 vue 实例里面的 data 数据变化时,触发组件的重新渲染
- beforeUpdate updated
destroy 阶段:vue 实例被销毁
- beforeDestroy destroyed
数据请求放在 mounted
# Vue 2 组件间通信方式
父子组件:使用「props / $emit」进行通信
爷孙组件: a. 使用两次父子组件间通信来实现 b. 使用「provide + inject」来通信
任意组件:使用 eventBus = new Vue() 来通信 a. 主要 API 是 eventBus.$on 和 eventBus.$emit b. 缺点是事件多了就很乱,难以维护
任意组件:使用 Vuex 通信(Vue 3 可用 Pinia 代替 Vuex)
# Vuex
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 + 库
主要包括以下几个模块:
- State:定义了应用状态的数据结构,可以在这里设置默认的初始状态。
- Getter:允许组件从 Store 中获取数据,mapGetters 辅助函数仅仅是将 store 中的 getter 映射到局部计算属性。
- Mutation:是唯一更改 store 中状态的方法,且必须是同步函数。
- Action:用于提交 mutation,而不是直接变更状态,可以包含任意异步操作。
- Module:允许将单一的 Store 拆分为多个 store 且同时保存在单一的状态树中。
Mutation 和 Action 分开原因:为了让代码更易于维护
# VueRouter
Vue Router 是 Vue.js 的官方路由。它与 Vue.js 核心深度集成,让用 Vue.js 构建单页应用变得轻而易举。
mode
- hash
- history
router-link:在不重新加载页面的情况下更改 URL
router-view:将显示与 url 对应的组件
跳转
this.$router.push()
<router-link to=""></router-link>
$route 和 $router 区别
- router 为 VueRouter 的实例,是一个全局路由对象,包含了路由跳转的方法(push,replace)、钩子函数等。
- route 是路由信息对象,每一个路由都会有一个 route 对象,是一个局部对象,包含 path,params,hash,query,fullPath,matched,name 等路由信息参数。
Hash 模式和 History 模式区别
- 一个用的 Hash,一个用的 History API
- 一个不需要后端 nginx 配合,一个需要
# 导航守卫
vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航 全局守卫、路由守卫、组件守卫
全局守卫:
- router.beforeEach 全局前置守卫
- router.beforeResolve 全局解析守卫
- router.afterEach 全局后置钩子
路由独享守卫:beforeEnter
组件内的守卫:
- beforeRouteEnter
- beforeRouteUpdate
- beforeRouteLeave
导航守卫实现登录控制
router.beforeEach((to, from, next) => {
if (to.path === '/login')
return next()
if (to 是受控页面 && 没有登录)
return next('/login')
next()
})
# Vue 2 双向绑定
使用 v-model / .sync 实现,
v-model
是 v-bind:value 和 von:input 的语法糖
- v-bind:value 实现了 data ⇒ UI 的单向绑定
- v-on:input 实现了 UI ⇒ data 的单向绑定
- 加起来就是双向绑定了
这两个单向绑定是如何实现?
a. 前者通过 Object.defineProperty API 给 data 创建 getter 和 setter,用于监听 data 的改变,data 一变就会安排改变 UI
b. 后者通过 template compiler 给 DOM 添加事件监听,DOM input 的值变了就 会去修改 data。
# Vue 3 Proxy
- 弥补 Object.defineProperty 的两个不足
- 动态创建的 data 属性需要用 Vue.set 来赋值,Vue 3 用了 Proxy 就不需要了
- 基于性能考虑,Vue 2 篡改了数组的 7 个 API,Vue 3 用了 Proxy 就不需要了
- defineProperty 需要提前递归地遍历 data 做到响应式,而 Proxy 可以在真正用到 深层数据的时候再做响应式(惰性)
# Vue 3 Composition API
Composition API 比 mixins、高阶组件、extends、Renderless Components 等更好,原因有三:
- 模版中的数据来源不清晰
- 命名空间冲突
- 性能
更适合 TypeScript
# Vue 3 对比 Vue 2 改动
- createApp() 代替了 new Vue()
- v-model 代替了以前的 v-model 和 .sync
- 根元素可以有不止一个元素
- 新增 Teleport 传送门
- ref 属性支持函数
- 响应式原理改变: 使用 Proxy 取代 Object.defineProperty
- 生命周期
- 使用 setup 代替之前的 beforeCreate 和 created
- destroyed 被改名为 unmounted