Vue3中组件间数据v-model双向绑定

发布时间:2023-08-23浏览次数:1653 次
要说清楚组件间的双向绑定,我们需要先回顾一下元素之间的数据双向绑定,我们都知道组件内,元素之间的数据双向绑定,可以使用v-model来实现,有人将v-model

要说清楚组件间的双向绑定,我们需要先回顾一下元素之间的数据双向绑定,我们都知道组件内,元素之间的数据双向绑定,可以使用v-model来实现,有人将v-model称为是语法糖,一点也不假,因为如果没有v-model,要实现元素间的双向绑定,其实我们也可以实现,只是需要的代码稍多一点而已。

一、元素间数据双向绑定

使用v-model实现:

<input v-model="keyword" />
<span>{{keyword}}</span>

使用v-bind实现(等效写法):

<input :value="keyword" @input="keyword = $event.target.value" />

<span>{{keyword}}</span>

二、组件间的双向数据绑定

同样,在组件之间,我们也可以实现数据的双向绑定,但是相对元素间的要繁琐一些。我们都知道,父子组件之间传递数据和方法,需要通过props和emit来进行传递,子组件可以使用父组件props过来的数据,但是不能对prop来的数据做修改,如果要修改,则续父组件提前通过emit的方式提供给子组件一个回调方法,子组件通过触发该方法,间接的达到修改数据的目的。实现方法如下:

父组件(这里的two为子组件):

<two :keyword="keyword" @update="value=>keyword = value"/>

子组件:

首先声明接收变量和方法

defineProps(['keyword'])
// 在vue3的setup语法糖写法中,该方法声明可以省略
defineEmits(['update'])

再在元素上实现数据的双向绑定:

<input :value="keyword" @input="$emit('update',$event.target.value)">

以上方式,我们就可以实现组件间的数据双向绑定了,但是在组件上,我们可不可以直接使用v-model来实现数据的双向绑定呢?答案是可以的。

<two v-model="keyword"/> // 父组件

可是当我们将父组件中的方法直接改为v-model时,却发现并不能实现我们的需求。此时,我们就需要再了解一下,官方提供的过渡实现方法了:

1、先将上面的props属性名改为modelValue,将方法名改为:update:modelValue。如下:

父组件

<two :modelValue="keyword" @update:modelValue="value=>keyword = value"/>

子组件:

<template>
    <input :value="modelValue" @input="$emit('update:modelValue',$event.target.value)">

</template>

<script setup>
defineProps(['modelValue'])

defineEmits(['update:modelValue'])
</script>

即,我们将最开始实现组件间数据双向绑定方法中的props属性名和emit方法名做了修改,业务逻辑均一致,验证没问题后,我们再次将再将父组件改为:

<two v-model="keyword"/>

发现,实现的效果居然一模一样。那么问题来了,为什么只有在使用modelValue作为属性名、方法名为update:modelValue时,可以简写呢?

简单的说,这是Vue官方为我们提供的语法糖,其规定了:在组件上使用v-model时,默认的prop为:modelValue 作为 prop,对应的事件为 update:modelValue。

那么如果我们想使用v-model,并且还不想使用官方默认提供的modelValue和update:modelValue时,有没有办法呢?答案是可以自定义。

三、v-model传参

我们可以通过给v-model传参的方式,来自定义子组件接收的prop属性名和emit方法名。

如:

<two v-model:title="xxx"/>

当我们在组件上使用 v-model:title 时,子组件接收的prop属性名就变成了:title,对应的emit方法名,也变成了update:title。即:使用我们参数title,替换了原来的modelValue。如下代码所示:

父组件:

<two v-model:title="keyword"/>

子组件:

<template>
    <input :value="title" @input="$emit('update:title',$event.target.value)">
</template>

<script setup>

defineProps(['title']) // modelValue 变为 title


defineEmits(['update:title']) // update:modelValue 变为update:title
</script>

基本到这一步,我们就可以掌握vue3中组件间使用v-model来实现数据双向绑定的方法了。

同理,我们可以在一个组件上使用多个v-model,然后传递不同的参数,这样就可以实现多个数据绑定了。

扫一扫,在手机上查看