3

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

<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>

我想了解如何从父组件观察子组件的变化。我不工作的解决方案受到此处询问的 Vue.js 2 解决方案的启发。所以我不想发出,count.value但只是注意变化。

谢谢!

4

2 回答 2

3

如您在此处看到的,其中的 Bindings<script setup>是“默认关闭的” 。

但是,您可以显式公开某些参考。为此,您使用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
  })

它有效!

于 2021-02-21T16:07:52.890 回答
0

我已经回答了Vue 2 解决方案,如果您不使用script setup或显式公开属性 ,它与 Vue 3 完美配合。

这是工作代码。

孩子.vue

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

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

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

父.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>

在 StackBlitz 上现场观看


请继续阅读

Vue 2 解决方案中,我已经描述了我们应该使用挂载钩子以便能够观察子属性。然而,在 Vue 3 中,这不再是问题/限制,因为观察者有额外的选项flush: 'post',例如确保元素已被渲染。

请务必阅读文档:观看模板参考


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

使用脚本设置

从 'vue' 导入 { ref } const a = 1 const b = ref(2) defineExpose({ a, b })

使用选项 API

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

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

于 2021-12-13T11:17:06.757 回答