Vue2_11

Vue2组件自定义事件与全局事件总线

Vue2_11

1、组件的自定义事件

  • 事件: @cilck @keyup…

  • 自定义事件:自定义的事件呗

    但是这个自定义的事件,只能给组件标签使用,上面的事件只能给 html 标签使用

1.定义

v-on:事件名=“事件(methods)”

<XiaoMing v-on:a="haha"/>
<!-- v-on 就是@cilck 的 '@' -->

既然是 v-on 那么就可以简写成:<XiaoMing @a="haha"/>

2.$emit

自定义事件只能使用 $emit 触发,不需要接收

<template>
  <div>
    <button @click="haha">haha</button>
  </div>
</template>

<script>
export default {
    methods:{
        haha(){
            // $emit 是调用自定义事件的函数
            this.$emit('a','haha')
            // ('传进来的事件名', 参数1, 参数2, ...)
        }
    }
}
</script>

3.和props的区别

3.1 传递
  • props:<HaHa :a="a"/>
  • $emit:<HaHa @a="a"/>

冒号 和 @符 的区别

3.2 导入
  • props:props:['a']
    • 在 vc 身上
    • 导入多个:props:['a','b',...]
  • **$emit:**不需要导入
    • 在 vc.$emit 身上
3.3 使用
  • props:this.a(参数)

  • ** e m i t : ∗ ∗ ‘ t h i s . emit:**`this. emitthis.emit(‘a’, 参数)`

4.使用ref

使用 $on 绑定自定义事件

<XiaoMing ref="ming"/>
<script>
	...
	mounted(){
        // this.$refs.引号里的名字,就可以拿到 这个组件的 vc
        /*
        	1.拿到传递的实例对象 this.$refs.ming
        	2.给他绑定事件 .$事件('接收名', 传递的函数)
        	3.他是XiaoMing的vc
        */
		this.$refs.ming .$on('a', this.haha)	// haha 是 method 中的一个函数
        // $on 函数,就是 v-on
	}
</script>

这样还可以用其他的函数,比如:

this.$refs.ming.$once('a', this.haha)
// 之前学的 once 只能点一次

这种方法更加灵活

5.解绑自定义事件 $off

// 解绑一个自定义事件
this.$off('a')

// 解绑多个 (传数组)
this.$off(['a','b'])

// 解绑全部 (不传参)
this.$off()

6.小扩展

6.1 销毁后的事件
  • 销毁 vm 会销毁子组件的自定义事件,但是销不毁组件本身的事件

    add(){	// 点按钮 n++,组件本身的事件
        console.log('++');
        this.n++
    },
    haha(){	// 点按钮输出 haha,自定义事件
        this.$emit('a','haha')
    },
    

    最后销毁了 vm this.destroyed(),haha输出不了,n 还能++

  • 但是销毁 App 会没页面

6.2 this是调用事件的vc

事件不用mounted写了,当场定义一个函数

mounted(){
    this.$refs.ming.$on('a', function(){
        cosole.log(this)
        // 得到的是使用它的 vc
    })
},

这样一来,如果要改传递组件的数据就不行

解决:

  • 用 mounted
  • 使用箭头函数:因为箭头函数没有 this,vue给这里指定的this没有效果,this自己就会往外找
6.3 原生事件native
  • 普通使用:@cilek="a"
    • 会将原生事件解析成自定义事件,需要用$emit
  • 事件.native:@cilek.native="a"
    • 这样就可以使用了

2、全局事件总线

任意组件之间的通信,这个不是什么API,是捣鼓出来的一个玩意

需要满足两个条件:

  1. 所有组件都能拿的到
  2. 有$emit

答:在vm的原型对象(也是vc的原型对象的原型对象)上,创建一个 vc 实例对象

1.创建全局事件总线

vc:

const a = Vue.extend({})
// a 只是一个构造函数,只能 new出来示例对象
const b = new a()
// 在 vm 的构造函数 Vue的实例对象上,创建一个vc
Vue.prototype.x = b;

vm:

new Vue({
	...
	beforeCreate(){
		Vue.prototype.x = this;
	},
	...
}).$mount('#app')
// 不能 Vue.prototype.x = vm; 因为这时候App都放上去了

2.使用

怎么使用呢?

  • 绑事件

    前面的 使用$ref 写的是

    // this.$ref 就是实例对象嘛
    vc.事件(...)
    

    x 不就是实例对象嘛

    // 用 this 到自己的实例对象中找
    this.x.$on('WAW', this.QAQ)
    
  • 调用事件

    前面:

    this.$emit(...)
    

    this 不还是 x 嘛

    this.x.$emit('WAW', this.name)
    

3.使用时机

自定义事件大多用于子传父,因为是调用函数来改变父的数值,所以:

  • 绑事件 —— 需要被改变的组件
  • 调用事件 —— 传递数据的组件

4.$bus

这个变量的名称不叫 x 叫 $bus,因为bus有一个意思叫 “总线”

5.销毁时解绑

因为这个bus名字建了别人就用不了了嘛

所以最好在这个组件销毁之前,解绑它

beforeDestroy(){
    this.$bus.$off('WAW')
}

之前的不解绑是因为,销毁了组件,自定义事件也会被销毁。但是这个==bus不是这个组件里的==!

3. 芝士捕虫

1. setTimeout

之前捕虫了 setInterval 在一定时间内,持续执行一个函数

这个函数是,在一段时间之后,执行这个函数。比如上面的:

setTimeout(() => {
    // 在5秒之后,销毁vm
    this.destroyed()
}, 5000);

重复调用:

let i = 5
console.log('vm 要销毁啦!')
function a() {
    if (i > 0) {
        // 倒计时没到 0
        setTimeout(() => {
            console.log(i--)
            a()
        }, 1000);
    }
    else {
        // 倒计时倒完了
        console.log('BOOM!!!');
        this.destroyed()
    }
}
// 调用后,倒计时开始
a()
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值