首页 > 编程笔记 > JavaScript笔记 阅读:46

Vue ref和defineExpose实现组件通信(附带实例)

Vue 父子组件之间通信可以借助 ref()函数和 defineExpose 实现。

我们可以先在父组件中通过 ref() 函数找到子组件,然后控制子组件的数据和方法。下面简单演示一下这个过程。

首先修改子组件文件 HelloWorld.vue,为其设置一个名为 count 的 ref 响应式数据,并且利用 increase() 函数对其进行累加操作。再修改父组件文件 App.vue,为子组件添加 ref 标识,并输出查看。

components/HelloWorld.vue 文件代码如下:
<template>
  <div>
    <p>count:{{ count }}</p>
    <button @click="increase">increase</button>
  </div>
</template>

<script setup>
import { ref } from 'vue';
const count = ref(0);
const increase = () => {
  count.value++;
};
</script>

App.vue 文件代码如下:
<script setup>
import { ref } from 'vue';
import HelloWorld from './components/HelloWorld.vue';
const refCount = ref(null);
console.log(refCount);
console.log(refCount.value);
</script>

<template>
  <HelloWorld ref="refCount" />
</template>
运行代码后可以发现,当打印 refCount 对象时,输出结果中没有任何子组件数据和方法的内容。当打印的是 refCount.value 时,则可以确认输出的是 null(空内容),控制台输出结果如下图所示。


图 1 控制台输出结果

那父组件怎么才能获取子组件的数据和方法呢?其实上面的操作只是缺少了一步。要想获取子组件的数据和方法,还需要通过 defineExpose 暴露数据和方法让子组件许可和确认。

接下来在父组件中就可以查看子组件中暴露的数据与方法。在父组件中编写两个函数 increaseChildCount 与 invokeChildIncrease,用于修改调用的子组件中的数据和方法,如果结果可以正常执行,就说明父组件与子组件之间成功实现了交互通信。

修改后的 components/HelloWorld.vue 文件代码如下:
<template>
  ......(篇幅原因,省略这部分代码)
</template>

<script setup>
import { ref } from 'vue';
const count = ref(0);
const increase = () => {
  count.value++;
};

// 允许其他组件使用当前组件的 count 与 increase
defineExpose({
  count,
  increase,
});
</script>

修改后的 App.vue 文件代码如下:
<script setup>
import { ref } from 'vue';
import HelloWorld from './components/HelloWorld.vue';
const refCount = ref(null);

// 利用 ref 找到子组件并控制子组件的 count 响应式数据
const increaseChildCount = () => {
  refCount.value.count++;
};

// 利用 ref 找到子组件并控制子组件的 increase 函数的调用
const invokeChildIncrease = () => {
  refCount.value.increase();
};
</script>

<template>
  <HelloWorld ref="refCount" />
  <button @click="increaseChildCount">increaseChildCount</button>
  <button @click="invokeChildIncrease">invokeChildIncrease</button>
</template>
在此时的项目中,父组件可以成功修改子组件的数据和调用子组件的方法,这说明父组件与子组件之间成功实现了交互通信。

相关文章