关于vue3 页面更新onUpdated函数没有调用问题

818 阅读1分钟

问题代码如下:

    <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注册的回调函数的

image.png 但是父组件的依赖是空的

image.png 所以当count触发时,不会去更新父组件,因此不会调用onUpdate回调函数

那为什么页面会更新呢?因为count的值是在ComA的render函数中访问的, ComA的render函数被被收集到ComA的deps当中,所以当count发生改变的时候触发的是ComA的render函数

image.png

这和插槽的工作机制是有关系的 将上面的父组件在编译成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函数