Vue框架学习03
一、Vue事件
1、事件监听
1.1、在触发事件是执行JavaScript代码
v-on
允许在触发事件时执行JavaScript代码,示例代码如下:
<div id="app">
<button v-on:click="count+=Math.random()">随机数</button>
<p>自动生成的随机数是{{count}}</p>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
count: 0
}
})
</script>
1.2、使用按键修饰符监听按键
Vue 允许为v-on
添加按键修饰符来监听按键
,如Enter、空格、Shift等。示例代码如下(以Enter键为例):
<div id="app">
<input type="text" v-on:keyup.enter="submit" />
</div>
<script>
var vm = new Vue({
el: '#app',
methods: {
submit() {
console.log('表单提交')
}
}
})
</script>
在上述代码中,当按下键盘的回车键后,就会触发submit()
事件处理方法。
2、事件修饰符
事件修饰符是自定义事件行为
,配合v-on
指令来使用,写在事件之后,用“.
”符号连接,如“v-on:click.stop
”表示阻止事件冒泡。常用的事件修饰符如下表:
修饰符 | 说明 |
---|---|
.stop | 阻止事件冒泡 |
.prevent | 阻止默认事件行为 |
.capture | 事件捕获 |
.self | 将事件绑定到自身,只有自身才能触发 |
.once | 事件只触发一次 |
2.1、.stop阻止事件冒泡
默认的事件传递方式是冒泡,所以同一事件类型会在元素内部和外部触发,有可能会造成事件的错误触发,所以就需要使用.stop
修饰符来阻止事件冒泡行为。
示例代码如下:
<div id="app">
<div v-on:click="doParent">
<button v-on:click="doThis">事件冒泡</button>
<button v-on:click.stop="doThis">阻止事件冒泡</button>
</div>
</div>
<script>
var vm = new Vue({
el: '#app',
methods: {
doParent() {
console.log('我是父元素单击事件')
},
doThis() {
console.log('我是被单击元素事件')
}
}
})
</script>
2.2、.prevent阻止默认事件行为
在实际开发中,若HTML标签的默认行为与事件发生冲突,此时可以使用.prevent
修饰符来阻止标签的默认行为。
示例代码如下:
<div id="app">
<a href="https://www.baidu.com" v-on:click.prevent>阻止默认行为</a>
<a href="https://www.baidu.com">不阻止默认行为</a>
</div>
<script>
var vm = new Vue({
el: '#app'
})
</script>
// 运行结果:
// 单击“阻止默认行为”链接,页面不会发生变化;
// 而单击“不阻止默认行为”链接,页面会跳转到https://www.baidu.com页面
2.3、.capture事件捕获
事件捕获的执行顺序
是由外部结构向内部结构执行,与事件冒泡的顺序相反。
示例代码如下:
<div id="app">
<div v-on:click.capture="doParent">
<button v-on:click="doThis">事件捕获</button>
</div>
</div>
<script>
var vm = new Vue({
el: '#app',
methods: {
doParent() {
console.log('我是父元素的单击事件')
},
doThis() {
console.log('我是当前元素的单击事件')
}
}
})
</script>
// 运行结果:
// 控制台先输出"我是父元素的单击事件",再输出'我是当前元素的单击事件'
2.4、.self自身触发
事件修饰符.self
用来实现只有DOM元素本身会触发事件。
示例代码如下:
1 <style>
2 .Odiv1 {width: 80px; height: 80px; background: #aaa;margin: 5px}
3 .Odiv2 {width: 50px; height: 50px; background: #ccc;}
4 </style>
5 <div id="app">
6 <div class="Odivl" v-on:click.self="doParent">a
7 <div class="Odiv2" v-on:click="doThis">b</div>
8 </div>
9 <div class="Odivl" v-on:click="doParent">c
10 <div class="Odiv2" v-on:click.self="doThis">d</div>
11 </div>
12 </div>
13 <script>
14 var vm = new Vue({
15 el: '#app',
16 methods: {
17 doParent() {
18 console.log('我是父元素的单击事件')
19 },
20 doThis() {
21 console.log('我是当前元素的单击事件')
22 }
23 }
24 })
25 </script>
2.5、.once只触发一次
事件修饰符.once
用于阻止事件多次触发,只触发一次。
示例代码如下:
<div id="app">
<button v-on:click.once="doThis">只执行一次</button>
</div>
<script>
var vm = new Vue({
el: '#app',
methods: {
doThis() {
console.log('我是当前元素的单击事件,且只执行一次')
}
}
})
</script>
// 运行结果:
// 控制台先输出"我是当前元素的单击事件,且只执行一次"
// 多次单击“只执行一次”按钮,控制台的输出不变
注意:使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。因此,用v-on:click.prevent.self
会阻止所有的点击,而v-on:click.self.prevent
只会阻止对元素自身的点击。
二、Vue组件
1、什么是组件
Vue 可以进行组件化开发,组件
是构成页面的独立结构单元。组件能实现复杂的页面结构,能够减少重复代码的编写,提高开发效率,提高代码的可复用性,降低代码之间的耦合程度。
示例代码如下:
<div id="app">
<my-component></my-component>
<my-component></my-component>
<my-component></my-component>
</div>
<script>
Vue.component('my-component', {
data() {
return {
count: 0
}
},
template: '<button v-on:click="count++">被单击{{count}}次</button>'
})
var vm = new Vue({
el: '#app'
})
</script>
上述代码中,Vue.component()
表示注册组件的API,参数为my-component
为组件名称,该名称与页面中的 <my-component>
标签名对应。组件名还可以使用驼峰命名法,若将my-component修改为myComponent
,运行结果相同;data()
表示组件中的数据,它必须是一个函数,通过返回值来返回数据;template
表示组件的模板。
2、局部注册组件
Vue.component()
方法用于全局注册组件,除了全局注册组件外,还可以局部注册组件,即通过 Vue 实例的components
属性来实现。
示例代码如下:
<div id="app">
<my-component></my-component>
</div>
<script>
var comp1 = {
template: '<p>我是 vm 实例中的局部组件</p>'
}
var vm = new Vue({
el: '#app'
// 注册局部组件
components: {
myComponent: comp1
}
})
</script>
3、template 模板
template
模板代码可以写在HTML结构中,这样有利于在编辑器中显示代码提示和高亮显示。Vue 提供了<template>
标签来定义组件的模板,可以在该标签中书写HTML代码,然后通过id
值与组件内的template
属性绑定上。
示例代码如下:
<div id="app">
<p>{{title}}</p>
<my-component></my-component>
</div>
<template id="temp1">
<p>{{title}}</p>
</template>
<script>
Vue.component('my-component', {
template: '#temp1',
data() {
return {
title: '我是组件内的title'
}
}
})
var vm = new Vue({
el: '#app',
data: {
title: '我是vm实例中的title'
}
})
</script>
4、组件之间的数据传递
在 Vue 中,组件实例具有局部作用域,组件之间的数据传递需要借助一些工具。父组件与子组件的依赖关系是完成数据传递的基础,组件之间的数据信息传递过程如下:
父组件向子组件传递
是数据从外部向内部传递,子组件向父组件传递是数据从内部向外部传递。
在Vue中,数据传递主要通过props属性
和$emit
方式来实现。
4.1、props 传值
props
属性,用来接受父组件中定义的数据,其值为数组,数组中是父组件传递的数据信息。
示例代码如下:
<div id="app">
<my-parent name="title"></my-parent>
</div>
<script>
Vue.component('my-parent', {
props: ['name'],
template: '<div>我是父组件{{name}}</div>'
})
var vm = new Vue({
el: '#app'
})
</script>
// 运行结果:
// “我是父组件title”
注意:props
是以从上到下的单向数据流传递,且父级组件的props
更新会向下流动到子组件中。
4.2、$emit 传值
$emit
能够将子组件中的值传递到父组件中去。$emit
可以触发父组件中定义的事件,子组件的数据信息通过传递参数的方式完成。
示例代码如下:
<div id="app">
<parent></parent>
</div>
<template id="child">
<div>
<button @click="click">Send</button>
<input type="text" v-model="message">
</div>
</template>
<script>
// parent组件
Vue.component('parent', {
template: '<div><child @childFn="transContent"></child>' + '子组件传来的值 : {{message}}</div>',
data () {
return {
message: ''
}
},
methods: {
transContent (payload) {
this.message = payload
}
}
})
// child组件
Vue.component('child', {
template: '#child',
data () {
return {
message: '子组件的消息'
}
},
methods: {
click () {
this.$emit('childFn', this.message);
}
}
})
var vm = new Vue({ el: '#app' })
</script>
5、组件切换
以登录组件和注册组件的切换为例,示例代码如下:
<div id="app">
<a href="#" @click.prevent="flag ? flag : flag = !flag">登录</a>
<a href="#" @click.prevent="flag ? flag = !flag : flag">注册</a>
<!-- 登录组件 -->
<login v-if="flag"></login>
<!-- 注册组件 -->
<register v-else="flag"></register>
</div>
<script>
// 登录组件
Vue.component('login', {
template: '<div>登录页面</div>'
})
// 注册组件
Vue.component('register', {
template: '<div>注册页面</div>'
})
var vm = new Vue({
el: '#app',
data: { flag: true }
})
</script>
在上述代码中,login
表示登录组件,register
表示注册组件。.prevent
事件修饰符用于阻止<a>
标签的超链接默认行为。上例中,组件的切换是靠v-if
来控制的,还可以通过组件的is
属性来实现,使用is属性匹配组件的名称。
示例代码如下:
<div id="app">
<a href="#" @click.prevent="comName='login'">登录</a>
<a href="#" @click.prevent="comName='register'">注册</a>
4 <component v-bind:is="comName"></component>
</div>
<script>
Vue.component('login', {
template: '<div>登录页面</div>'
})
Vue.component('register', {
template: '<div>注册页面</div>'
})
var vm = new Vue({
el: '#app',
data: { comName: '' }
})
</script>
// 第4行的is属性值绑定了data中的comName
// <a>标签用于改变comName的值,从而切换对应的组件
参考资料:
1、《Vue.js 前端开发实战》,黑马程序员.
2、Vue 2.x 官方 Guide 文档. (https://cn.vuejs.org/v2/guide/)