键盘敲烂,月薪过万作业不做,等于没学
当前系列: Vue.js 修改讲义

之前我们学习的都是将vue data的数据绑定到HTML模板上,能不能反过来,把DOM上的数据绑定到vue data呢?首先我们想到的,肯定就是form表单。


v-model

在表单元素上添加v-model指令,指向vue data(此后改称ViewModel),就能实现:

  • 页面渲染时,根据ViewModel的值呈现form表单项的初始值
  • 用户输入/选择时,将用户输入/选择的数据,自动绑定到指定的ViewModel

这又被称之为双向绑定


text

<input type="text" v-model="body" />
data: {
    body: 'Hello, 源栈'
}
vue-devtools演示:修改文本框的值,vue data的值相应变化

注意

  • input不一定要放form里了,因为我们不一定是用form表单提交的方式往后台传递数据,而是通过Ajax
  • input自带的value属性被忽略(其他所有表单元素的value、checked、selected特性的初始值也都会被忽略)

还可以绑定复杂的、嵌套层级的v-model:

data: {
    body: {
        short: 'Hi',
        full: 'Hello, 源栈'
    }
}
<input type="text" v-model="body.full" value="一起帮" />

甚至body.full属性不用在ViewModel中声明

data: {
    body: {}  //但必须保证body是一个对象
}


textarea

和input极其类似:

<textarea v-model="body.full"></textarea>
不要以为这样可以生效:(再次理解是渲染而不是拼接
<textarea>{{body.full}}</textarea>


radio

v-model指定的是ViewModel中对应的属性名,当用户选中时赋予它value的值:
<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>

演示:

  • 能不能不要label
  • 或者,不要selectedIds
  • value前面为什么有个冒号


checkbox

单个复选框,和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

也分为单选和多选,和checkbox非常类似了。直接上代码:
<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>


修饰符

可以在v-model后面添加一个后缀(修饰符)
  • .lazy:在 change 事件_之后_进行同步:(相比render,v-model的绑定实现原理简单很多,就是通过JavaScript事件机制实现的)
    <input type="text" v-model.lazy="body" />
  • .number:自动将用户的输入值转为数值类型
    <input type="text" v-model.number="body" />
  • .trim:自动过滤用户输入的首尾空白字符
    <input type="text" v-model.trim="body" />

也可以同时添加多个:

<input type="text" v-model.lazy.trim.number="body" />

F12控制台演示:有无.lazy修饰的事件绑定的不同

其他:详见文档


v-for中的key

先上代码:
<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: '大飞哥' })

仔细观察:这时候勾选中的是谁?还是不是“波仔”?为什么?因为:

  • vue的重新渲染,不是把数组中每个元素对应的Html元素都重新渲染一次(为了提高性能)
  • 而是使用一种diff算法,对比新旧两种结果,只改变“需要改变”的


怎么消除这种混乱呢?使用v-bind:key标记每一个DOM元素:

<li v-for="item in list" v-bind:key="item.id">

key值能重复!

如果能够找到不重复的key,建议总是使用:key标记子元素:减少bug,提高性能。


作业

  1. HTML表单页面更改成用Vue渲染,并能绑定到ViewModel(不包含文件
  2. 完成课堂上没有完成的checkbox绑定
学习笔记
源栈学历
大多数人,都低估了编程学习的难度,而高估了自己的学习能力和毅力。

作业

觉得很 ,不要忘记分享哟!

任何问题,都可以直接加 QQ群:273534701

在当前系列 Vue.js 中继续学习:

多快好省!前端后端,线上线下,名师精讲

  • 先学习,后付费;
  • 不满意,不要钱。
  • 编程培训班,我就选源栈

更多了解 加:

QQ群:273534701

答疑解惑,远程debug……

B站 源栈-小九 的直播间

写代码要保持微笑 (๑•̀ㅂ•́)و✧

公众号:源栈一起帮

二维码