vue 中被忽略但却很实用的
AprilTong 1/28/2021 Vue
# 动态路由复用组件
对于复用组件(只是路由参数发生改变),生命周期函数钩子不会被调用 解决:
- 监听路由变化
watch: {
'$route'(to, from) {
// 对路由变化作出响应
}
}
1
2
3
4
5
2
3
4
5
- vue-router 的钩子方法
beforeRouteUpdate(ro, from, next) {
// 在当前路由改变, 但是该组件被复用时调用
// 举例: 对于带有动态参数的路径 /foo/:id,在/foo/1 和/foo/2 之间跳转的时候, 由于会渲染同样的Foo组件,组件会被复用, 此刻该钩子会被调用
// 可以访问组件实例this
}
1
2
3
4
5
2
3
4
5
# 监听组件生命周期
通常我们监听组件生命周期会用$emit,父组件接收事件 子组件
export default {
mounted() {
this.$emit('listenMounted')
},
}
1
2
3
4
5
2
3
4
5
父组件
<template>
<div>
<List @listenMounted="listenMounted"/>
</div>
</template>
1
2
3
4
5
2
3
4
5
简洁方法:@hook 即可监听
<template>
<List @hook:mounted="listenMounted">
</template>
1
2
3
2
3
# nextTick && 异步渲染
- 数据在同步变化时,页面订阅的响应操作不会与数据变化完全对应,而是在所有的数据变化操作做完之后,页面才会得到响应,完成页面渲染。
- 为什么异步渲染
- 用户体验: 如果数据更改两次,第一次只是中间值,如果渲染后给用户展示,页面会有闪烁效果,会造成不好的用户体验
- 性能角度:如果渲染中间值,会有无用的渲染,增加性能的消耗
nextTick 的实现原理: 不是浏览器的 API,而是通过浏览器本身提供的原生异步 API 封装而成,选用规则:Promise 存在选用 Promise.then,不存在 promise 则取 MutatiaonObserver,MutationObserver 不存在 setImmediate,setImmediate 不存在最后取 setTimeout 来实现
使用
getData(res).then(() => {
this.testData = res.data
this.$nextTick(() => {
// 这里我们可以获取变化后的 DOM
console.log(this.testData)
})
})
1
2
3
4
5
6
7
2
3
4
5
6
7
# 使用 eventBus 实现兄弟组件传数据
场景:需要兄弟组件传数据
- 建立 eventBus
import Vue from 'vue'
export default new Vue()
1
2
3
2
3
- 在需要往外传值和接受值的兄弟组件中使用 eventBus
import Bus from '@/utils/eventBus'
1
- 往外传值的组件
eventBus.$emit('getParams', data)
1
- 接收数据的组件处理
created(){
eventBus.$on('getParams', item => {
this.name = item
console.log(this.name)
})
}
1
2
3
4
5
6
7
2
3
4
5
6
7
出现异常:console.log 可以打印出 this.name 的值,但是页面中的 name 没有任何变化,还是 data 函数中的初始值; 原因:vue 路由切换时,会先加载新的组件,等新的组件渲染好但是还没有挂载前,销毁旧的组件,之后挂载新组件
新组件beforeCreate
↓
新组件created
↓
新组件beforeMount
↓
旧组件beforeDestroy
↓
旧组件destroyed
↓
新组件mounted
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
- 正确写法 在需要接收值的组件的 created 生命周期函数里写$on,并且在每次使用完之后移除应用内所有对此事件的监听, 在需要往外传值的组件的 destroyed 生命周期函数函数里写:
mounted() {
Bus.$off('getParmas')
},
1
2
3
2
3
destroyed(){
eventBus.$emit('getParams',data)
}
1
2
3
2
3