Vue2(六)组件自定义事件、全局事件总线、$nextTick、动画与过渡

目录

(一)组件自定义事件

1.介绍

2.组件自定义事件的绑定

(1)在组件标签绑定

(2)通过ref属性绑定

(3)绑定后只调用一次

(4)为组件绑定原生事件

3.组件自定义事件的解绑

(二)全局事件总线

1.介绍

2.结构

(1)安装全局事件总线

(2)实现组件间数据传输

(三)消息订阅与发布

1.介绍

2.具体操作

(1)订阅

(2)发布

(四)$nextTick API

(四)Vue封装的动画与过渡

1.动画

2.过渡

3.借助第三方库 


(一)组件自定义事件

1.介绍

在上个小案例了解到了子组件给父组件传递数据的一种方式:父组件传递函数给子组件,子组件通过props接收再用函数进行调用;上述方法较为繁琐,所以利用组件自定义事件可以更好的实现“子传父”的功能

组件自定义事件:

和绑定事件一样,绑定到组件标签:v-on:自定义事件名=“函数名” 或者 @自定义事件名="函数名"

自定义事件的触发函数在父组件编写,子组件在函数内写this.$emit.('自定义事件名',...数据)触发自定义事件,从而实现“子传父”的功能

!!!涉及到“子传父”的情况都可以使用组件自定义事件!孙传父、父传子等用不了

2.组件自定义事件的绑定

(1)在组件标签绑定

在App.vue中: 

<!-- 自定义事件schoolName 子传父 -->
<School v-on:schoolName="getSchoolName" />

methods: {
    getSchoolName(name) {
      console.log("app拿到了学校名:" + name)
    }
}

在school.vue中

methods: {
    sendSchoolName() {
        // 触发自定义事件
        this.$emit('schoolName', this.name)
    }
}

自定义事件创建绑定后实际是存在于vc的events属性中,通过$emit()激发

(2)通过ref属性绑定

在App.vue中

<!-- 2.自定义事件stuName 通过ref在挂载时绑定 子传父 -->
<Student ref="Stu" />

mounted() {
    // 在挂载时绑定自定义事件
    this.$refs.Stu.$on('stuName', this.getStuName)
}

在这里函数this.getStuName可以直接写成一个函数体,注意:一定是箭头函数! (this指向问题)

this.$refs.Stu.$on('stuName', (name) => {
      console.log("app拿到了学校名:" + name)
})

在student.vue中

methods: {
    sendStuName() {
        this.$emit('stuName', this.name)
    }
}

通过ref绑定看起来麻烦了点,实际这样可以实现标签直接绑定不能实现的功能,即:延时绑定

mounted() {
    // 延时3s绑定
    setTimeout(() => {
      // 在挂载时绑定自定义事件
      this.$refs.Stu.$on('stuName', this.getStuName)
    }, 3000);
  }

在挂载后的前3秒点击按钮不会响应,3s后就绑定了

(3)绑定后只调用一次

        [1]在组件标签绑定:v-once:schoolName="getSchoolName" 或者

                                        @schoolName.once="getSchoolName"

        [2]ref绑定:this.$refs.Stu.$once('stuName',this.getStuName)

(4)为组件绑定原生事件

Vue2会默认组件标签上绑定的事件就是自定义事件(Vue3已废除),所以为组件绑定原生事件时有以下两种方法:

        [1]在绑定的组件内使用$emit激发;例如:this.$emit('click')

        [2]在组件标签上添加.native;例如:@click.native="函数名"

3.组件自定义事件的解绑

this.$off('stuName') //解绑单个自定义事件
this.$off(['stuName', 'demo']) // 解绑多个自定义事件
this.$off([]) // 解绑所有自定义事件

在之前的笔记里记录的生命周期的销毁流程中,销毁的自定义事件就是这里写的所有自定义事件

一旦销毁该组件,该组件绑定的所有自定义事件都会解绑,不再有效

(二)全局事件总线

1.介绍

可以实现任意组件相互交流 适用于兄弟之间通信、爷和孙之间通信

本质就是在Vue原型上创建一个属性$bus,它的值是vm或者vc实例(能够提供$on、$off、$emit功能),从而任意组件vc都能够在原型上找到该属性,实现数据的传输

2.结构

(1)安装全局事件总线

在main.js中:

new Vue({
  // 将App组件放入容器中
  render: h => h(App),
  beforeCreate() {
    // 在Vue原型上创建一个全局事件总线$bus,其值为该vm实例
    Vue.prototype.$bus = this
  },
}).$mount('#app')

这是最最标准、基础的一种写法

(2)实现组件间数据传输

在school中:

mounted() {
    this.$bus.$on('stuName', (data) => {
        console.log("school收到了学生姓名:", data)
    })
},
beforeDestroy() {
    // 在该组件弃用删除之后,解绑该事件,减轻$bus的负担
    this.$bus.$off('stuName')
},

在$bus上绑定自定义事件stuName,stuName被触发后发送数据data给school组件

最好在组件销毁前将自定义事件解绑,减轻$bus的负担

在student中:

methods: {
    sendStuName() {
        this.$bus.$emit('stuName', this.name)
    }
},

触发自定义事件stuName,发送数据

(三)消息订阅与发布

1.介绍

可以实现任意组件的通信,借助第三方库pubsub-js实现(该库可以在多种语言里使用)

组件订阅消息,另一个组件发布消息,向订阅的组件传输数据

引入第三方库:import pubsub from 'pubsub-js' 

订阅:pubsub.subscribe('消息名',(msgname,data)=>{...}) 最好使用箭头函数(需要用到this指针)

发布:pubsub.publish('消息名',data)

2.具体操作

(1)订阅

在school.vue中

mounted() {
    // 订阅消息时箭头函数要接收至少两个数据:消息名和数据
    this.pubsubID = pubsub.subscribe('stuName', (msgName,data) => {
        console.log("school收到了学生名:", data);
    })
},
beforeDestroy() {
    // 取消订阅
    pubsub.unsubscribe(this.pubsubID)
},

订阅消息时箭头函数要接收至少两个数据:消息名和数据

pubsub设计类似于定时器,订阅消息后会返回一个id,当取消订阅的时候unsubscribe里的参数就是该id

(2)发布

在student.vue中

methods: {
    sendStuName() {
        pubsub.publish('stuName', this.name)
    }
},

发布消息要传两个参数:消息名和数据

(四)$nextTick API

在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM

用法:this.$nextTick(function(){ //dom更新后再运行的代码 }) 

在todolist小案例里,点击编辑后自动获取输入框焦点有用到这个api

this.$nextTick(function () {

    this.$refs.focusIpt.focus()

})

vue在所有处理完后才会开始编译模板,如果直接写聚焦,此时模板还未编译,输入框还未出现,执行聚焦也没有效果

$nextTick实现模板更新编译后再执行内部的代码

(五)Vue封装的动画与过渡

作用:在插入、更新、移除dom元素时,在合适的时候给元素添加样式类名

Transition Diagram

元素进入的样式:
        1.V-enter:进入的起点
        2.V-enter-active:进入过程中
        3.V-enter-to:进入的终点

元素离开的样式
        1.v-leave:离开的起点
        2.v-leave-active: 离开过程中
        3.v-leave-to:离开的终点

使用<transition>包裹要过度的元素,并配置name属性

备注:若有多个元素需要过渡,则需要使用:<transition-group>,且每个元素都要指定key值

1.动画

<transition name="comego" appear>
    <p v-show="show">我显示出来了</p>
</transition>

.comego-enter-active {
    animation: comego 0.5s;
}

.comego-leave-active {
    animation: comego 0.5s reverse;
}

@keyframes comego {
    from {
        transform: translateX(-100%);
    }

    to {
        transform: translateX(0)
    }
}

2.过渡

<transition name="comego" appear>
    <p v-show="show">我显示出来了</p>
</transition>

p {
    background-color: cornflowerblue;
    height: 50px;
    width: 200px;
    transition: 0.5s linear;
}

.comego-enter,
.comego-leave-to {
    transform: translateX(-100%);
}

.comego-enter-to,
.comego-leave {
    transform: translateX(0);
}

3.借助第三方库 

通过第三方库,例如animate.css

Animate.css | A cross-browser library of CSS animations.

网站内有用法的详细说明 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值