vue 中被忽略但却很实用的

1/28/2021 Vue

# 动态路由复用组件

对于复用组件(只是路由参数发生改变),生命周期函数钩子不会被调用 解决:

  1. 监听路由变化
    watch: {
        '$route'(to, from) {
            // 对路由变化作出响应
        }
    }
1
2
3
4
5
  1. vue-router 的钩子方法
beforeRouteUpdate(ro, from, next) {
  // 在当前路由改变, 但是该组件被复用时调用
  // 举例: 对于带有动态参数的路径 /foo/:id,在/foo/1 和/foo/2 之间跳转的时候, 由于会渲染同样的Foo组件,组件会被复用, 此刻该钩子会被调用
  // 可以访问组件实例this
}
1
2
3
4
5

# 监听组件生命周期

通常我们监听组件生命周期会用$emit,父组件接收事件 子组件

export default {
    mounted() {
        this.$emit('listenMounted')
    },
}
1
2
3
4
5

父组件

<template>
    <div>
        <List @listenMounted="listenMounted"/>
    </div>
</template>
1
2
3
4
5

简洁方法:@hook 即可监听

<template>
<List @hook:mounted="listenMounted">
</template>
1
2
3

# nextTick && 异步渲染

  • 数据在同步变化时,页面订阅的响应操作不会与数据变化完全对应,而是在所有的数据变化操作做完之后,页面才会得到响应,完成页面渲染。
  • 为什么异步渲染
  1. 用户体验: 如果数据更改两次,第一次只是中间值,如果渲染后给用户展示,页面会有闪烁效果,会造成不好的用户体验
  2. 性能角度:如果渲染中间值,会有无用的渲染,增加性能的消耗

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

# 使用 eventBus 实现兄弟组件传数据

场景:需要兄弟组件传数据

  • 建立 eventBus
import Vue from 'vue'

export default new Vue()
1
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

出现异常:console.log 可以打印出 this.name 的值,但是页面中的 name 没有任何变化,还是 data 函数中的初始值; 原因:vue 路由切换时,会先加载新的组件,等新的组件渲染好但是还没有挂载前,销毁旧的组件,之后挂载新组件

新组件beforeCreate
        ↓
新组件created
        ↓
新组件beforeMount
        ↓
旧组件beforeDestroy
        ↓
旧组件destroyed
        ↓
新组件mounted
1
2
3
4
5
6
7
8
9
10
11
  • 正确写法 在需要接收值的组件的 created 生命周期函数里写$on,并且在每次使用完之后移除应用内所有对此事件的监听, 在需要往外传值的组件的 destroyed 生命周期函数函数里写:
mounted() {
    Bus.$off('getParmas')
},
1
2
3
destroyed(){
    eventBus.$emit('getParams',data)
}
1
2
3
上次更新: 3/22/2021, 3:28:01 PM