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

发布时间 2023-08-27 13:04:57作者: 前端cry

背景

再很多场景中,我们可能想在子组件中修改父组件的数据,但事实上,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数据绑定,子组件数据也会更新到最新的值。