目录
1. 定义一个名为 modelValue 的 props 属性和一个名为 update:modelValue 的事件
2.使用一个可写的,同时具有 getter 和 setter 的 computed 属性
前言
v-model 是 Vue 框架中用于实现双向数据绑定的指令之一,在 Vue 3 中保留了这一特性,并对其进行了一些改进。Vue 3 的 v-model 指令更加灵活,可以适用于原生 HTML 元素和自定义组件,并支持修饰符的使用。
一、原生元素上的用法
在 Vue 3 中,我们可以通过 v-model 在原生 HTML 元素上实现双向数据绑定。v-model 可以应用于 input、textarea 和 select 等表单元素。
1. 输入框(input)
在Vue 3中,可以通过v-model指令实现对输入框的双向绑定。
<template>
<div>
<input v-model="message" type="text">
<p>Message: {{ message }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue'
const message = ref('')
</script>
2. 多行文本域(textarea)
<template>
<div>
<textarea v-model="message"></textarea>
<p>Message: {{ message }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue'
const message = ref('')
</script>
3. 单选按钮(radio)
对于单选按钮,我们可以通过v-model指令绑定同一个name属性,将其与一个变量进行关联。
<template>
<div>
<input type="radio" id="option1" value="option1" v-model="selectedOption">
<label for="option1">Option 1</label>
<input type="radio" id="option2" value="option2" v-model="selectedOption">
<label for="option2">Option 2</label>
<p>Selected Option: {{ selectedOption }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue'
const selectedOption = ref('')
</script>
在上面的代码中,我们使用v-model指令绑定了两个单选按钮,并通过selectedOption变量进行双向数据绑定。用户选择其中一个选项时,selectedOption变量会更新,并且变化会实时反映在页面上。
4. 多选框(checkbox)
<template>
<div>
<input type="checkbox" id="option1" value="option1" v-model="selectedOptions">
<label for="option1">Option 1</label>
<input type="checkbox" id="option2" value="option2" v-model="selectedOptions">
<label for="option2">Option 2</label>
<p>Selected Options: {{ selectedOptions }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue'
const selectedOptions = ref([])
</script>
在这个例子中,我们使用v-model指令绑定了两个多选框,并通过selectedOptions变量进行双向数据绑定。当用户选择或取消选择其中一个多选框时,selectedOptions变量会相应地更新,并且变化会实时反映在页面上。
注意:对于多选框,使用v-model进行绑定的变量应该是一个数组类型,用于保存选中的多个选项的值。
5. 下拉选择框(select)
<template>
<div>
<select v-model="selectedOption">
<option value="option1">Option 1</option>
<option value="option2">Option 2</option>
</select>
<p>Selected Option: {{ selectedOption }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue'
const selectedOption = ref('')
</script>
二、自定义组件上的用法
除了原生 HTML 元素,Vue 3 中的 v-model 还可以在自定义组件中使用。需要注意的是,自定义组件上使用v-model需要遵循一些规则。实现的方式有两种。
默认情况下,
v-model
在组件上都是使用modelValue
作为 prop,并以update:modelValue
作为对应的事件。
1. 定义一个名为 modelValue
的 props 属性和一个名为 update:modelValue
的事件
父组件:v-model将message
变量与该组件进行双向绑定
<template>
<div>
<child-component v-model="message"></child-component>
<p>父组件:Message: {{ message }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue'
const message = ref('')
</script>
自定义组件:v-model默认绑定的不是value,而是modelValue。发射的方法固定位为@update:modelValue。
<template>
<div>
子组件
<input :value="modelValue" @input="$emit('update:modelValue', $event.target.value)" />
</div>
</template>
<script setup>
defineProps({
modelValue: {
type: String
}
})
defineEmits(['update:modelValue'])
</script>
在自定义组件的模板中,我们使用:value来绑定输入框的值,并通过@input监听输入事件。同时,使用$emit函数触发update:modelValue事件,将输入框的新值传递给父组件。
通过使用props和事件,我们可以实现自定义组件上类似于原生表单元素的双向绑定效果。
2.使用一个可写的,同时具有 getter 和 setter 的 computed
属性
父组件:同上
自定义组件:get 方法需返回 modelValue prop,而 set 方法需触发相应的事件。
<template>
<div>
子组件
<input :value="modelValue" @input="$emit('update:modelValue', $event.target.value)" />
</div>
</template>
<script setup>
import { computed } from 'vue'
const props = defineProps({
modelValue: {
type: String
}
})
defineEmits(['update:modelValue'])
computed({
get() {
return props.modelValue
},
set(value) {
emit('update:modelValue', value)
}
})
</script>
三、v-model修饰符
除了基本的双向绑定外,Vue 3 的 v-model 还支持多种修饰符。常用的修饰符有 .lazy
和 .number
。
1. lazy
修饰符
.lazy
修饰符可以使输入框的值在失去焦点时才进行更新。例如:
<template>
<div>
<input type="text" v-model.lazy="message">
<p>{{ message }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue'
const message = ref('Hello, Vue 3!')
</script>
2. number
修饰符
.number
修饰符可以将输入框的值转换为数值类型。例如:
<template>
<div>
<input type="text" v-model.number="count">
<p>Count: {{ count }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue'
const count = ref(0)
</script>
四、注意事项
1. 不是所有的原生元素都能直接使用 v-model。例如,<button>
元素不能直接使用 v-model 来实现双向绑定,但可以使用其他的事件和方法来进行状态管理和更新。
2. 在自定义组件中修改modelValue
的值时,应当使用响应式的ref
或reactive
变量。