问题代码如下:
<template>
<div>
<ComA>
{{ count }}
<button @click="add">add</button>
</Coma>
</div>
</template>
<script setup lang="ts" name="home">
import ComA from "./ComA.vue";
import { ref, onUpdated } from "vue";
const count = ref(0);
const add = () => {
count.value++;
};
onUpdated(() => {
console.log("更新");
});
</script>
在父组件当中,我们直接将count当作插槽使用在ComA组件当中,这样是触发不到onUpdated 具体原因 在父组件实例当中,是存在通过onUpdated注册的回调函数的
但是父组件的依赖是空的
所以当count触发时,不会去更新父组件,因此不会调用onUpdate回调函数
那为什么页面会更新呢?因为count的值是在ComA的render函数中访问的, ComA的render函数被被收集到ComA的deps当中,所以当count发生改变的时候触发的是ComA的render函数
这和插槽的工作机制是有关系的 将上面的父组件在编译成render函数
import { toDisplayString as _toDisplayString, createElementVNode as _createElementVNode, createTextVNode as _createTextVNode, resolveComponent as _resolveComponent, withCtx as _withCtx, createVNode as _createVNode, openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue"
export function render(_ctx, _cache, $props, $setup, $data, $options) {
const _component_ComA = _resolveComponent("ComA")
return (_openBlock(), _createElementBlock("template", null, [
_createElementVNode("div", null, [
_createVNode(_component_ComA, null, {
default: _withCtx(() => [
_createTextVNode(_toDisplayString(_ctx.count) + " ", 1 /* TEXT */),
_createElementVNode("button", { onClick: _ctx.add }, "add", 8 /* PROPS */, ["onClick"])
], undefined, true),
_: 1 /* STABLE */
})
])
]))
}
default插槽的调用时发生在子组件当中的
import { renderSlot as _renderSlot, createElementVNode as _createElementVNode, openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue"
export function render(_ctx, _cache, $props, $setup, $data, $options) {
return (_openBlock(), _createElementBlock("template", null, [
_createElementVNode("div", { class: "container" }, [
_renderSlot(_ctx.$slots, "default")
])
]))
}
在父组件渲染的时候,不会访问到count的值,因此时收集不到依赖的,所以count改变触发不到onUpdated函数