日常开发中我们不可避免要用到表单提交数据,因此我们就会使用v-model指令。接下来我们就来讨论一下v-model的实现原理吧
原生元素使用v-model
<input v-model="message"></input>
上边代码等价于
<input :value="message" @input="message = $event.target.value"></input>
解析
v-model实际就是一个语法糖,它包含两个步骤,
第一步:绑定value的值
第二步:当input的值改变时把当前值赋值给绑定的value
组件上使用v-model
<!-- 父组件 -->
<h3>我是父组件:{{msg}}</h3>
<CustomInput v-model="msg"></CustomInput>
<!-- CustomInput 子组件 -->
<template>
<input :value="modelValue" @input="$emit('update:modelValue', $event.target.value)"></input>
</template>
<script setup>
// 定义Props
defineProps(['modelValue'])
// 定义自定义事件
defineEmits(['update:modelValue'])
</script>
解析
默认情况下组件绑定的值是modelValue
,而触发的update:modelValue
方法来修改modelValue
的值
我们也可以使用computed计算属性实现组件的v-model指令
使用计算属性实现v-model
<!-- CustomInput 子组件 -->
<template>
<input v-model="value" />
</template>
<script setup>
import { computed } from 'vue';
// 定义Props
const props = defineProps(['modelValue'])
// 定义自定义事件
const emit = defineEmits(['update:modelValue'])
// 使用计算属性响应式数据
const value = computed({
get() {
return props.modelValue
},
set(value) {
emit('update:modelValue', value)
}
})
</script>
一个组件多个v-model
<!-- CustomInput 子组件 -->
<template>
我是自定义组件:
<input :value="modelValue" @input="$emit('update:modelValue', $event.target.value)">
<div>
姓:
<input :value="firstName" @input="changeFirstName($event)" />
名:
<input v-model="second_name" />
</div>
</template>
<script setup>
// 导入计算函数
import { computed } from 'vue';
// 定义props
const props = defineProps(['modelValue', 'firstName', 'secondName'])
// 定义emit触发方法
const emit = defineEmits(['update:modelValue', 'update:firstName', 'update:secondName'])
// 修改姓
const changeFirstName = function (e) {
emit('update:firstName', e.target.value)
}
// 修改名 使用计算属性修改
const second_name = computed({
get() {
return props.secondName
},
set(value) {
emit('update:secondName', value)
}
})
</script>
<!-- 父组件 -->
<h3>我是父组件:{{msg}}</h3>
<h4>我的名字是:{{firstName + secondName}}</h4>
<CustomInput v-model="msg" v-model:firstName="firstName" v-model:secondName="secondName"></CustomInput>