1、表单输入绑定(双向数据绑定)
1.1、基础用法
当用户修改model数据时,页面dom发生变化;
当用户修改页面dom时,model数据发生变化;
v-model是v-on和v-bind两个指令的语法糖(集合指令)
可以用 v-model
指令在表单 <input>、<textarea> 及 <select>元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。尽管有些神奇,但v-model 本质上不过是语法糖。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。
v-model
会忽略所有表单元素的 value、checked、selected 特性的初始值而总是将 Vue 实例的数据作为数据来源。所以应该通过JavaScript 在组件的 data 选项中声明初始值。
v-model
在内部为不同的输入元素使用不同的属性并抛出不同的事件:
- text 和 textarea 元素使用 value 属性和 input 事件;
- checkbox 和 radio 使用 checked 属性和 change 事件;
- select 字段将 value 作为 prop 并将 change 作为事件。
1.1.1、单行文本和多行文本
单行文本和多行文本不用指定name
和value
,直接使用v-model
绑定属性名称即可。
<div id="root">
<div>
<p>输入框的默认值:{{inputValue}}</p>
<input type="text" v-model="inputValue">
<p>多行文本框默认值:{{textareaText}}</p>
<textarea v-model="textareaText"></textarea>
</div>
</div>
<script type="text/javascript">
const vm = new Vue({
el: '#root',
data:{
inputValue: "",
textareaText:""
}
});
</script>
运行结果:

1.1.2、单选框和复选框
(1)、单选框
单选框需要指定name
和value
。
<div id="root">
<div>
<p>单选框的值:{{radioValue}}</p>
<input type="radio" name="gender" value="男" v-model="radioValue" />男
<input type="radio" name="gender" value="女" v-model="radioValue" />女
</div>
</div>
<script type="text/javascript">
const vm = new Vue({
el: '#root',
data:{
radioValue: '',
}
});
</script>
运行结果:

(2)、单个复选框
如果是单个复选框,需要绑定的值是bool类型,单个复选框不需要指定name
和value
。
<div id="root">
<div>
<p>单复选框的值:{{checked}}</p>
<!--
如果是单个复选框,需要绑定的值是bool类型,单个复选框不需要指定name和value
-->
<input type="checkbox" v-model="checked">是否同意协议
</div>
</div>
<script type="text/javascript">
const vm = new Vue({
el: '#root',
data:{
checked: true,//单个复选框,true代表默认勾选,false默认不勾选
},
});
</script>
运行结果:

(3)、多个复选框
如果是多个复选框需要绑定的是数组,多个复选框的时候,需要指明name
和value
。
<div id="root">
<div>
<h4>多复选框的值:{{hobbies}}</h4>
<!--
如果是多个复选框需要绑定的是数组
多个复选框的时候,需要指明name和value
-->
<input type="checkbox" name="hobby" value="篮球" v-model="hobbies">篮球
<input type="checkbox" name="hobby" value="足球" v-model="hobbies">足球
<input type="checkbox" name="hobby" value="乒乓球" v-model="hobbies">乒乓球
<input type="checkbox" name="hobby" value="羽毛球" v-model="hobbies">羽毛球
</div>
</div>
<script type="text/javascript">
const vm = new Vue({
el: '#root',
data:{
hobbies: []
}
});
</script>
运行结果:

1.1.3、选择框
对于选择框,无需定义name
,value
可有可无。如果没有value
,选择的值以option
选择的文本作为值,如果有value
则以value
的值作为值。
(1)、选择框单选时
如果v-model表达式的初始值未能匹配任何选项,<select>
元素将被渲染为“未选中“状态。在iOS
中,这会使用户无法选择第一个选项。因为这样的情况下,iOS
不会触发change
事件。因此,更推荐像下面这样提供一个值为空的禁用选项。
<div id="root">
<div>
<p>选择框单选的值:{{selectValue}}</p>
<select v-model="selectValue">
<option value="" disabled>请选择</option>
<option>A</option>
<option>B</option>
<option>C</option>
<option>D</option>
<option>E</option>
</select>
</div>
</div>
<script type="text/javascript">
const vm = new Vue({
el: '#root',
data:{
selectValue: ''
}
});
</script>
运行结果:

(2)、选择框多选时
多选时,绑定的是数组。
<div id="root">
<div>
<h4>选择框多选时的值:{{selectMultiple}}</h4>
<!--
多选时,绑定的是数组
-->
<select v-model="selectMultiple" multiple>
<option value="" disabled>请选择</option>
<option>刘德华</option>
<option>张学友</option>
<option>梁朝伟</option>
<option>黎明</option>
<option>郑少秋</option>
</select>
</div>
</div>
<script type="text/javascript">
const vm = new Vue({
el: '#root',
data:{
selectMultiple:[]
}
});
</script>
运行结果:

1.1.4、v-for渲染动态选项
<div id="root">
<div>
<h4>v-for渲染动态选项:{{options}}</h4>
<select v-model="options">
<option v-for="option in options" :value="option.value">
{{option.option}}
</option>
</select>
</div>
</div>
<script type="text/javascript">
const vm = new Vue({
el: '#root',
data:{
options:[
{'option':'刘德华','value':'liudehua'},
{'option':'张学友','value':'zhangxueyou'},
{'option':'黎明','value':'liming'},
{'option':'周润发','value':'zhourunfa'}
]
}
});
</script>
运行结果:

1.2、修饰符
1.2.1、.lazy修饰符
在默认情况下,v-model
在每次 input
事件触发后将输入框的值与数据进行同步(除了上述输入法组合文字时)。你可以添加 lazy
修饰符,从而转为在change
事件之后进行同步:
<div id="root">
<div>
<p>输入框的默认值:{{inputValue}}</p>
<!--
使用了.lazy修饰符,不再是一边输入一边更新了,而是在输入完成焦点离开input框以后才更新
-->
<input type="text" v-model.lazy="inputValue">
</div>
</div>
<script type="text/javascript">
const vm = new Vue({
el: '#root',
data:{
inputValue: '',
}
});
</script>

1.2.2、.number修饰符
如果需要自动将用户的输入值转为数值类型,可以给v-model
添加number
修饰符:
<div id="root">
<div>
<p>.number修饰符使用</p>
<!--
如果需要自动将用户的输入值转为数值类型,可以给v-model添加number修饰符:
-->
<input type="text" v-model.number="age">
</div>
</div>
<script type="text/javascript">
const vm = new Vue({
el: '#root',
data:{
age: ''
}
});
</script>
运行结果:

这通常很有用,因为即使在 type="number"
时,HTML 输入元素的值也总会返回字符串。如果这个值无法parseFloat()
解析,则会返回原始的值。
1.2.3、.trim修饰符
如果要自动过滤用户输入的首尾空白字符,可以给 v-model
添加 trim
修饰符:
<div id="root">
<div>
<p>.trim修饰符使用</p>
<!--
如果要自动过滤用户输入的首尾空白字符,可以给 v-model 添加 trim 修饰符
-->
<input type="text" v-model.trim="trimValue">
</div>
</div>
<script type="text/javascript">
const vm = new Vue({
el: '#root',
data:{
trimValue: ''
}
});
</script>
运行结果:

2、class和style绑定
操作元素的class
列表和内联样式是数据绑定的一个常见需求。因为它们都是attribute
,所以我们可以用v-bind
处理它们:只需要通过表达式计算出字符串结果即可。不过,字符串拼接麻烦且易错。因此,在将v-bind
用于class
和 style
时,Vue.js
做了专门的增强。表达式结果的类型除了字符串之外,还可以是对象或数组。
2.1、绑定html的class
2.1.1、对象语法
我们可以传给 v-bind:class
(简写::class=""
)一个对象,以动态地切换 class
:
<style type="text/css">
.my-class{
width: 200px;
height: 200px;
background-color: red !important;
}
.active{
width: 200px;
height: 200px;
background-color: #00ff;
}
</style>
<div id="root">
<div>
<h4>对象语法动态绑定class类</h4>
<!--
对象语法:键值对(key:value)
样式类名为对象名称(key),值(value)为boolean类型:true表示样式类生效,
false表示样式类无效样式类名中有特殊符号需要使用引号包裏
-->
<div :class="{active : isActive, 'my-class': isMyclass}">
<p>div的内容</p>
</div>
</div>
</div>
<script type="text/javascript">
const vm = new Vue({
el: '#root',
data:{
isActive: false,
isMyclass: true
}
});
</script>
上面的语法表示 active
这个 class
存在与否将取决于数据属性 isActive
的真假。"my-class"
也是一样取决于isMyclass
属性。

可以在对象中传入更多字段来动态切换多个 class
。此外, v-bind:class
指令也可以与普通的 class attribute
共存。当有如下模板:
<div class="box" :class="{active : isActive, 'my-class': isMyclass}">
<p>div的内容</p>
</div>

当 isActive
或者 isMyclass
变化时,class
列表将相应地更新。例如,如果 isMyclass
的值为true
, class
列表将变为 "box my-class"
。
绑定的数据对象不必内联定义在模板里:
<div id="root">
<div>
<h4>对象语法动态绑定class类</h4>
<div class="box" :class="classObj">
<p>div的内容</p>
</div>
</div>
</div>
<script type="text/javascript">
const vm = new Vue({
el: '#root',
data:{
classObj:{
active: false,
'my-class': true
}
}
});
</script>
运行结果:

2.1.2、数组语法
可以把一个数组传给 :class
,以应用一个 class
列表:
<div id="root">
<div>
<h4>数组写法</h4>
<!--
数组写法:样式类名以字符串的方法定义在数组
-->
<div :class="[box,myClass,active]">数组写法内容</div>
</div>
</div>
<script type="text/javascript">
const vm = new Vue({
el: '#root',
data:{
box: 'box',
myClass:'my-class',
active: 'active'
}
});
</script>

无论使用数组写法还是对象写法都不影响使用class属性静态绑定的样式。
2.1.3、使用内联样式
(1)、对象写法
:style
的对象语法十分直观,看起来非常像CSS
,但其实是一个JavaScript
对象。CSS property
名可以用驼峰式(camelCase
) 或短横线分隔(kebab-case
,需要用引号括起来)来命名:
<div id="root">
<div>
<h2>使用内联样式</h2>
<!--
对象属性名称为样式属性名,值为样式值,可以为字符串类型、数值等类型
样式属性名中带有特殊符号,那么需要使用引号包裹或者使用驼峰写法
-->
<h4>对象语法:</h4>
<div :style="{backgroundColor: bgColor, width: Whidth, height: Height, fontSize: fontSize}">
对象语法写法测试
</div>
</div>
</div>
<script type="text/javascript">
const vm = new Vue({
el: '#root',
data:{
bgColor: 'red',
Whidth: '200px',
Height: '150px',
fontSize: 18+'px'
}
});
</script>
运行结果:

(2)、数组写法
:style
的数组语法可以将多个样式对象应用到同一个元素上:
<div id="root">
<div>
<h4>数组的写法:</h4>
<div :style="[baseStyle, fontStyle]">数组写法测试</div>
</div>
</div>
<script type="text/javascript">
const vm = new Vue({
el: '#root',
data:{
baseStyle:{
width: '200px',
height: '150px',
backgroundColor: 'red'
},
fontStyle:{
fontSize: 18+'px',
color: 'white'
}
}
});
</script>
运行结果:

当:style
使用需要添加浏览器引擎缀的CSS property
时,如transform
,Vue.js
会自动侦测并添加相应的前缀。