vue-learning:27 - component - 组件三大API之二:event
组件三大API之二: event
在上一节中讲到prop单向下行数据绑定的特征,父组件向子组件传值通过prop实现,那如果有子组件需要向父组件传值或其它通信请求,可以通过vue的事件监听系统(触发事件,执行监听回调函数,并且可以在回调函数中接受传参)。
Vue内置了一套完整的事件触发器逻辑:
v-on / @: 原来HTML元素中监听原生事件,或子组件自定义事件.native: 触发组件根元素的原生事件$on:监听组件自身触发的事件$emit: 触发事件$off: 卸载组件自身的事件监听器$once: 单次监听,只会执行一次事件监听,之后不再有效$listeners: 包含在组件标签上v-on注册的所有自定义监听器的对象,key为事件名,value为事件监听函数。
v-on / @
点击查看:v-on事件及事件修饰符,以及DOM/JQUERY事件对比
所以要实现上面子组件向父组件通信,我们可以在父组件中将v-on绑定在子组件标签上开启一个事件监听,然后在子组件内部使用$emit触发该事件。
<div id="app">
<p>this is event example for v-on/@<p>
<!-- 绑定监听事件some-event -->
<com-child @com-btn-click="handleChildClick"></com-child>
</div>
const comChild = Vue.extend({
template: `<button @click="handleClick">我是子组件内定义的按钮,点击触发父级监听事件</button>`,
methods: {
handleClick() {
this.$emit('com-btn-click',666)
}
}
})
const vm = new Vue({
el: "#app",
components: {
comChild,
},
methods: {
handleChildClick(val) {
alert('我是由子组件触发的:' + val);
}
}
})
事件名称始终采用kebab-case形式
不同于组件和 prop,事件名不会作为一个 JavaScript 变量名或属性名,所以不存在任何自动化的大小写转换。即触发的事件名需要完全匹配监听这个事件所用的名称。
又因为v-on绑定在html元素上,而 HTML 是不区分大小写的。而一般事件名称都是采用多个单词,所以建议事件名一律采用kebab-case连字符形式。
事件传参
子组件在$emit触发事件的同时,可以传递一个值,在v-on绑定的事件监听器中接收到。
// $emit第一个参数是监听器事件名,第二个是要传递的参数
this.$emit('some-event',666)
// 监听事件处理函数第一个参数即为接收的值
handleChildEvent(val) {
alert('我是由子组件触发的:' + val)
}
$on / $once
$on开启的监听事件和$emit触发的监听事件都是在同一个组件实例。
<div id="app">
<p>this is event example for $on<p>
<com-child></com-child>
</div>
const comChild = Vue.extend({
template: `<button @click="handleClick">我是子组件内定义的按钮,点击触发监听事件</button>`,
data: () => {
return {
count: 0,
}
},
methods: {
handleClick() {
this.count++
this.$emit('comBtnClick',this.count)
}
},
mounted() {
this.$on('comBtnClick', (val) => {
alert('我是由$on注册的监听子组件按钮点击事件'+val)
if (val === 3) {
console.log('卸载事件监听')
this.$off('comBtnClick')
}
})
this.$once('comBtnClick', (val) => {
alert('我是由$once注册监听子组件按钮点击事件,只会触发一次'+val)
})
}
})
const vm = new Vue({
el: "#app",
components: {
comChild,
},
})
对于组件内部触发有条件下其它事件时,比如就监听执行一次用$once,或监听执行然后某条件满足下不再监听用$on配合$off。
但是如果是持续监听,只要事件触发就执行某动作,完全可以将监听回调函数写成methods中方法,事件处理时直接执行该方法。
const comChild = Vue.extend({
template: `<button @click="handleClick">我是子组件内定义的按钮,点击触发监听事件</button>`,
methods: {
handleClick() {
// this.$emit('comBtnClick',888)
this.comBtnClick(val)
},
comBtnClick(val) {
alert('我是按钮点击触发执行'+val)
}
},
})
上面使用$on / $emit如果只在组件内部执行,并不能实现子组件向父组件传值通信的目的。此时我们需要再配合$refs属性实现。
ref特性用在单个HTML元素上可以获取原生DOM节点对象,用在组件标签上,可以获取该组件实例对象。
上面的例子修改下,使用$on / $emit / $refs实例子组件向父组件组件的目的
<div id="app">
<p>this is event example for $on / $emit / $refs<p>
<com-child ref="comChild"></com-child>
</div>
const comChild = Vue.extend({
template: `<div>
<button @click="handleBtnClick">我是子组件内定义的按钮,点击触发监听事件</button>
</div>`,
methods: {
handleBtnClick() {
this.$emit('comBtnClick',999)
},
},
})
const vm = new Vue({
el: "#app",
components: {
comChild,
},
mounted() {
this.$refs.comChild.$on('outerSelfEvent', val => {
console.log('组件按钮点击了')
})
this.$refs.comChild.$once('outerSelfEvent', val => {
console.log('组件按钮点击了,我只监听执行一次')
})
}
})
$off
移除自定义事件监听器。
- 如果没有提供参数,则移除所有的事件监听器;
- 如果只提供了事件,则移除该事件所有的监听器;
- 如果同时提供了事件与回调,则只移除这个回调的监听器(此时注册事件时回调函数不能采用匿名函数写法)。
<div id="app">
<p>this is event example for $off<p>
<com-child ref="comChild"></com-child>
</div>
const comChild = Vue.extend({
template: `<div>
<button @click="handleBtnClick1">点击触发触发组件内部监听事件elert</button>
<button @click="handleBtnClick2">点击触发触发组件内部监听事件console</button>
<button @click="handleUninstallAllListener">点击卸载组件内所有事件监听$off()</button>
<button @click="handleUninstallTheEvent">点击卸载组件内指定事件监听器$off(event)</button>
<button @click="handleUninstallTheEventCallback">点击卸载组件内指定监听器$off(event,cb)</button>
</div>`,
methods: {
handleBtnClick1() {
this.$emit('handleAlert')
},
handleBtnClick2() {
this.$emit('handleConsole')
},
handleUninstallAllListener() {
console.log('卸载所有监听器')
this.$off()
},
handleUninstallTheEvent() {
console.log('卸载指定事件handleAlert的所有监听器')
this.$off('handleAlert')
},
handleUninstallTheEventCallback() {
console.log('卸载指定事件handleConsole中的handleConsole2监听器')
this.$off('handleConsole', this.handleConsole2)
},
handleConsole2() {
console.log('监听器Console2')
}
},
mounted() {
this.$on('handleAlert',function () {
alert('监听器alert1')
})
this.$on('handleAlert',function () {
alert('监听器alert2')
})
this.$on('handleConsole',function () {
console.log('监听器Console1')
})
this.$on('handleConsole',this.handleConsole2 )
}
})
const vm = new Vue({
el: "#app",
components: {
comChild,
},
})
$listeners
包含了父作用域中的在组件标签上所有通过v-on注册的事件监听器。
但不包括:
- 含有.native 修饰器的原生事件监听器
- 组件使用$on注册的监听器
下面的例子,我们在子组件标签上绑定了一个原生事件,二个v-on方式的自定义事件,一个$on方式的自定义事件。
但终$listeners打印出来的只有其中二个v-on方式绑定的事件。
<div id="app">
<p>this is event example for $listeners<p>
<com-child
ref="comChild"
@click.native="handleNativeClick"
@child-btn-click-console="handelChildBtnClickConsole" @child-btn-click-alert="handelChildBtnClickAlert"
></com-child>
</div>
const comChild = Vue.extend({
template: `<div>
<button @click="handleBtnClick" >点击触发触发组件内部监听事件elert</button>
</div>`,
methods: {
handleBtnClick() {
this.$emit('child-btn-click-alert')
this.$emit('child-btn-click-console')
this.$emit('handleConsole')
},
},
mounted() {
this.$on('handleConsole',function () {
console.log('$on绑定监听器')
})
// 打印出$listeners
console.log('$listeners:', this.$listeners)
}
})
const vm = new Vue({
el: "#app",
components: {
comChild,
},
methods: {
handelChildBtnClickAlert() {
alert('v-on绑定$emit触发alert')
},
handelChildBtnClickConsole() {
console.log("v-on绑定$emit触发console")
},
handleNativeClick() {
alert('native click')
}
}
})
$listeners:
child-btn-click-alert: ƒ invoker()
child-btn-click-console: ƒ invoker()
vue-learning:27 - component - 组件三大API之二:event的更多相关文章
- vue-learning:26 - component - 组件三大API之一:prop
组件三大API之一: prop prop的大小写 prop接收类型 字符串数组形式 对象形式: type / required / default / validator prop传递类型: 静态传递 ...
- vue-learning:29 - component - 组件三大API之三:slot
组件三大API之三: slot <slot>标签 v-slot指令 普通插槽 有默认值的插槽 具名插槽 作用域插槽 v-slot是Vue 2.6.0引入的一个新语法指令,目的是统一之前sl ...
- 第六章 组件 59 组件切换-使用Vue提供的component元素实现组件切换
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8&quo ...
- Vue.js——60分钟组件快速入门(下篇)
概述 上一篇我们重点介绍了组件的创建.注册和使用,熟练这几个步骤将有助于深入组件的开发.另外,在子组件中定义props,可以让父组件的数据传递下来,这就好比子组件告诉父组件:"嘿,老哥,我开 ...
- Vue.js——60分钟组件快速入门
一.组件简介 组件系统是Vue.js其中一个重要的概念,它提供了一种抽象,让我们可以使用独立可复用的小组件来构建大型应用,任意类型的应用界面都可以抽象为一个组件树: 那么什么是组件呢?组件可以扩展HT ...
- Vue.js——60分钟组件快速入门(下篇)
转自:https://www.cnblogs.com/keepfool/p/5637834.html 概述 上一篇我们重点介绍了组件的创建.注册和使用,熟练这几个步骤将有助于深入组件的开发.另外,在子 ...
- Vue:Vue的介绍以及组件剖析
介绍 现在,随着基于JavaScript的单页应用程序(SPA)和服务器端渲染(SSR)的兴起,可以用JavaScript编写整个前端应用程序,并整洁地管理和维护该应用程序的前端代码.诸如Angula ...
- Vue 引出声明周期 && 组件的基本使用
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8" /> 5 & ...
- Vue.js学习 Item11 – 组件与组件间的通信
什么是组件? 组件(Component)是 Vue.js 最强大的功能之一.组件可以扩展 HTML 元素,封装可重用的代码.在较高层面上,组件是自定义元素,Vue.js 的编译器为它添加特殊功能.在有 ...
随机推荐
- thinkphp5.0 验证提示信息的类型
以上是5.0.12版本 下面是5.0.5版本,没有elseif 上图中红方格的值只能是string类型,但是这种情况是在5.0.5版本是可以设置为array类型的
- 闲鱼Flutter&FaaS云端一体化架构
讲师介绍 国有,闲鱼架构团队负责人.在7月13号落幕的2019年Archsummit峰会上就近一年来闲鱼在Flutter&FaaS一体化项目上的探索和实践进行了分享. 传统Native+Web ...
- 笔记:字体大小的几种不同的格式px,em,rem
px px像素(Pixel),相对长度单位,像素px是相对于显示器屏幕分辨率而言的.(引自CSS2.0手册) 譬如,Windows的用户所使用的分辨率一般是96像素/英寸. 而MAC的用户所使用的分辨 ...
- python HTTP请求过程
- C#面向对象基础 —— 类与对象
文章来源: https://www.cnblogs.com/huluobozu/p/5070500.html 一.类与对象 类是面向对象编程的基本单元:类造出来的变量叫对象. 一个类包含俩种成员:字段 ...
- Android实现圆角边框
http://www.cnblogs.com/flyme/archive/2012/06/20/2556259.html android shape的使用 http://www.cnblogs.com ...
- 当better-scroll遇见了react擦出的火花
关于better-scroll这个插件前面已经介绍过两次了 从原生js使用到结合服务端发送数据使用都有过介绍 今天给大家分享一下这款插件在react中遇见的坑 总之我真是对这款插件又爱又恨 每次各种 ...
- 从零学React Native之01创建第一个程序
本篇首发于简书 欢迎关注 上一篇文章是时候了解React Native了介绍了React Native.大家应该对React Native有个初步的认识. 接下来我们就可以初始化一个React Nat ...
- js280行代码写2048
2048 原作者就是用Js写的,一直想尝试.但久久未动手. 昨天教学生学习JS代码.最好还是就做个有趣的游戏好了.2048这么火,是一个不错的选择. 思路: 1. 数组 ,2维数组4x4 2. 移动算 ...
- Java帮助文档打开索引就停止服务
cmd: regsvr32 jscript.dllregsvr32 hhctrl.ocxregsvr32 itss.dllregsvr32 itircl.dll