通常是在 form 表单相关的场景中会用到双向绑定相关, 核心是 v-model 的应用.
input 输入框
<!DOCTYPE html>
<html lang="en">
<head>
<title>input</title>
<script src="https://unpkg.com/vue@3"></script>
</head>
<body>
<div id="root"></div>
<script>
const app = Vue.createApp({
data () {
return {
message: 'hello, youge'
}
},
template: `
<div>
{{message}}
<input v-model="message" />
</div>
`
})
const vm = app.mount('#root')
</script>
</body>
</html>
这里双向绑定指的是, message 和 input 框的输入内容和数据是"互相绑定和同步的" 任何一个发生改变, 则另一个同样改变, 核心就是 v-model 的功效. 对于 input 来说, 这里就不用写 value 相关的了.
<div>
{{message}}
<input v-model="message" />
</div>
textarea 多行输入框
多行输入标签和 input 是一样的写法. 同原生不同在于, 就一个单标签的方式即可完成编写.
template: `
<div>
{{message}}
<textarea v-model="message" />
</div>
`
radio 单选框
单选框, 只能选中一个选项, 因此用字符串来存储数据是非常合适的.
<!DOCTYPE html>
<html lang="en">
<head>
<title>radio</title>
<script src="https://unpkg.com/vue@3"></script>
</head>
<body>
<div id="root"></div>
<script>
const app = Vue.createApp({
data () {
return {
message: ""
}
},
template: `
<div>
{{message}}
youge <input type="radio" v-model="message" value="youge" />
youni <input type="radio" v-model="message" value="youni" />
myson <input type="radio" v-model="message" value="myson" />
</div>
`
})
const vm = app.mount('#root')
</script>
</body>
</html>
checkbox 多选框
复选框就稍微复杂一点, 需要 value 来做标记, 同时数据的存储可以通过数组.
<!DOCTYPE html>
<html lang="en">
<head>
<title>chexbox</title>
<script src="https://unpkg.com/vue@3"></script>
</head>
<body>
<div id="root"></div>
<script>
const app = Vue.createApp({
data () {
return {
message: []
}
},
template: `
<div>
{{message}}
youge <input type="checkbox" v-model="message" value="youge" />
youni <input type="checkbox" v-model="message" value="youni" />
myson <input type="checkbox" v-model="message" value="myson" />
</div>
`
})
const vm = app.mount('#root')
</script>
</body>
</html>
// 就勾选了 1, 3 然后数组显示了 1, 3
[ "myson", "youge" ] youge youni myson
因此 单选框 radio 和 多选框 checkbox 的共性都是需要 value 属性来绑定数据, 差异在于数据的存储上, radio 用字符串存储, checkbox 用数组存储即可.
checkbox 自定义属性值
即我们想实现, 即刷新页面是, 选项默认是 "未选中", 当勾选选项时, 则显示 "已选中"
<!DOCTYPE html>
<html lang="en">
<head>
<title>checkbox 自定义属性值</title>
<script src="https://unpkg.com/vue@3"></script>
</head>
<body>
<div id="root"></div>
<script>
const app = Vue.createApp({
data () {
return {
message: "未选中"
}
},
template: `
<div>
{{message}}
<input
type="checkbox"
v-model="message"
true-value="已选中"
false-value="未选中"
/>
</div>
`
})
const vm = app.mount('#root')
</script>
</body>
</html>
核心的控制在于默认 message: "未选中" 且 false-value: "未选中". 这样就双向绑定啦.
select 下拉框
下拉框其实也就分单选和多选, 用法和上面的标签是一致的, 先来看单选的情况.
<!DOCTYPE html>
<html lang="en">
<head>
<title>select 单选下拉框</title>
<script src="https://unpkg.com/vue@3"></script>
</head>
<body>
<div id="root"></div>
<script>
const app = Vue.createApp({
data () {
return {
message: ""
}
},
template: `
<div>
{{message}}
<select v-model="message">
<option value="" disabled>请选择内容</option>
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
<option value="D">D</option>
<option value="E">E</option>
</select>
</div>
`
})
const vm = app.mount('#root')
</script>
</body>
</html>
多选其实即在 select 中加上 multiple 关键字即可. 在实际的应用中, 我们会将这些 value 相关的都将其定义或者存储在 data 中, 这样以数据接口的方式来进行动态生成.
<!DOCTYPE html>
<html lang="en">
<head>
<title>select 多选下拉框</title>
<script src="https://unpkg.com/vue@3"></script>
</head>
<body>
<div id="root"></div>
<script>
const app = Vue.createApp({
data () {
return {
message: "",
options: [
{ text: 'A', value: { value: 'A'}},
{ text: 'B', value: { value: 'B'}},
{ text: 'C', value: { value: 'C'}},
{ text: 'D', value: { value: 'D'}},
{ text: 'E', value: { value: 'E'}},
]
}
},
template: `
<div>
{{message}}
<select v-model="message" multiple>
<option
v-for="(item, index) in options"
:key=index
:value=item.value
>
{{item.text}}
</option>
</select>
</div>
`
})
const vm = app.mount('#root')
</script>
</body>
</html>
/数据展示是 B, C, D 但数据存储则是如下这种更友好的 json 就很 nice .
[ { "value": "B" }, { "value": "C" }, { "value": "D" } ]
v-model 修饰符
这里以 input 标签为例, 主要演示 lazy, number, trim 等常用的即可.
<!DOCTYPE html>
<html lang="en">
<head>
<title>表单元素修饰符</title>
<script src="https://unpkg.com/vue@3"></script>
</head>
<body>
<div id="root"></div>
<script>
const app = Vue.createApp({
data () {
return { message: "hello"}
},
template: `
<div>
{{message}}
<input v-model.lazy="message" />
</div>
`
})
const vm = app.mount('#root')
</script>
</body>
</html>
这里 v-model.lazy = "message" 的意思是, 要等用户在输出框填完内容后, 移除焦点, 数据才会变化. 这个能有一定的性能优化, 同时用户体验也是蛮好的.
另外常用的也就挑两个一并小结一波吧, 仍然以 input 输入框为例:
- v-model.lazy: 等用户填完并失去焦点后, 数据才发生变化
- v-model.number: 当感知到输入的是 number 时, 会自动将值转为 number 存储
- v-model.trim: 会自动将用户输入的首尾空格去掉 (主要是用户就喜欢乱加空格), 中间不能哈