Vue对DOM元素的class和style两个特性做了专门的增强,即对CSS类和内联样式做了一层封装,通过v-bind指令来处理它们,而接收的表达式既可以是简单的字符串、对象或数组,也可以是复杂的计算属性。不仅如此,Vue还为表单设计了一些语法糖,让表单处理变得尤为简单。
## 一、CSS类
  v-bind指令与class参数配合,就能处理CSS类,并且能接收多种类型的值。
**1)对象**
  v-bind:class可以接收一个对象,对象的属性名就是CSS类名,只有当其值是真值时,才能添加到DOM元素上,否则会被忽略。下面的\<p>元素会接收数据对象中的classList,它包含两个属性warning和cur,其中cur属性保存了一个假值。
~~~html
<p v-bind:class="classList">strick</p>
<script>
var vm = new Vue({
data: {
classList: {
warning: true,
cur: ""
}
}
});
</script>
~~~
  渲染出的\<p>元素如下所示,不包含cur类。
~~~html
<p class="warning">strick</p>
~~~
  此外,v-bind:class可简写成:class,并且能与普通的class特性共存,如下所示。
~~~html
<p :class="classList" class="size">strick</p>
~~~
**2)数组**
  当v-bind:class接收一个数组时,其元素既可以是CSS类名,也可以是对象,格式与之前相同,如下所示。
~~~html
<p :class="[classList, cur]">strick</p>
<script>
var vm = new Vue({
data: {
classList: {
warning: true
},
cur: "cur"
}
});
</script>
~~~
## 二、内联样式
  v-bind指令与style参数配合,就能避免通过字符串拼接的方式来处理内联样式,并且也能接收多种类型的值。
**1)对象**
  v-bind:style可以接收一个对象,对象的属性名有两种命名方式:驼峰式和连字符分隔式,第二种就是层叠样式表中的CSS属性的命名方式。下面的\<p>元素会接收数据对象中的cssObj,其属性采用了两种命名方式。
~~~html
<p :style="cssObj">strick</p>
<script>
var vm = new Vue({
data: {
cssObj: {
"fontSize": "30px",
"line-height": 2
}
}
});
</script>
~~~
  渲染出的\<p>元素如下所示。
~~~html
<p style="font-size: 30px; line-height: 2;">strick</p>
~~~
  Vue允许为属性赋一个包含多个值的数组(即多重值),可让浏览器选择支持的属性,例如定义不同阶段的伸缩盒样式,如下所示。
~~~html
<p :style="{display: ['-webkit-box', '-ms-flexbox', 'flex']}">strick</p>
~~~
**2)数组**
  当v-bind:style接收一个数组时,其元素就是样式对象,并且如果出现同名的CSS属性,那么后面的会覆盖前面的。例如下面的cssObj1和cssObj2两个对象都包含line-height属性,而最终渲染出的值为1.5。
~~~html
<p :style="[cssObj1, cssObj2]">strick</p>
<script>
var vm = new Vue({
data: {
cssObj1: {
"fontSize": "30px",
"line-height": 2
},
cssObj2: {
"line-height": 1.5
}
}
});
</script>
~~~
**3)浏览器前缀**
  Vue会自动侦测浏览器样式的兼容性,并根据需要为CSS属性(例如border-radius、transform等)添加相应的浏览器前缀。
  下面的代码摘自Vue.js,其中camelize()函数可将连字符分隔式的字符串转换成驼峰式的字符串;vendorNames变量记录了三种浏览器前缀;normalize()函数会判断传入的属性是否存在于\<div>元素的style属性中,如果不存在,就为其添加浏览器前缀,而之所以单独处理filter属性是因为Chrome的一个bug,虽然Chrome只支持-webkit-filter属性,但是style属性中保存的却是无前缀的filter。
~~~js
var camelizeRE = /-(\w)/g;
var camelize = cached(function(str) {
return str.replace(camelizeRE, function(_, c) {
return c ? c.toUpperCase() : "";
});
});
var vendorNames = ["Webkit", "Moz", "ms"];
var emptyStyle;
var normalize = cached(function(prop) {
emptyStyle = emptyStyle || document.createElement("div").style;
prop = camelize(prop);
if (prop !== "filter" && prop in emptyStyle) {
return prop;
}
var capName = prop.charAt(0).toUpperCase() + prop.slice(1);
for (var i = 0; i < vendorNames.length; i++) {
var name = vendorNames[i] + capName;
if (name in emptyStyle) {
return name;
}
}
});
~~~
## 三、表单
  Vue提供了v-model指令,可在表单控件上实现双向数据绑定,即修改控件的值,也会自动更新Vue实例中所对应的数据对象的属性,反之亦然。
**1)v-model**
  下面用一个示例来演示v-model指令的用法,文本框的初始值是“strick”,当修改\<input>元素中的值时,\<p>元素的文本也会随之更新。
~~~html
<input type="text" v-model="name"/>
<p>{{name}}</p>
<script>
var vm = new Vue({
data: {
name: "strick"
}
});
</script>
~~~
  而如果在控制台执行下面这条赋值语句,那么就会更新\<input>元素中的值,其实这就是Vue的双向数据绑定所起的作用。
~~~js
vm.name = "freedom";
~~~
  在使用v-model指令时需要注意,表单控件的初始值得声明在数据对象的属性中,而不是value、checked或selected这些特性中。还是以之前的文本框为例,添加了一个value特性,如下所示,渲染出的控件值将是“strick”,而不是“init”。
~~~html
<input type="text" v-model="name" value="init"/>
~~~
  v-model本质上是个语法糖,它在内部会监听表单控件相关特性的变化,并触发相应的事件,其对应关系如表4所示。
:-: ![](https://img.kancloud.cn/c0/78/c078544eb7b9659df16d2d8ff7dfb8d3_720x265.jpg)
表4 v-model指令内部的对应关系
**2)表单控件**
  将v-model指令作用于表单控件时,其初始值常用的类型会有所不同,如下所示。
~~~js
var vm = new Vue({
data: {
name: "", //文本框(单行和多行)
checked: true, //一个复选框
names: [], //多个复选框
color: "", //单选框
selected: "", //选择框(单选)
selecteds: [] //选择框(多选)
}
});
~~~
  当只使用一个复选框时,v-model指令可绑定一个布尔值;而当使用多个复选框时,v-model指令适合绑定数组,如下所示。
~~~html
<input type="checkbox" v-model="checked" />
<input type="checkbox" value="strick" v-model="names"/>
<input type="checkbox" value="freedom" v-model="names"/>
~~~
  单选框与复选框不同,由于它只能选中一个值,因此不适合绑定数组,如下所示。
~~~html
<input type="radio" value="red" v-model="color"/>
<input type="radio" value="black" v-model="color"/>
~~~
  选择框的multiple特性能控制其是否多选,而这也会决定是否需要绑定数组,如下所示。
~~~html
<select v-model="selected">
<option value="1">strick</option>
<option value="2">freedom</option>
</select>
<select v-model="selecteds" multiple>
<option value="1">strick</option>
<option value="2">freedom</option>
</select>
~~~
**3)值绑定**
  单选框、复选框和选择框的值原先只能是字符串或布尔值,而通过v-bind指令就能让它们绑定任意类型的值,如下所示,为两个单选框的value特性绑定了一个对象。当选中其中一个按钮时,color属性的值就会更新成绑定的对象。
~~~html
<input type="radio" v-model="color" :value="{digit: 1}" />
<input type="radio" v-model="color" :value="{digit: 2}" />
~~~
  复选框包含两个特殊的特性:true-value和false-value(如下代码所示),当将其选中时,toggle属性会更新为yes属性的值,否则更新为no属性的值。
~~~html
<input type="checkbox" v-model="toggle" :true-value="yes" :false-value="no" />
<script>
var vm = new Vue({
data: {
toggle: 1,
yes: 1,
no: 0
}
});
</script>
~~~
**4)修饰符**
  Vue为v-model指令提供了3个修饰符,如下所列,每个修饰符后面都给出了相应的示例。
  (1).lazy修饰符能将同步输入值的事件从input替换成change,以下面的文本框为例,只有当修改其值并失去焦点时,才会更新数据对象的name属性。
~~~html
<input type="text" v-model.lazy="name" />
~~~
  (2).number修饰符能让输入值自动转换成数字,常与number类型的文本框配合使用。
~~~html
<input type="number" v-model.number="age" />
~~~
  (3).trim修饰符能过滤输入值的首尾空格。
~~~html
<input type="text" v-model.trim="school" />
~~~
*****
> 原文出处:
[博客园-Vue躬行记](https://www.cnblogs.com/strick/category/1512864.html)
[知乎专栏-Vue躬行记](https://zhuanlan.zhihu.com/pwvue)
已建立一个微信前端交流群,如要进群,请先加微信号freedom20180706或扫描下面的二维码,请求中需注明“看云加群”,在通过请求后就会把你拉进来。还搜集整理了一套[面试资料](https://github.com/pwstrick/daily),欢迎浏览。
![](https://box.kancloud.cn/2e1f8ecf9512ecdd2fcaae8250e7d48a_430x430.jpg =200x200)
推荐一款前端监控脚本:[shin-monitor](https://github.com/pwstrick/shin-monitor),不仅能监控前端的错误、通信、打印等行为,还能计算各类性能参数,包括 FMP、LCP、FP 等。
- ES6
- 1、let和const
- 2、扩展运算符和剩余参数
- 3、解构
- 4、模板字面量
- 5、对象字面量的扩展
- 6、Symbol
- 7、代码模块化
- 8、数字
- 9、字符串
- 10、正则表达式
- 11、对象
- 12、数组
- 13、类型化数组
- 14、函数
- 15、箭头函数和尾调用优化
- 16、Set
- 17、Map
- 18、迭代器
- 19、生成器
- 20、类
- 21、类的继承
- 22、Promise
- 23、Promise的静态方法和应用
- 24、代理和反射
- HTML
- 1、SVG
- 2、WebRTC基础实践
- 3、WebRTC视频通话
- 4、Web音视频基础
- CSS进阶
- 1、CSS基础拾遗
- 2、伪类和伪元素
- 3、CSS属性拾遗
- 4、浮动形状
- 5、渐变
- 6、滤镜
- 7、合成
- 8、裁剪和遮罩
- 9、网格布局
- 10、CSS方法论
- 11、管理后台响应式改造
- React
- 1、函数式编程
- 2、JSX
- 3、组件
- 4、生命周期
- 5、React和DOM
- 6、事件
- 7、表单
- 8、样式
- 9、组件通信
- 10、高阶组件
- 11、Redux基础
- 12、Redux中间件
- 13、React Router
- 14、测试框架
- 15、React Hooks
- 16、React源码分析
- 利器
- 1、npm
- 2、Babel
- 3、webpack基础
- 4、webpack进阶
- 5、Git
- 6、Fiddler
- 7、自制脚手架
- 8、VSCode插件研发
- 9、WebView中的页面调试方法
- Vue.js
- 1、数据绑定
- 2、指令
- 3、样式和表单
- 4、组件
- 5、组件通信
- 6、内容分发
- 7、渲染函数和JSX
- 8、Vue Router
- 9、Vuex
- TypeScript
- 1、数据类型
- 2、接口
- 3、类
- 4、泛型
- 5、类型兼容性
- 6、高级类型
- 7、命名空间
- 8、装饰器
- Node.js
- 1、Buffer、流和EventEmitter
- 2、文件系统和网络
- 3、命令行工具
- 4、自建前端监控系统
- 5、定时任务的调试
- 6、自制短链系统
- 7、定时任务的进化史
- 8、通用接口
- 9、微前端实践
- 10、接口日志查询
- 11、E2E测试
- 12、BFF
- 13、MySQL归档
- 14、压力测试
- 15、活动规则引擎
- 16、活动配置化
- 17、UmiJS版本升级
- 18、半吊子的可视化搭建系统
- 19、KOA源码分析(上)
- 20、KOA源码分析(下)
- 21、花10分钟入门Node.js
- 22、Node环境升级日志
- 23、Worker threads
- 24、低代码
- 25、Web自动化测试
- 26、接口拦截和页面回放实验
- 27、接口管理
- 28、Cypress自动化测试实践
- 29、基于Electron的开播助手
- Node.js精进
- 1、模块化
- 2、异步编程
- 3、流
- 4、事件触发器
- 5、HTTP
- 6、文件
- 7、日志
- 8、错误处理
- 9、性能监控(上)
- 10、性能监控(下)
- 11、Socket.IO
- 12、ElasticSearch
- 监控系统
- 1、SDK
- 2、存储和分析
- 3、性能监控
- 4、内存泄漏
- 5、小程序
- 6、较长的白屏时间
- 7、页面奔溃
- 8、shin-monitor源码分析
- 前端性能精进
- 1、优化方法论之测量
- 2、优化方法论之分析
- 3、浏览器之图像
- 4、浏览器之呈现
- 5、浏览器之JavaScript
- 6、网络
- 7、构建
- 前端体验优化
- 1、概述
- 2、基建
- 3、后端
- 4、数据
- 5、后台
- Web优化
- 1、CSS优化
- 2、JavaScript优化
- 3、图像和网络
- 4、用户体验和工具
- 5、网站优化
- 6、优化闭环实践
- 数据结构与算法
- 1、链表
- 2、栈、队列、散列表和位运算
- 3、二叉树
- 4、二分查找
- 5、回溯算法
- 6、贪心算法
- 7、分治算法
- 8、动态规划
- 程序员之路
- 大学
- 2011年
- 2012年
- 2013年
- 2014年
- 项目反思
- 前端基础学习分享
- 2015年
- 再一次项目反思
- 然并卵
- PC网站CSS分享
- 2016年
- 制造自己的榫卯
- PrimusUI
- 2017年
- 工匠精神
- 2018年
- 2019年
- 前端学习之路分享
- 2020年
- 2021年
- 2022年
- 2023年
- 日志
- 2020