数据及事件绑定
一、数据绑定
单向绑定
单向绑定: 把 Model
绑定到 View
后,当用 JavaScript 代码更新Model
时,View
会自动更新。因此,我们不需要进行额外的 DOM 操作,只需要进行 Model 操作就可以实现视图的联动更新。
单向绑定的实现过程是:
-
所有数据只保存一份。
-
一旦数据变化,就去更新页面(只有
data->DOM
,没有DOM->data
) -
若用户在页面上做了更新,就手动收集(双向绑定式自动收集),合并到原有的数据中。
插值绑定
插值绑定: 是数据绑定的基本形式,用“{{ }}”
实现,这种语法在Vue中称为Mustache
语法。插值的形式就是{{ data }}
,它使用的是单向绑定。首先定义一个JavaScript对象作为 Model,并且把这个 Model 的两个属性绑定到 DOM 节点上。
<div id="app">{{ num }}</div>
<script>
new Vue({
el: '#app',
data: {
num: '学习Vue'
}
})
</script>
【提示】Vue实例就是ViewModel的代理对象。
在上述代码中
-
el:指定要把Model绑定到 id 为 app 的DOM节点上;
-
data:指定Model。data中的num相当于Model
<div>{{ num }}</div>
:相当于View
v-bind绑定
v-bind绑定: 如果HTML的某些属性可以支持单向绑定,我们只需要在该属性前面加上v-bind
指令,这样Vue在解析时会识别出该指令,将属性值跟Vue实例的Model 进行绑定。以后,我们就可以通过 Model 来动态的操作该属性,从而实现 DOM 的联动更新。
<div id="app">
<p v-bind:class="jumooc">Hello,{{ name }}</p>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
name: 'Vue之旅',
jumooc:'red'
}
})
</script>
<style>
.red{
background-color: red;
}
.blue{
background-color: blue;
}
</style>
双向绑定
双向绑定: Vue框架的核心功能就是双向数据绑定。简单的说,双向绑定就是把Model
绑定到 View
的同时也将 View
绑定到 Model
上,这样既可以通过更新Model
来实现View
的自动更新,也可以通过更新 View
来实现 Model
数据的更新。
在Vue中只有表单元素能够创建双向的绑定,可以用v-model
指令在<input>
、<textarea>
及<select>
元素上创建双向数据绑定。
<form action="#" id="app">
<p>
<input type="text" v-model="name">
</p>
<p>
<input type="text" v-model="age">
</p>
<p>姓名:{{ name }}</p>
<p>年龄:{{ age }}</p>
</form>
<script>
var vm = new Vue({
el: '#app',
data: {
name: '刘备',
age: 38
}
})
</script>
二、表单控件绑定
1、text(文本框)的绑定
<div id="app">
<form action="#">
<label>
姓名:
<input type="text" v-model="name">
</label>
<br><br>
<label>
年龄:
<input type="number" v-model="age">
</label>
</form>
<br><br>
<p>姓名:{{ name }}</p>
<p>年龄:{{ age }}</p>
</div>
<script>
var vm = new Vue({
el:'#app',
data:{
name:'胡图图',
age:26
}
})
</script>
2、checkbox(复选框)的绑定
多个复选框,绑定的model必须是一个数组
<div id="app">
<p>单个复选框:</p>
<label>
<input type="checkbox" v-model="check" value="自动控制">自动控制
</label>
<p>{{ check }}</p>
<hr>
<p>多个复选框:</p>
<!-- 多个复选框,绑定的model必须是一个数组 -->
<label>
<input type="checkbox" v-model="checkNames" value="study">学习
</label>
<label>
<input type="checkbox" v-model="checkNames" value="购物">taobao
</label>
<label>
<input type="checkbox" v-model="checkNames" value="上网">google
</label>
<br>
{{ checkNames }}
<hr>
<p>单选按钮:</p>
<label>
<input type="radio" v-model="Line" value="subway">地铁
</label>
<label>
<input type="radio" v-model="Line" value="plane">飞机
</label>
<p>{{ Line }}</p>
<input type="text">
<p>{{ test }}</p>
</div>
<script>
new Vue({
el:'#app',
data:{
check:true,
checkNames:[],
Line:'',
test:'水果'
}
})
</script>
3、radio(单选按钮)的绑定
<div id="app">
<p>单选框:</p>
<label>
<input type="radio" value="飞机" v-model="Line">
飞机
</label>
<label>
<input type="radio" value="高铁" v-model="Line">
高铁
</label>
<p>Picked:{{ Line }}</p>
</div>
<script>
new Vue({
el: '#app',
data: {
Line: '快起来'
}
})
</script>
4、select:因为select控件分为单选和多选,所有v-model在select控件的单选和多选上会有不同的表现。
<div id="app">
<select v-model="Line" multiple>
<option value="apple" checked>苹果</option>
<option value="pear">梨子</option>
<option value="orange">橙子</option>
</select>
<p>{{ Line }}</p>
</div>
<script>
new Vue({
el: '#app',
data: {
Line: '水果'
}
})
</script>
三、值绑定
v-model用来在View与Model之间同步数据,但是有时候需要控制同步发生的时机,或者在数据同步到Model前将数据转换为Number类型。此时,可以在v-model指令所在的form控件上添加相应的修饰指令来实现这个需求。
.lazy(懒加载)修饰符
在输入框中,v-model默认是同步数据的。使用.lazy
会转变为在change事件中同步。也就是在失去焦点或者按下回车键才更新
<div id="app">
<input type="text" v-model.lazy="Line">
<p>{{ Line }}</p>
</div>
<script>
new Vue({
el: '#app',
data: {
Line: '水果'
}
})
</script>
效果是:
以前:随着文本框内的文字删掉,下面会跟着很迅速的删掉;
现在:把“水果”删掉,在鼠标点击之后或者按下其他键后,“水果”才消失;
.number修饰符
可以将输入的值转化为Number类型,否则虽然输入的是数字,但它的类型是String,在数字输入框中比较有用。
<div id="app">
<p>.number修饰符</p>
<input type="number" v-model.number="val">
<p>数据类型是:{{ typeof(val) }}</p>
</div>
<script>
new Vue({
el: '#app',
data: {
val: ''
}
})
</script>
.trim修饰符
会自动过滤掉输入的首尾空格
<div id="app">
<p>.trim修饰符</p>
<input type="text" v-model.trim="val">
<p>val的长度是:{{ val.length }}</p>
</div>
<script>
new Vue({
el: '#app',
data: {
val: ''
}
})
</script>
这样只会记录长度,防止空格影响结果
四、事件绑定与监听
方法及内联处理器
通过v-on
绑定实例选项属性methods
中的方法作为事件的处理器,v-on:
后的参数接收所有的原生事件名称。
(1)方法处理器:可以用 v-on 指令监听 DOM 事件
<div id="app" v-on:click="greet">Geet</div>
<script>
var vm = new Vue({
el: '#app',
data: {
name: 'Vue.js'
},
// 在 `methods` 对象中定义方法
methods: {
greet: function (event) {
// 方法内 `this` 指向 vm
alert('Hello ' + this.name + '!')
// `event` 是原生 DOM 事件
alert(event.target.tagName)
}
}
})
</script>
(2)内联语句处理器:除了直接绑定到一个方法,也可以用内联 JavaScript 语句
<div id="example">
<button v-on:click="say('hi')">Say Hi</button>
<button v-on:click="say('what')">Say What</button>
</div>
<script>
new Vue({
el: '#example',
methods: {
say: function (msg) {
alert(msg)
}
}
})
</script>
(3)内联语句处理器中访问原生 DOM 事件。可以用特殊变量$event
把它传入方法:
<div id="example">
<a href="https://www.baidu.com" v-on:click="say('hello',$event)">
去百度
</a>
</div>
<script>
new Vue({
el: '#example',
methods: {
say: function (msg,event) {
event.preventDefault()
alert(msg)
}
}
})
</script>
点击“去百度”超链接,没有发生跳转,因为有event.preventDefault()
事件方法。
【提示】 判断是否为内联处理器的方法:没有括号的是函数名;有括号的实际是一条JS语句,称为内联处理器。
修饰符
(1)事件修饰符:在事件处理器中经常需要调用 event.preventDefault()
或 event.stopPropagation()
。尽管在方法内可以轻松做到。但更换的方式是:方法只有纯粹的数据逻辑,而不是去处理DOM事件细节
preventDefault():
阻止链接打开 URLstopPropagation():
阻止单击事件继续传播(阻止事件冒泡)
为了解决这个问题,Vue.js 为v-on
提供两个事件修饰符:
.prevent
:调用preventDefault()
<div id="example">
<a href="https://www.baidu.com" v-on:click.prevent>去百度</a>
</div>
.stop
:调用stopPropagation()
<a v-on:click.stop="doThis"></a>
.capture
:使用capture
模式添加事件监听器。即元素自身触发的事件先在此处理,然后才交由内部元素进行处理
<div v-on:click.capture="doThis">...</div>
.self
:只当事件在该元素本身(而不是子元素)触发时触发回调
(2)键值修饰符:在监听键盘事件时,经常需要检测 keyCode。Vue.js 允许为 v-on 添加按键修饰符,记住所有的 keyCode 比较困难,Vue.js 为最常用的按键提供别名。
<div id="example">
<button v-on:keyup.enter="say">提交</button>
</div>
<script>
new Vue({
el: '#example',
data: {
msg: '键修饰符'
},
methods: {
say: function () {
alert(this.msg)
}
}
})
</script>
全部的按键别名:
enter、tab、delete、esc、space、up、down、left、right
五、class与style的绑定
绑定class
(1)对象语法:可以传给v-bind:class一个对象,动态的切换class。
效果是一个颜色交替
<style>
div{
width: 100px;
height: 100px;
}
.class1{
background-color: #ff0;
}
.class2{
background-color: #f00;
}
</style>
<body>
<div id="example" v-bind:class="colorName" v-on:click="changeColor">
</div>
<script>
new Vue({
el: '#example',
data: {
colorName: {
class1: true,
class2: false
}
},
methods: {
changeColor(){
this.colorName.class1 = !this.colorName.class1
this.colorName.class2 = !this.colorName.class2
}
}
})
</script>
</body>
点击div后
一个交替的效果
(2)数组语法:可以把一个数组传给v-bind:class,以应用一个class列表
与上述效果一样,只是语法不一样而已。
<style>
div{
width: 100px;
height: 100px;
}
.class1{
background-color: #ff0;
}
.class2{
background-color: #f00;
}
</style>
<body>
<div id="example" v-bind:class="[class1,class2]" v-on:click="changeColor"></div>
<script>
new Vue({
el: '#example',
data: {
class1: 'class1',
class2: ''
},
methods: {
changeColor(){
this.class1 = this.class1==''?'class1':''
this.class2 = this.class2==''?'class2':''
}
}
})
</script>
</body>
绑定内联样式
(1)对象语法:v-bind:style
的对象语法十分直观,本质是一个JavaScript对象。CSS属性名可用驼峰式(nameCase)命名
<style>
div{
width: 100px;
height: 100px;
}
.class1{
background-color: #ff0;
}
.class2{
background-color: #f00;
}
</style>
<body>
<div id="example" v-bind:class="[class1,class2]" v-on:click="changeColor">
<div v-bind:style="{color:fontColor,fontSize:mySize}">西安邮电大学</div>
</div>
<script>
new Vue({
el: '#example',
data: {
class1: 'class1',
class2: '',
fontColor: 'white',
mySize: '30px'
},
methods: {
changeColor(){
this.class1 = this.class1==''?'class1':''
this.class2 = this.class2==''?'class2':''
}
}
})
</script>
</body>
(2)数组语法:可以将对个样式应用到一个元素上。
<style>
div{
width: 100px;
height: 100px;
}
.class1{
background-color: #ff0;
}
.class2{
background-color: #f00;
}
</style>
<body>
<div id="example" v-bind:class="[class1,class2]" v-on:click="changeColor">
<div v-bind:style="[baseStyles,vueStyles]">西安邮电大学</div>
</div>
<script>
new Vue({
el: '#example',
data: {
class1: 'class1',
class2: '',
baseStyles:{ 'color': 'red'},
vueStyles: { 'font-size':'35px'}
},
methods: {
changeColor(){
this.class1 = this.class1==''?'class1':''
this.class2 = this.class2==''?'class2':''
}
}
})
</script>
</body>
(3)自动添加前缀:当v-bind:style
需要厂商前缀的CSS属性(如transform)时,Vue会自动侦测并添加相应的前缀。在Vue中采用prefix函数来完成这个功能。
谷歌(-webkit-)、微软(-ms-)、火狐(-moz-)