主题
原生 v-model(表单输入绑定)
单行文本
v-model 会绑定 value 属性并监听 input 事件。
vue
<script setup>
import { ref } from 'vue'
const msg = ref('hello')
</script>
<template>
<div>msg: {{ msg }}</div>
<!-- v-model -->
<input v-model="msg" />
<!-- value + @input -->
<input :value="msg" @input="(e) => (msg = e.target.value)" />
</template>多行文本
v-model 会绑定 value 属性并监听 input 事件。
vue
<script setup>
import { ref } from 'vue'
const msg = ref('hello')
</script>
<template>
<div>msg: {{ msg }}</div>
<!-- v-model -->
<textarea v-model="msg" />
<!-- value + @input -->
<textarea :value="msg" @input="(e) => (msg = e.target.value)" />
</template>单选按钮
v-model 会绑定 checked 属性并监听 change 事件。
vue
<script setup>
import { ref } from 'vue'
const picked = ref('')
</script>
<template>
<div>picked: {{ picked }}</div>
<!-- v-model -->
<label>
One
<input type="radio" value="One" v-model="picked" />
</label>
<label>
Two
<input type="radio" value="Two" v-model="picked" />
</label>
<!-- value + @change -->
<label>
One
<input type="radio" value="One" :checked="picked === 'One'" @change="(e) => (picked = e.target.value)" />
</label>
<label>
Two
<input type="radio" value="Two" :checked="picked === 'Two'" @change="(e) => (picked = e.target.value)" />
</label>
</template>复选框
复选框有两种情况:
- 单个复选框,绑定布尔类型值。
- 多个复选框,绑定到同一个数组或集合的值。
单个复选框
v-model 会绑定 checked 属性并监听 change 事件。
vue
<script setup>
import { ref } from 'vue'
const checked = ref(false)
</script>
<template>
<div>checked: {{ checked }}</div>
<!-- v-model -->
<input type="checkbox" id="checkbox" v-model="checked" />
<!-- checked + @change -->
<input type="checkbox" id="checkbox" :checked="checked" @change="(e) => (checked = e.target.checked)" />
</template>值绑定
默认情况下,v-model 绑定的值(toggle)只会是布尔值 true 和 false。
true-value 和 false-value 是 Vue 特有的 attributes,仅支持和 v-model 配套使用。toggle 属性的值会在选中时被设为 'yes',取消选择时设为 'no'。
template
<input
type="checkbox"
v-model="toggle"
true-value="yes"
false-value="no" />多个复选框
v-model 会绑定 checked 属性并监听 change 事件。
vue
<script setup>
import { ref } from 'vue'
const checkedNames = ref([])
// --- checked + @change ---
const checkedNamesSet = new Set([])
const handleCheckboxChange = (e) => {
const { checked, value } = e.target
if (checked) {
checkedNamesSet.add(value)
} else {
checkedNamesSet.delete(value)
}
checkedNames.value = Array.from(checkedNamesSet)
}
</script>
<template>
<div>checkedNames: {{ checkedNames }}</div>
<!-- v-model -->
<label>
<input type="checkbox" value="Jack" v-model="checkedNames" />
Jack
</label>
<label>
<input type="checkbox" value="John" v-model="checkedNames" />
John
</label>
<label>
<input type="checkbox" value="Mike" v-model="checkedNames" />
Mike
</label>
<!-- checked + @change -->
<label>
<input type="checkbox" value="Jack" :checked="checkedNames.includes('Jack')" @change="handleCheckboxChange" />
Jack
</label>
<label>
<input type="checkbox" value="John" :checked="checkedNames.includes('John')" @change="handleCheckboxChange" />
John
</label>
<label>
<input type="checkbox" value="Mike" :checked="checkedNames.includes('Mike')" @change="handleCheckboxChange" />
Mike
</label>
</template>选择器
选择器有两种情况:
- 单选
- 多选 (值绑定到一个数组)
单选
v-model 会绑定 value 属性并监听 change 事件。
vue
<script setup>
import { ref } from 'vue'
const selected = ref('')
</script>
<template>
<div>selected: {{ selected }}</div>
<!-- v-model -->
<select v-model="selected">
<option value="">Please select one</option>
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
</select>
<!-- value + @change -->
<select :value="selected" @change="(e) => (selected = e.target.value)">
<option value="">Please select one</option>
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
</select>
</template>多选
v-model 会绑定 value 属性并监听 change 事件。
vue
<script setup>
import { ref } from 'vue'
const multiSelected = ref([])
const handleSelectChange = (e) => {
const selected = Array.from(e.target.selectedOptions).map((opt) => opt.value)
multiSelected.value = selected
}
</script>
<template>
<div>Selected: {{ multiSelected }}</div>
<!-- v-model -->
<select v-model="multiSelected" multiple>
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
</select>
<!-- value + @change -->
<select :value="multiSelected" @change="handleSelectChange" multiple>
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
</select>
</template>修饰符
.lazy
默认情况下,v-model 会 在每次 input 事件后更新数据。v-model.lazy 会将行为改为 在每次 change 事件后更新数据:
template
<!-- 在 "change" 事件后同步更新而不是 "input" -->
<input v-model.lazy="msg" />.number
v-model.number 会尝试把用户的输入值转换为一个数字,如果该值无法被 parseFloat() 处理,那么将返回原始值。
template
<input v-model.number="age" />提示
number 修饰符会在输入框有 type="number" 时自动启用。
.trim
v-model.trim 会自动去除用户输入内容中两端的空格:
template
<input v-model.trim="msg" />