08表单绑定
表单绑定
表单控件在实际开发中是非常常见的。特别是对于用户信息的提交,需要大量的表单。
Vue中使用v-model指令来实现表单元素和数据的双向绑定。
<body>
<div id="app">
<input type="text" v-model="massage">
{{massage}}
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: "#app",
data: {
massage: "你好"
}
})
</script>
</body>
当我们在输入框输入内容时
因为input中的v-model绑定了message ,所以会实时将输入的内容传递给message , message发生改变。
当message发生改变时,因为上面我们使用Mustache语法,将message的值插入到DOM中,所以DOM会发生响应的改变。
所以,通过v-model实现了双向的绑定。
原理
<div id="app">
<!-- <input type="text" v-model="massage"> -->
<!-- <input type="text" :value="massage" @input="valueChange"> -->
<input type="text" :value="massage" @input="massage = $event.target.value">
{{massage}}
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: "#app",
data: {
massage: "你好"
},
methods: {
valueChange(event) {
this.massage = event.target.value;
}
}
})
</script>
</body>
v-model结合radio类型
<div id="app">
<label for="">
<input type="radio" id="male" value="男" v-model="sex">男
</label>
<label for="">
<input type="radio" id="female" value="女" v-model="sex">女
</label>
<h2>{{sex}}</h2>
</div>
<body>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: "#app",
data: {
message: "你好",
sex:'男'
}
})
</script>
</body>
v-model结合checkbox类型
单个勾选框: .
v-modelI即为布尔值。
此时input的value并不影响v-model的值。
多个复选框:
多个复选框时,因为可以选中多个,所以对应的data中属性是一个数组。
当选中某一个时 ,就会将input的value添加到数组中。
<div id="app">
<!-- 单选框 -->
<!-- <label for="agree">
<input type="checkbox" id="agree" v-model="isAgree">同意协议
</label>
<h2>{{isAgree}}</h2>
<button :disabled="!isAgree">下一步</button> -->
<!-- 多选框 -->
<!-- <input type="checkbox" value="篮球" v-model="hobbies">篮球
<input type="checkbox" value="足球" v-model="hobbies">足球
<input type="checkbox" value="排球" v-model="hobbies">排球
<input type="checkbox" value="手球" v-model="hobbies">手球
<h2>{{hobbies}}</h2> -->
<label v-for="item in originHobbies" :for="item">
<input type="checkbox" :value="item" :id="item" v-model="hobbies">{{item}}
</label>
</div>
<body>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: "#app",
data: {
message: "你好",
isAgree: false,//单选框
hobbies:[],//多选框
originHobbies:['篮球','足球','乒乓球','台球','高尔夫球']
//也可以通过值绑定来从服务器获取值
}
})
</script>
</body>
v-model结合select
单选:只能选中一个值。
v-model绑定的是一个值。
当我们选中option中的一个时,会将它对应的value赋值到mySelect中
多选:可以选中多个值。
v-model绑定的是一个数组。
当选中多个值时,就会将选中的option对应的value添加到数组mySelects中
<body>
<div id="app">
<!-- 1、选择一个 -->
<select name="abc" id="" v-model="fruit">
<option value="苹果">苹果</option>
<option value="香蕉">香蕉</option>
<option value="榴莲">榴莲</option>
<option value="西瓜">西瓜</option>
</select>
<h2>{{fruit}}</h2>
<!-- 2、选择多个 -->
<select name="abc" id="" v-model="fruits" multiple>
<option value="苹果">苹果</option>
<option value="香蕉">香蕉</option>
<option value="榴莲">榴莲</option>
<option value="西瓜">西瓜</option>
</select>
<h2>{{fruits}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: "#app",
data: {
message: "你好",
fruit:"香蕉",
fruits:[]
}
})
</script>
</body>
v-model的修饰符
lazy修饰符:
默认情况下, v- model默认是在input事件中同步输入框的数据的。
也就是说, 一旦有数据发生改变对应的data中的数据就会自动发生
改变。
lazy修饰符可以让数据在失去焦点或者回车时才会更新:
number修饰符:
默认情况下,在输入框中无论我们输入的是字母还是数字,都会被
当做字符串类型进行处理。
但是如果我们希望处理的是数字类型,那么最好直接将内容当做数
字处理。
number修饰符可以让在输入框中输入的内容自动转成数字类型:
trim修饰符:
如果输入的内容首尾有很多空格,通常我们希望将其去除
trim修饰符可以过滤内容左右两边的空格
<div id="app">
<!-- 1.修饰符:lazy -->
<input type="text" v-model.lazy="message">
<h2>{{message}}</h2>
<!-- 2.修饰符:number -->
<input type="number" v-model.number="age">
<h2>{{typeof age}}</h2>
<!-- 3.修饰符:trim -->
<input type="text" v-model.trim="name">
<h2>{{name}}</h2>
</div>
<body>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: "#app",
data: {
message: "你好",
age:12,
name:''
}
})
</script>
</body>
综合-书籍购物车案例
- HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="./style.css">
</head>
<body>
<div id="app">
<div v-if="books.length">
<table>
<thead>
<tr>
<th></th>
<th>书籍名称</th>
<th> 出版日期</th>
<th> 价格</th>
<th> 购买数量</th>
<th> 操作</th>
</tr>
</thead>
<tbody>
<tr v-for="(item,index) in books">
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.date}}</td>
<td>{{item.price | showPrice}}</td>
<td>
<button @click="decrement(index)" v-bind:disabled="item.count <= 1">-</button>
{{item.count}}
<button @click="increment(index)">+</button>
</td>
<td><button @click="removeHandler(index)">移除</button></td>
</tr>
</tbody>
</table>
<h2>
总价格: {{totalPrice | showPrice}}
</h2>
</div>
<div v-else>
<h1>购物车为空</h1>
</div>
</div>
<script src="../js/vue.js"></script>
<script src="./main.js"></script>
</body>
</html>
- CSS
table{
border: 1px solid #000;
border-collapse: collapse;
border-spacing: 0;
}
th,td{
padding: 8px 16px;
border: 1px solid #000;
text-align: left;
}
th{
background-color: #f7f7f7;
color: #5c6b77;
font-weight: 600;
}
- JS
const app = new Vue({
el: "#app",
data: {
books: [{
id: 1,
name: '《算法导论》',
date: "2006-9",
price: 85.00,
count: 1
},
{
id: 2,
name: '《算法导论》',
date: "2006-9",
price: 85.00,
count: 1
},
{
id: 3,
name: '《算法导论》',
date: "2006-9",
price: 85.00,
count: 1
},
{
id: 4,
name: '《算法导论》',
date: "2006-9",
price: 85.00,
count: 1
}
]
},
methods: {
// getFinalPrice(price){
// return '¥'+price.toFixed(2) //toFixed(2)保留两位小数
// }
increment(index) {
this.books[index].count++
},
decrement(index) {
this.books[index].count--
},
removeHandler(index) {
this.books.splice(index, 1)
}
},
filters: { //过滤器
showPrice(price) {
return '¥' + price.toFixed(2)
}
},
computed: {
totalPrice() {
let totalPrice = 0;
for (let i = 0; i < this.books.length; i++) {
totalPrice += this.books[i].price * this.books[i].count;
}
return totalPrice;
}
}
})

浙公网安备 33010602011771号