之前我们学习的都是将vue data的数据绑定到HTML模板上,能不能反过来,把DOM上的数据绑定到vue data呢?首先我们想到的,肯定就是form表单。
在表单元素上添加v-model指令,指向vue data(此后改称ViewModel),就能实现:
这又被称之为双向绑定。
<input type="text" v-model="body" />
data: { body: 'Hello, 源栈' }vue-devtools演示:修改文本框的值,vue data的值相应变化
注意:
还可以绑定复杂的、嵌套层级的v-model:
data: { body: { short: 'Hi', full: 'Hello, 源栈' } }
<input type="text" v-model="body.full" value="一起帮" />
甚至body.full属性不用在ViewModel中声明
data: { body: {} //但必须保证body是一个对象 }
和input极其类似:
<textarea v-model="body.full"></textarea>不要以为这样可以生效:(再次理解是渲染而不是拼接)
<textarea>{{body.full}}</textarea>
<input type="radio" value="1" v-model="enrolled" /> 夏康平 <input type="radio" value="6" v-model="enrolled" /> 韩佳宝
data: { enrolled: 6 }@想一想@:多个radio能不能用v-for渲染?
比如说,我们从后台拿到了一组学生对象,每个学生都有id和name:
data: { students: [ { id: 8, name: '夏康平' }, { id: 12, name: '陈国栋' }, { id: 6, name: '韩佳宝' } ], selectedId:'' }
这时候就需要一个额外的selectedId,存储用户选中的值。然后:
<label v-for="s of students"> <input type="radio" :value="s.id" v-model="selectedId" />{{s.name}} </label>
演示:
单个复选框,和radio很类似(不需要value):
<input type="checkbox" v-model="remember" />记住我
绑定到布尔值:
data: { remember: true }
多个复选框(需要指定value了)
<input type="checkbox" value="1" v-model="students" />夏康平 <input type="checkbox" value="12" v-model="students" />陈国栋 <input type="checkbox" value="6" v-model="students" />韩佳宝
绑定到同一个数组:
data: { students: [12] }@试一试@:多个checkbox用v-for渲染
再进一步,ViewModel数据还指定了学生是否已经入栈(enrolled),要求render时已入栈学生就已经被勾选了:
students: [ { id: 8, name: '夏康平', enrolled: true }, { id: 12, name: '陈国栋', enrolled: false }, { id: 6, name: '韩佳宝', enrolled: true } ],这就需要计算属性了:
computed: { enrolleds: function () { return this.students.filter(function (s) { return s.enrolled; }).map(function (s) { return s.id; }) } }
@想一想@:用户勾选的值怎么传递给ViewModel?(作业)
<select v-model="selectedId"> <!--注意v-model放置在select元素中,添加mutiple变成多选--> <option v-for="s of students" :value="s.id" >{{s.name}}</option> </select>
//单选类型为基本类型 selectedId: 12 //多选:类型为数组 //selectedId: []
唯一需要注意的是:单选时,如果 v-model 表达式的初始值未能匹配任何选项,<select> 元素将被渲染为“未选中”状态。
但是,一旦用户选择之后,就无法再恢复到“未选中”状态。要避免这种情况,可以额外添加一个option:
<option value="">------</option>
<input type="text" v-model.lazy="body" />
<input type="text" v-model.number="body" />
<input type="text" v-model.trim="body" />
也可以同时添加多个:
<input type="text" v-model.lazy.trim.number="body" />
F12控制台演示:有无.lazy修饰的事件绑定的不同
其他:详见文档
<ul> <li v-for="item in list"> <input type="checkbox"> {{item.name}} </li> </ul>
data: { list: [ { id: 1, name: '阿泰' }, { id: 2, name: '波仔' }, { id: 3, name: '浪神' } ] },勾选上“波仔”,然后修改vue data:
vm.list.unshift({ id: 4, name: '大飞哥' })
仔细观察:这时候勾选中的是谁?还是不是“波仔”?为什么?因为:
怎么消除这种混乱呢?使用v-bind:key标记每一个DOM元素:
<li v-for="item in list" v-bind:key="item.id">
key值不能重复!
如果能够找到不重复的key,建议总是使用:key标记子元素:减少bug,提高性能。
多快好省!前端后端,线上线下,名师精讲
更多了解 加: