v-model 是 vue 的主要特性,双向绑定是响应式变量的核心。v-model 的简单原理就是数据监听加UI通知,如何在我们自己的组件中实现 v-model 呢?数据变更监听加父组件事件通知,如下,来自官网的一个例子
<script setup>
const props = defineProps(['modelValue'])
const emit = defineEmits(['update:modelValue'])
</script>
<template>
<input
:value="props.modelValue"
@input="emit('update:modelValue', $event.target.value)"
/>
</template>
- 绑定props.modelValue
父组件使用 v-model 时会自动将父组件 v-model 对应的变量转换为子组件的一个属性(props) modelValue,子组件可以通过 Props 进行读取 - 数据变更时进行通知
通过 update:modelValue 通知父组件数据已经更新 - 父组件中进行调用
<!-- Parent.vue -->
<Child
:modelValue="foo"
@update:modelValue="$event => (foo = $event)"
/>
Vue3中的简化写法
可以看到 v-model 中我们需要定义数据监听和变更通知,为什么不能直接在子组件中使用 v-model 呢,这是由于 props 变量是单向的、只读的,子组件中不能更改。Vue3 提供了一个新的写法,通过 defineModel 定义 v-model 属性,如下:
<script setup>
const model = defineModel()
</script>
<template>
<input v-model="model" />
</template>
v-model 自定义变量名
默认 v-model 对应变量名为 modelValue,在 vue3 我们也可以指定变量名,这样父组件可以传递多个 v-model 变量,如下:
<script setup>
const title = defineModel('title')
</script>
<template>
<input type="text" v-model="title" />
</template>
父组件中调用时,需要制定变量名
<MyComponent v-model:title="bookTitle" />
总结
v-model 核心就是监听和通知,本文使用了官网的例子进行了简单的介绍,更多高级用法可以到官网进行学习。