03v-on的事件修饰符
`v-on` 提供了很多事件修饰符来辅助实现一些功能。事件修饰符有如下:
- `.stop` 阻止冒泡。本质是调用 event.stopPropagation()。
- `.prevent` 阻止默认事件(默认行为)。本质是调用 event.preventDefault()。
- `.capture` 添加事件监听器时,使用捕获的方式(也就是说,事件采用捕获的方式,而不是采用冒泡的方式)。
- `.self` 只有当事件在该元素本身(比如不是子元素)触发时,才会触发回调。
- `.once` 事件只触发一次。
- `.{keyCode | keyAlias}` 只当事件是从侦听器绑定的元素本身触发时,才触发回调。
- `.native` 监听组件根元素的原生事件。
PS:一个事件,允许同时使用多个事件修饰符。
<!-- click事件 --><button v-on:click="doThis"></button><!-- 缩写 --><button @click="doThis"></button><!-- 内联语句 --><button v-on:click="doThat('hello', $event)"></button><!-- 阻止冒泡 --><button @click.stop="doThis"></button><!-- 阻止默认行为 --><button @click.prevent="doThis"></button><!-- 阻止默认行为,没有表达式 --><form @submit.prevent></form><!-- 串联修饰符 --><button @click.stop.prevent="doThis"></button>
.stop
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title><script src="vue2.5.16.js"></script><style>.father {height: 300px;width: 300px;background: pink;}.child {width: 200px;height: 200px;background: green;}</style>
</head><body><div id="app"><div class="father" @click="fatherClick"><div class="child" @click="childClick"></div></div></div><script>var vm = new Vue({el: '#app',data: {},methods: {fatherClick: function () {console.log('father 被点击了');},childClick: function () {console.log('child 被点击了');}}})</script>
</body></html>
.capture
.capture:触发事件时,采用捕获的形式,而不是冒泡的形式。
<div class="father" @click.capture="fatherClick">
.prevent
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title><script src="vue2.5.16.js"></script>
</head><body><div id="app"><!-- 通过 .prevent 阻止超链接的默认跳转行为 --><a href="http://www.baidu.com" @click.prevent="linkClick">百度一下</a></div><script>var vm = new Vue({el: '#app',data: {},methods: {linkClick: function () {console.log('超链接被点击了');}}})</script>
</body></html>
//如果去掉`.prevent`,点击按钮后,既会打印log,又会跳转到百度页面。//现在加上了`.prevent`,就只会打印log,不会跳转到百度页面。
.self
`.self` 只有当事件在该元素本身(比如不是子元素)触发时,才会触发回调。
<div class="father" @click.self="fatherClick">
既然`.stop`和`.self`都可以阻止冒泡,那二者有什么区别呢?区别在于:前者能够阻止整个冒泡行为,而后者只能阻止自己身上的冒泡行为。
04 Vue的系统指令(二)
v-model:双向数据绑定
重点:双向数据绑定,只能用于表单元素,或者用于自定义组件
v-bind:只能实现数据的单向绑定,从 M 自动绑定到 V
注意:v-model 只能运用在**表单元素**中,或者用于自定义组件。常见的表单元素包括:input(radio, text, address, email....) 、select、checkbox 、textarea。
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Document</title><script src="vue.js"></script>
</head>
<body>
<div id="app"><form action="#"><!-- 将 input 标签中的value值双向绑定到 Vue实例中的data。注意,v-model 后面不需要跟冒号 --><input type="text" id="username" v-model="myAccount.username"><input type="password" id="pwd" v-model="myAccount.userpwd"><input type="submit" v-on:click="submit1" value="注册"></form>
</div>
</body><script>var vm = new Vue({el: '#app',//上面的标签中采用v-model进行双向数据绑定,数据会自动更新到data里面来data: {name: 'qianguyihao',myAccount: {username: '', userpwd: ''}},//在methods里绑定各种方法,根据业务需要进行操作methods: {submit1: function () {alert(this.myAccount.username + " pwd=" + this.myAccount.userpwd);}}});
</script></html>
v-for
在 Vue 2.2.0+ 版本里,当在**组件中**使用 v-for 时,key 属性是必须要加上的。
key的类型只能是:string/number,而且要通过 v-bind 来指定。
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title><script src="vue2.5.16.js"></script>
</head><body><div id="app"><div><label>Id:<input type="text" v-model="id"></label><label>Name:<input type="text" v-model="name"></label><input type="button" value="添加" @click="add"></div><!-- 注意: v-for 循环的时候,key 属性只能使用 number 或者 string --><!-- 注意: key 在使用的时候,必须使用 v-bind 属性绑定的形式,指定 key 的值 --><!-- 在组件中,使用v-for循环的时候,或者在一些特殊情况中,如果 v-for 有问题,必须 在使用 v-for 的同时,指定 唯一的 字符串/数字 类型 :key 值 --><p v-for="item in list" :key="item.id"><input type="checkbox">{{item.id}} --- {{item.name}}</p></div><script>// 创建 Vue 实例,得到 ViewModelvar vm = new Vue({el: '#app',data: {id: '',name: '',list: [{ id: 1, name: 'smyh' },{ id: 2, name: 'vae' },{ id: 3, name: 'qianguyihao' },{ id: 4, name: 'xiaoming' },{ id: 5, name: 'xiaohong' }]},methods: {add() { // 添加方法this.list.unshift({ id: this.id, name: this.name })}}});</script>
</body></html>
v-if:设置元素的显示和隐藏(添加/删除DOM元素)
作用:根据表达式的值的真假条件,来决定是否渲染元素,如果为false则不渲染(达到隐藏元素的目的),如果为true则渲染。在切换时,元素和它的数据绑定会被销毁并重建。
/******点击按钮时,切换和隐藏盒子)****/
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title>Document</title><script src="vue.js"></script>
</head><body><div id="app"><button v-on:click="toggle">显示/隐藏</button><div v-if="isShow">我是盒子</div></div>
</body><script>new Vue({el: '#app',data: {isShow: true},methods: {toggle: function() {this.isShow = !this.isShow;}}});
</script></html>
v-show:设置元素的显示和隐藏
作用:根据表达式的真假条件,来切换元素的 display 属性。如果为false,则在元素上添加 `display:none`属性;否则移除`display:none`属性。
(点击按钮时,切换和隐藏盒子)
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title>Document</title><script src="vue.js"></script>
</head><body><div id="app"><button v-on:click="toggle">显示/隐藏</button><div v-show="isShow">我是盒子</div></div>
</body><script>new Vue({el: '#app',data: {isShow: true},methods: {toggle: function() {this.isShow = !this.isShow;}}});
</script></html>
v-if和v-show的区别
`v-if`和`v-show`都能够实现对一个元素的隐藏和显示操作。
区别:
- v-if:每次都会重新添加/删除DOM元素
- v-show:每次不会重新进行DOM的添加/删除操作,只是在这个元素上添加/移除`style="display:none"`属性,表示节点的显示和隐藏。
优缺点:
- v-if:有较高的切换性能消耗。这个很好理解,毕竟每次都要进行dom的添加/删除操作。
- v-show:**有较高的初始渲染消耗**。也就是说,即使一开始`v-show="false"`,该节点也会被创建,只是隐藏起来了。而`v-if="false"`的节点,根本就不会被创建。