2024.06.17~2024.06.21
senmu2024/06/21
computed
属性
Vue 中的 用法:
computed
属性支持 getter
和 setter
两个函数,如果直接写成函数形式则默认为 getter
函数,并且对于计算属性 Vue 会缓存其结果,也就意味着多次访问该属性返回的都是同样的结果。当然,计算属性也支持依赖响应式数据作为返回值,当响应式数据改变时会改变其结果。
场景:
计算属性一般用于复杂的响应式数据的处理,当响应式数据没改变的情况下可以极大地提高性能;但是,同样要注意,因为它会缓存结果,在计算属性中返回一个普通值那么该值永远不会被更新。
与 watch
相比:
它们的设计目的就不相同,computed
被设计作为计算响应式数据的复杂逻辑,且它是无副作用的纯函数;而 watch
被设计作为侦听响应式数据的变化并处理副作用逻辑。
原理:
- 初始化:当一个计算属性被定义时,Vue会为其创建一个内部的观察者实例(Watcher)。
- 依赖收集:在计算属性的函数第一次执行时,它会访问响应式数据,这时响应式数据会将该计算属性的观察者添加到它的依赖列表中。这个过程称为依赖收集。
- 缓存:计算属性的结果会被缓存,只有当它的依赖发生变化时,缓存才会失效。下次访问计算属性时,如果缓存有效,则直接返回缓存结果;如果缓存失效,则重新计算。
- 派生状态:当计算属性的依赖响应式数据发生变化时,依赖于该计算属性的 Watcher 会被通知,从而触发视图更新。
Vue 中虚拟节点/DOM 有哪些类型?
以下是在 XX 组件库中发现的逻辑,所以深入探索下。
<script>
const getNode = (children) => {
return children && children.find(node => node && node.tag)
}
export default {
name: 'xxComp',
// ... 省略属性等等
render() {
return getNode(this.$slots.default)
}
}
</script>
上面的 xxComp
子组件不支持纯文本的情况,因为纯文本节点的虚拟 DOM 没有 tag 属性。
Vue 源码中对于纯文本节点的创建:
// VNode 部分
class VNode {
constructor(
tag?: string,
data?: VNodeData,
children?: Array<VNode> | null,
text?: string,
elm?: Node,
context?: Component,
componentOptions?: VNodeComponentOptions,
asyncFactory?: Function
) {}
}
export function createTextVNode(val: string | number) {
return new VNode(undefined, undefined, undefined, String(val))
}
从上面源码片段就可以看出来纯文本不存在 tag 属性~
另外,从源码中看虚拟节点包括 element
、component