引言:v-model不仅可以写在html标签内,也可以写在组件标签内,下面介绍v-model在组件标签内双向绑定的原理,相当于整合了组件通信里的props(父传子)和自定义事件customevent(子传父);
a.通过v-model实现组件的数据传递
father组件向自定义kzinput组件传递响应式数据username,同时father组件给子组件绑定事件,子组件声明绑定的事件,同时子组件在调用时,将修改后的username传回父组件,呈现在页面上,实现双向绑定;
father组件向自定义kzinput组件传递响应式数据username:
父组件在template引入kzinout组件,并将username传递给子组件
<template>
<div class="father">
<kzInput :modelValue="username"/>
</div>
</template>
father组件给子组件绑定update:modelValue事件:
<template>
<div class="father">
<kzInput @update:modelValue="username=$event"/>
</div>
</template>
子组件接收父组件传递的数据,并声明事件:
<script setup lang="ts">
//接收父组件传递的数据
defineProps(['modelValue'])
// 子组件需要声明 父组件绑定的事件
const emit = defineEmits(['update:modelValue'])
</script>
子组件通过emit(事件名,传递的参数)触发父组件绑定的事件:
<template>
<input type="text" :value="modelValue" @input="emit('update:modelValue',(<HTMLInputElement>$event.target).value)">
</template>
至此,实现了自定义组件中使用v-model进行双向绑定,父组件中的 传递数据 和 声明事件 就等价于 v-model 代码如下:
<kzInput v-model="username"/>
等价于:
<kzInput :modelValue="username" @update:modelValue="username=$event"/>
b.补充:
通常默认组件使用v-model进行参数传递时,参数名为modelValue,可以通过 v-model:指定参数名 同时被调用的组件也需要使用对应参数名进行传参,示例代码如下:
//父组件引入子组件时,v-model指定传递参数名
<kzinput v-model:yhm='username'>
// 子组件也需要进行修改
<template>
<input type="text" :value="yhm" @input="emit('update:yhm',(<HTMLInputElement>$event.target).value)">
</template>
<script setup lang="ts">
defineProps(['yhm'])
// 子组件需要声明 父组件绑定的事件
const emit = defineEmits(['update:yhm'])
</script>
好处的话,可以在一个组件上设置多个v-model,并且他们参数名都不一样,实现多个值的双向绑定;