Skip to content

组件通信

  • props 属性
  • 自定义事件; 子组件触发自定义事件,父组件进行监听
  • vuex
  • $attrs,$listeners, useAttrs(),useListeners()
  • provide、inject
  • vue2 中,可以使用 new Vue() 实例来进行 on、emit 事件,即 eventBus

生命周期

作用合法操作
beforeCreate在组件实例被创建之前立即调用
此时组件的数据和事件还未初始化。
注册全局组件、添加全局指令或混入全局方法、页面拦截
created在组件实例被创建后立即调用。
组件的数据已经初始化,但此时还未挂载到 DOM。
接口请求
beforeMount在组件挂载到 DOM 之前立即调用。
此时模板编译完成,但尚未将组件渲染到页面上。
mounted在组件挂载到 DOM 后立即调用。
此时组件已经渲染到页面上。
可以操作 dom
beforeUpdate在组件数据更新之前立即调用。
在此钩子函数内,你可以访问之前的状态,但此时尚未应用最新的数据。
updated在组件数据更新后立即调用。此时组件已经重新渲染,可以进行 DOM 操作。
beforeDestroy在组件销毁之前立即调用。此时组件仍然可用,你可以执行一些清理工作。
destroyed在组件销毁后立即调用。此时组件已经被完全销毁,不再可用。

组件嵌套时候的生命周期

  • 挂载阶段 img_1.png
  • 更新阶段 img_2.png
  • 销毁阶段 img_3.png

Vue 响应式原理

Vue 响应式原理的核心就是 ObserverDepWatcher

Observer 中进行响应式的绑定,在数据被读的时候,触发 get 方法,执行Dep来收集依赖,也就是收集 Watcher。 在数据被改的时候,触发 set 方法,通过对应的所有依赖(Watcher),去执行更新。比如 watch 和 computed 就执行开发者自定义的回调方法。

首先我们会先对数据进行劫持,利用 Object.defineProperty 重新写 getter 和 setter 方法
将 template、watch 方法、computed 中读取的属性(利用 getter 方法)添加到 Dep(Dep 会创建对应的 Watcher 来管理每个依赖) 中,这时候就收集齐了全部的依赖信息
当数据变化的时候,会触发 setter 方法,相对应的 Watcher 就会执行,也就是更新数据

img.png

如何处理异步更新队列

  1. 监听变化
  2. 队列缓存
  3. 去重(Watcher)
  4. 异步更新
  5. DOM 更新
  6. nextTick

keep-alive 的作用和原理

可以缓存包裹在其中的组件(只能有一个直接组件),用于保存组件状态或者避免重新渲染。

当路由切换时,Vue 会自动销毁当前页面组件,并加载一个新的页面组件,而被 <keep-alive> 缓存的组件则会保留在内存中不会被销毁,因为其内部维护了一个 cache 对象,并将组件的虚拟 DOM 和实例添加到 cache 对象中。当被缓存的组件(通过路由导航或其他方式)被再次访问时,Vue 会从缓存中取出之前的组件实例,重新激活它们,而不是重新创建新的实例。所以一般情况下,被缓存的组件不会触发 onBeforeUnmount 和 onUnmounted 钩子,取而代之的是 onActivated 和 onDeactivated。

可以通过 include 和 exclude 来指定和排除一些组件(组件想要被识别,必须声明 name 属性)

路由守卫

  • router.beforeEach() // 全局前置守卫
  • router.afterEach() // 全局后置守卫
  • router.beforeResolve() // 全局解析守卫(组件被解析之后调用)
  • beforeEnter() // 路由独享守卫
  • 组件内
    • beforeRouteEnter()
    • beforeRouteUpdate()
    • beforeRouteLeave()

computed 原理

内部存在一个 dirty 属性,当该值为 false 的时候,那么直接返回缓存的结果,否则重新执行函数来计算最新的值

Watcher 执行回调:将 dirty 置成 true (当依赖的值改变的时候)

Vue 快实现

小野{target="_blank"}

version2{target="_blank"}

Vue query 替换

javascript
const router = useRouter()
router.replace({ name: 'c', query: { a: 2 } })

数据响应式的本质

当数据变化的时候,依赖其的的函数会重新执行 (Object.defineProperty、Proxy 只是实现的手段)