在 vue 3 中查看父组件的子属性

Watch child properties from parent component in vue 3

我想知道如何使用组合 api 在 Vue 3 中观察父组件的子属性(我正在使用实验性 script setup)。

<template>//Child.vue
  <button 
    @click="count++" 
    v-text="'count: ' + count" 
  />
</template>

<script setup>
import { ref } from 'vue'

let count = ref(1)
</script>
<template>//Parent.vue
  <p>parent: {{ count }}</p> //update me with a watcher
  <Child ref="childComponent" />
</template>


<script setup>
import Child from './Child.vue'
import { onMounted, ref, watch } from 'vue'

const childComponent = ref(null)
let count = ref(0)

onMounted(() => {
  watch(childComponent.count.value, (newVal, oldVal) => {
    console.log(newVal, oldVal);
    count.value = newVal
  })
}) 
</script>

我想了解如何从父组件观察子组件的变化。我的无效解决方案的灵感来自 。所以我不想发出 count.value 但只是观察变化。

谢谢!

如您所见,<script setup> 中的绑定“默认关闭”here

但是您可以显式公开某些引用。 为此,您使用 useContext().expose({ ref1,ref2,ref3 })

所以只需将此添加到 Child.vue:

import { useContext } from 'vue'

useContext().expose({ count })

然后将Parent.vue中的Watcher修改为:

watch(() => childComponent.value.count, (newVal, oldVal) => {
    console.log(newVal, oldVal);
    count.value = newVal
  })

而且有效!

我已经回答了 如果您不使用 script setup 或显式公开属性 .

,它与 Vue 3 完美配合

这是工作代码。

Child.vue

<template>
  <button @click="count++">Increase</button>
</template>

<script>
import { ref } from 'vue';

export default {
  setup() {
    return {
      count: ref(0),
    };
  },
};
</script>

Parent.vue

<template>
  <div id="app">
    <Child ref="childComponent" />
  </div>
</template>

<script>
import { ref, onMounted, watch } from 'vue';
import Child from './components/Child.vue';

export default {
  components: {
    Child,
  },
  setup() {
    const childComponent = ref(null);

    onMounted(() => {
      watch(
        () => childComponent.value.count,
        (newVal) => {
          console.log({ newVal }) // runs when count changes
        }
      );
    });

    return { childComponent };
  },
};
</script>

See it live on StackBlitz


请继续阅读

中,我描述了我们应该使用 mounted hook 以便能够监视子属性。 然而,在 Vue 3 中,这不再是 issue/limitation,因为观察者有额外的选项,例如 flush: 'post',它确保元素已被渲染。

确保阅读 Docs: Watching Template Refs


使用 script setup 时,组件的 public 实例不会公开,因此,Vue 2 解决方案将不起作用。 为了使其工作,您需要显式公开属性:

使用脚本设置

从 'vue' 导入 { ref } 常量 = 1 常量 b = 参考 (2) 定义公开({ 一种, b })

有选项API

export default {
  expose: ['publicData', 'publicMethod'],
  data() {
    return {
      publicData: 'foo',
      privateData: 'bar'
    }
  },
  methods: {
    publicMethod() {
      /* ... */
    },
    privateMethod() {
      /* ... */
    }
  }
}

注意: 如果您在选项 API 中定义 expose,那么只有那些属性会被公开。其余部分将无法从模板引用或 $parent 链访问。