双向绑定
什么是双向绑定
在前端处理表单时,常常需要将表单输入的内容同步给 Javascript 变量,或者将 Javascript 变量的值同步给表单输入。这种双向的数据同步,就是双向绑定。
WARNING
v-model
只能用在表单元素上。v-model
会忽略所有表单元素的value
、checked
、selected
特性的初始值,而总是将Vue 实例
的数据作为数据来源。v-model
会根据所使用的元素自动使用对应的 DOM 属性和事件组合:<input>
和<textarea>
元素绑定value
属性并监听input
事件;checkbox
和radio
绑定checked
属性并监听change
事件;<select>
绑定value
属性并监听change
事件。
文本框
vue
<template>
<div class="div-box">
<!-- 单行文本框 -->
<p>Single Line Message is: {{ singleLineMsg }}</p>
<input v-model="singleLineMsg" placeholder="edit me" />
<!-- 多行文本框 -->
<p style="white-space: pre-line;">Multiple Line Message is: {{ multipleLinesMsg }}</p>
<textarea v-model="multipleLinesMsg" placeholder="add multiple lines"></textarea>
</div>
</template>
<script setup>
import { ref } from 'vue'
const singleLineMsg = ref('');
const multipleLinesMsg = ref('');
</script>
复选框
vue
<template>
<div class="div-box">
<!-- 单一复选框,绑定布尔值 -->
<input type="checkbox" id="checkbox" v-model="checked" />
<label for="checkbox">{{ checked }}</label>
<!-- 多个复选框,绑定数组 -->
<div>Checked names: {{ checkedNames }}</div>
<input type="checkbox" id="jack" value="Jack" v-model="checkedNames" />
<label for="jack">Jack</label>
<input type="checkbox" id="john" value="John" v-model="checkedNames" />
<label for="john">John</label>
<input type="checkbox" id="mike" value="Mike" v-model="checkedNames" />
<label for="mike">Mike</label>
</div>
</template>
<script setup>
import { ref } from 'vue'
const checked = ref(false);
const checkedNames = ref([]);
</script>
vue
<template>
<div class="div-box">
<input type="checkbox" id="checkbox" :true-value="dynamicTrueValue" :false-value="dynamicFalseValue"
v-model="toggle" />
<label for="checkbox">{{ toggle }}</label>
</div>
</template>
<script setup>
import { ref } from 'vue'
const dynamicFalseValue = 'no';
const dynamicTrueValue = 'yes';
const toggle = ref(dynamicFalseValue);
</script>
单选框
vue
<template>
<div class="div-box">
<div>Picked: {{ picked }}</div>
<input type="radio" id="one" value="One" v-model="picked" />
<label for="one">One</label>
<input type="radio" id="two" value="Two" v-model="picked" />
<label for="two">Two</label>
</div>
</template>
<script setup>
import { ref } from 'vue'
const picked = ref('');
</script>
vue
<template>
<div class="div-box">
<div>Picked: {{ pick }}</div>
<input type="radio" id="one" v-model="pick" :value="first" />
<label for="one">One</label>
<input type="radio" id="two" v-model="pick" :value="second" />
<label for="two">Two</label>
</div>
</template>
<script setup>
import { ref } from 'vue'
const pick = ref('');
const first = 'first';
const second = 'second';
</script>
下拉选框
Details
如果 v-model
表达式的初始值不匹配任何一个选择项,<select>
元素会渲染成一个“未选择”的状态。在 iOS 上,这将导致用户无法选择第一项,因为 iOS 在这种情况下不会触发一个 change 事件。因此,建议提供一个空值的禁用选项。
vue
<template>
<div class="div-box">
<!-- 单选 -->
<div>Selected: {{ selected }}</div>
<select v-model="selected">
<option disabled value="">Please select one</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
<!-- 多选 -->
<div>Selected: {{ multipleSelected }}</div>
<select v-model="multipleSelected" multiple>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
</div>
</template>
<script setup>
import { ref } from 'vue'
const selected = ref();
const multipleSelected = ref([]);
</script>
vue
<template>
<div class="div-box">
<div>Selected: {{ selected.number }}</div>
<select v-model="selected">
<option disabled value="">Please select one</option>
<option :value="{ number: 123 }">A</option>
<option :value="{ number: 456 }">B</option>
<option :value="{ number: 789 }">C</option>
</select>
</div>
</template>
<script setup>
import { ref } from 'vue'
const selected = ref({ number: undefined });
</script>