多的人,花少的钱,用高的效率,学多的知识,早日实现 职业自由
Vue:表单输入绑定 / v-model

当前系列: 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修饰的事件绑定的不同

其他:详见文档


作业

  1. HTML表单页面更改成用Vue渲染,并能绑定到ViewModel(不包含文件
  2. 完成课堂上没有完成的checkbox绑定


vue.js 表单 form v-model
觉得很 ,不要忘记分享哟!

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

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

我们的 特色

  • 面向就业
  • 线上线下结合
  • 同学互助
  • 师生共赢

报班 QQ群:273534701

  • 获取视频资料
  • 要求作业点评
  • 参加阶段性测试
  • 模拟面试