v-model 是 Vue.js 中一个非常实用的指令,它简化了双向数据绑定的过程。
在 Vue 3 (Vue 3.4 之前版本)中,使用 v-model方式:
<template>
<input v-model="message" placeholder="edit me">
<p>Message is: {{ message }}</p>
</template>
<script>
import { ref } from 'vue';
export default {
setup() {
const message = ref('');
return {
message,
};
},
};
</script>
原理:
通过 modelValue 作为 prop 和 update:modelValue 作为事件来实现的。这意味着你可以自定义 v-model 的行为和绑定的属性。例如,你可以为一个自定义组件实现一个基于 checked 属性的 v-model:
<!-- MyCheckbox.vue -->
<template>
<input
type="checkbox"
:checked="modelValue"
@change="$emit('update:modelValue', $event.target.checked)"
>
</template>
<script>
export default {
props: {
modelValue: Boolean,
},
};
</script>
然后,你可以像下面这样使用 MyCheckbox 组件,并通过 v-model 绑定一个变量:
<template>
<MyCheckbox v-model="isChecked" />
</template>
<script>
import { ref } from 'vue';
import MyCheckbox from './MyCheckbox.vue';
export default {
components: { MyCheckbox },
setup() {
const isChecked = ref(false);
return {
isChecked,
};
},
};
</script>
从 Vue 3.4 开始,官方推荐使用 defineModel() 宏实现:
<script setup>
const model = defineModel()
</script>
<template>
<input v-model="model" />
</template>
更多用法:
//默认值
const title = defineModel('title')
// 使 v-model 必填
const model = defineModel({ required: true })
// 提供一个默认值
const model = defineModel({ default: 0 })
//如果需要额外的 prop 选项,应该在 model 名称之后传递:
const title = defineModel('title', { required: true })
//多个 v-model 绑定
const firstName = defineModel('firstName')
const lastName = defineModel('lastName')
//处理 v-model 修饰符.trim,.number , .lazy ,.capitalize
<MyComponent v-model.capitalize="myText" />
//带参数的 v-model 修饰符
//3.4之后的用法
<UserName
v-model:first-name.capitalize="first"
v-model:last-name.uppercase="last"
/>
//3.4之前的用法
<script setup>
const props = defineProps({
firstName: String,
lastName: String,
firstNameModifiers: { default: () => ({}) },
lastNameModifiers: { default: () => ({}) }
})
defineEmits(['update:firstName', 'update:lastName'])
console.log(props.firstNameModifiers) // { capitalize: true }
console.log(props.lastNameModifiers) // { uppercase: true}
</script>