vue3探索——组件通信之v-model父子组件数据同步

  • vue3探索——组件通信之v-model父子组件数据同步已关闭评论
  • 102 次浏览
  • A+
所属分类:Web前端
摘要

再很多场景中,我们可能想在子组件中修改父组件的数据,但事实上,vue不推荐我们这么做,因为数据的修改不容易溯源。


背景

再很多场景中,我们可能想在子组件中修改父组件的数据,但事实上,vue不推荐我们这么做,因为数据的修改不容易溯源。

Vue2写法

在vue2中,我们使用.sync修饰符+自定义事件'update:xxx',来使父子组件数据同步。

// 父组件 <template>     <div>         <h2>我是父组件,我有{{ money }}¥</h2>         <hr> 				<!-- 这里使用.sync修饰符,使**子组件pmoney**与**父组件money**同步 -->         <Son :pmoney.sync="money" />     </div> </template>  <script> import Son from "./son.vue"; export default {     components: {         Son,     },     data() {         return {             money: 1000 // 父组件数据         };     }, }; </script> 
// 子组件 <template>     <div>         <h2>我是子组件,我爹有{{ pmoney }}¥</h2> 				<!-- 触发**update:pmoney**这个自定义事件,事件参数就是要更改的值 -->         <button @click="$emit('update:pmoney', pmoney - 100)">用了100¥</button>     </div> </template>  <script> export default {     props: { 				// 定义父组件传进来的数据         pmoney: {             type: Number,             default: 0         },     }, }; </script> 

这里不作过多说明,有需要请自行了解。

Vue3写法

vue3的写法与vue2基本一致。最大的区别就是,使用v-model代替.sync修饰符

// 父组件 <template>     <div>         <!-- 父组件的数据 -->         <h2>我是父组件,我有{{ money }}¥</h2>         <hr>         <!-- 使用子组件 -->         <!-- 这里v-model的作用相当于vue2的.sync修饰符 -->         <Son v-model:pmoney="money" />         <!-- 也可以绑定多组数据 -->         <!-- <Son v-model:pmoney1="money" v-model:pmoney2="money" /> -->     </div> </template>  <script setup lang="ts"> import { ref } from 'vue';  // 引入子组件 import Son from './son.vue';  // 父组件的数据 const money = ref(1000); </script> 
// 子组件 <template>     <div>         <!-- 使用props中的数据 -->         <h3>我是子组件,我爹有{{ pmoney }}¥</h3>         <!-- 这里通过自定义事件,向父组件传递变更后的值,由父组件监听事件并修改数据 -->         <button @click="emit('update:pmoney', pmoney - 100)">我使用了100¥</button>     </div> </template>  <script setup lang="ts"> // 定义props,接收父组件的数据 defineProps(['pmoney']);  // 定义emits,用于触发父组件的事件 const emit = defineEmits(['update:pmoney']); </script> 

原理剖析

下面的v-model:pmoney实际是v-bind:pmoney 属性绑定和@update:pmoney 事件绑定的语法糖。

这里事件绑定的@update:是固定的,这就是子组件的自定义事件要加update: 前缀的原因

<Son v-model:pmoney="money" /> 

相当于

<Son :pmoney="money" @update:pmoney="money = $event" /> 
  • $event:子组件通过自定义事件传给父组件的值。

父子组件数据同步的本质

本质是子组件通过自定义事件向父组件传参数,子组件触发自定义事件并传值,父组件监听自定义事件并取值,同时修改原本的数据,因为v-bind数据绑定,子组件数据也会更新到最新的值。