基本用法
v-model可以在组件上实现双向绑定
从 Vue 3.4 开始,推荐的实现方式是使用defineModel()宏:
vue
<script setup>
const model = defineModel()
</script>
<template>
<span>My input</span> <input v-model="model">
</template>
在子组件中使用defineModel声明一个model变量,在模板中使用v-model绑定这个变量
vue
// App.vue
<script setup>
import Child from './Child.vue'
import { ref } from 'vue'
const msg = ref('Hello World!')
</script>
<template>
<h1>{{ msg }}</h1>
<Child v-model="msg" />
</template>
在父组件声明一个响应变量msg,再用v-model绑定msg,这样msg的值传给了子组件
效果:在子组件中修改model的值,父组件的msg也随之变化。
底层原理
vue
<script setup>
const model = defineModel()
</script>
<template>
<span>My input</span> <input v-model="model">
</template>
可以拆解成由defineProps()和defineEmit()的组合
vue
<!-- Child.vue -->
<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>
vue
// App.vue
<script setup>
import Child from './Child.vue'
import { ref } from 'vue'
const msg = ref('Hello World!')
</script>
<template>
<h1>{{ msg }}</h1>
<Child v-model="msg" />
</template>
被拆解成
vue
<!-- APP.vue -->
<Child
:modelValue="msg"
@update:modelValue="$event => (msg = $event)"
/>
在子组件中用props.modelValue接受父组件传来的msg的值,在模板中用:value进行响应式渲染。
当模板中input的value被修改的时候,使用emit中update:modelValue向父组件传value的值,然后父组件的msg的值被修改成value的值。
v-model的参数
在组件上的v-model可以接受一个参数:
vue
// App.vue
<script setup>
import Child from './Child.vue'
import { ref } from 'vue'
const msg = ref('Hello World!')
</script>
<template>
<h1>{{ msg }}</h1>
<Child v-model:title="msg" />
</template>
在子组件中,我们可以通过将字符串作为第一个参数传递给 defineModel()
来支持相应的参数。
vue
<script setup>
const title = defineModel('title')
</script>
<template>
<span>My input</span> <input v-model="model">
</template>
如果需要额外的 prop 选项,应该在 model 名称之后传递
js
const title = defineModel('title', { required: true })