Appearance
vue3 篇
vue3 的 hook
Vue3 中的 Hooks 是一种函数,用于在组件中定义可复用的逻辑。它的主要作用是将文件中一些单独功能的 JavaScript 代码进行抽离,放到单独的函数中,或者将一些可以复用的公共方法/功能提取出来,以提高代码的复用性和逻辑的清晰性。
Hooks 和 Vue2 中的 mixin 有些类似,但相对而言,Hooks 更清楚复用功能代码的来源,也更清晰易懂。
hook 和 mixin 的区别
Mixin:
- 在 Vue 2 中,可以使用 Vue.mixin() 方法全局地应用 Mixin,这样,它将被应用到每一个之后创建的 Vue 实例中。也可以在组件选项中通过 mixins 数组局部地使用 Mixin。
- 在一个组件中如果引用多个 Mixin,变量的来源会变得错综复杂,需要手动调试,才知道数据来源。
- 在一个组件中使用多个 Mixin 可能会出现,函数和变量重名现象,就会导致冲突或覆盖现象。
Hook:
- Hooks 本质上是一组可复用的函数,它可以在任何地方使用。
- 能清楚的知道变量和方法的数据来源。
- 因为变量和函数是显示引用,就可以通过解构赋值,来避免函数和变量重名现象。
ref 和 reactive 的区别
底层实现
- ref 如果传入一个基本数据类型,则会创建一个包含 value 属性的对象,并通过对象的
get value
和set value
进行依赖收集,如果传递的是一个对象类型、则会调用 reactive 去实现。 - reactive 则是返回一个 proxy 对象。
区别
- ref 解构之后不会失去响应式,reactive 则会失去响应式。
- ref 可以传入基本类型和对象类型,reactive 只能传入对象
- ref 传入对象的时候可以直接替换整个对象,reactive 则不行,只能修改属性。
watch 和 watchEffect 的区别
- watchEffect 传入一个函数,它会立即执行,会自动追踪里面所有的响应式依赖,当有变化的时候会再次执行这个函数。
js
watchEffect(async () => {
const response = await fetch(
`https://jsonplaceholder.typicode.com/todos/${todoId.value}`
)
data.value = await response.json()
})
- watch 它第一个参数,是传入需要监听的数据,可以是 一个 ref、一个 reactive、一个 getter 函数、也可以是一个数组。但它不能直接监听对象的属性,需要通过 getter 函数返回这个属性。第二个参数是变化时,需执行的函数,第三个则是一些配置,它不会立即执行回调,也不会深度监听对象的属性变化。它不会追踪任何在回调中访问到的东西。
- 对于只有一个依赖项的例子来说,watchEffect() 的好处相对较小。但是对于有多个依赖项的侦听器来说,使用 watchEffect() 可以消除手动维护依赖列表的负担。此外,如果你需要侦听一个嵌套数据结构中的几个属性,watchEffect() 可能会比深度侦听器更有效,因为它将只跟踪回调中被使用到的属性,而不是递归地跟踪所有的属性。
js
const x = ref(0)
const y = ref(0)
const obj = reactive({ count: 0 })
// 单个 ref
watch(x, (newX) => {
console.log(`x is ${newX}`)
})
// reactive
watch(obj, (newValue, oldValue) => {
// 会隐式地创建一个深层侦听器
// 在嵌套的属性变更时触发
// 注意:`newValue` 此处和 `oldValue` 是相等的
// 因为它们是同一个对象!
})
// getter 函数
watch(
() => x.value + y.value,
(sum) => {
console.log(`sum of x + y is: ${sum}`)
}
)
// 监听对象的属性
watch(
() => obj.count,
(count) => {
console.log(`Count is: ${count}`)
}
)
// 多个来源组成的数组
watch([x, () => y.value], ([newX, newY]) => {
console.log(`x is ${newX} and y is ${newY}`)
})
diff 算法的优化
- 静态树提升,vue3 在模板编译的时候,会对动态内容通过 patchFlag 进行标记。静态节点会进行缓存,在后续更新中,除非内容发生改变,不然静态节点不会重新渲染。
- 采用了最长递增子序列(LIS)的算法,识别可以复用的节点,减少 DOM 操作。
- 事件侦听器缓存,Vue 3 引入了事件侦听器缓存机制,减少了因事件侦听器引起的不必要的 DOM 操作。
- 优化 key diff,Vue 3 对于带 key 的元素进行了优化的 diff 处理。通过构建一个 key 到索引的映射,算法可以快速定位到可以复用的节点,从而减少不必要的 DOM 操作。
- 引入了Fragment的概念,Vue 3 对 Fragment 类型的 VNode 进行了优化,使得在处理多个根节点时,diff 算法可以更高效地进行。
- 批量异步更新,Vue 3 引入了异步更新队列,这意味着在同一个事件循环中,所有的数据变更都会被收集起来,然后一次性进行虚拟 DOM 的更新,减少了不必要的多次 DOM 操作。