Vue小知识点总结

384 阅读2分钟

立帖为证,今后对于知识的掌握不能在含含糊糊,要做到精准的了解知识点,做到说出来既准确! 加油!

2021 死磕Vue 从我做起

1.导航守卫

1.导航被触发。

2.在失活的组件里调用 beforeRouteLeave 守卫。

3.调用全局的 beforeEach 守卫。

4.在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+)。

5.在路由配置里调用 beforeEnter。

6.解析异步路由组件。

7.在被激活的组件里调用 beforeRouteEnter。

8.调用全局的 beforeResolve 守卫 (2.5+)。

9.导航被确认。

10 调用全局的 afterEach 钩子。

11.触发 DOM 更新。

12.调用 beforeRouteEnter 守卫中传给 next 的回调函数,创建好的组件实例会作为回调函数的参数传入。

2.Mixins 混入

有些组件有些重复的 js 逻辑,如校验手机验证码,解析时间等,mixins 就可以实现这种混入 mixins 值是一个数组

简单的说就是当多个组件共用了一些数据\方法等的时候, 可以将这些数据和方法进行抽离,使用mixins的方式进行引入

mixins/show.js

export const showMixin =  {
    data(){
        return {
            shwoTag: true
        }
    },
    methods: {
        tagShow(){
            this.shwoTag = !this.shwoTag
        }
    },
}

Home.vue

<template>
  <div class="home">
    <img alt="Vue logo" v-show="shwoTag" src="../assets/logo.png">
     <div @click="tagShow">显示 隐藏</div>
  </div>
</template>

<script>
import { showMixin } from '../mixins'
export default {
  name: 'Home',
  mixins: [showMixin]
}
</script>

3.$nextTick

总结: 会在DOM异步渲染完成以后执行

<template>
  <div class="about">
    <div ref="chrenDom">
      <div v-for="item in arr" :key="item">{{item}}</div>
    </div>
    <h1 @click="add">增加</h1>
  </div>
</template>

<script>
export default {
  data(){
    return {
      arr: [1,2,3,4,5]
    }
  },
  methods:{
    add(){
      this.arr.push(Math.random())

      let HM = this.$refs.chrenDom.children.length 
      console.log(this.arr.length,HM) // 6 5
    }
  }
}
</script>

在上面这段代码里, 我么为 arr 增加一个元素后, 分别去获取 ref="chrenDom" 的子元素个数和 arr 数组的长度时, 我们惊奇的发现其数量不同, 子元素个数为5, 而 数组长度缺为6

<script>
export default {
  data(){
    return {
      arr: [1,2,3,4,5]
    }
  },
  methods:{
    add(){
      this.arr.push(Math.random())
        this.$nextTick(()=>{
            let HM = this.$refs.chrenDom.children.length 
            console.log(this.arr.length,HM)  // 6 6
        })
      
    }
  }
}
</script>

4.render函数的使用

<script>
export default {
  data(){
    return {
      people: [
        'A',
        "B",
        "C"
      ]
    }
  },
  render(createElement){
    return createElement(
        'h1', 
        {},
        this.people.map(name =>{
         return createElement('div',{
           attrs: {
             class: 'test'
           },
           on:{
             click: ()=>{
               console.log('点击了')
             }
           }
         },`${name}`)
        })
        )
  }
}
</script>

5.组件渲染流程

render -> newVnode(虚拟DOM) -> patch(vnode, newVnode) diff算法 -> 更新视图

6.vue修改原生数组的方法

const arrayMethods = ['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse'];
const arrayAugmentations = [];

arrayMethods.forEach((method)=> {

    // 这里是原生Array的原型方法
    let original = Array.prototype[method];

   // 将push, pop等封装好的方法定义在对象arrayAugmentations的属性上
   // 注意:是属性而非原型属性
    arrayAugmentations[method] = function () {
        console.log('我被改变啦!');

        // 调用对应的原生方法并返回结果
        return original.apply(this, arguments);
    };

});

let list = ['a', 'b', 'c'];
// 将我们要监听的数组的原型指针指向上面定义的空数组对象
// 别忘了这个空数组的属性上定义了我们封装好的push等方法
list.__proto__ = arrayAugmentations;
list.push('d');  // 我被改变啦! 4

7.History实现原理

    const tags = document.getElementById('tags')

        window.addEventListener('DOMContentLoaded', ()=>{
            console.log(location.pathname)
        })

        // 点击 改变 路由地址
        tags.addEventListener('click', ()=>{
            const state = { name: 'home' }
            history.pushState(state, '', 'home') // 跳转地址
            console.log('路由地址切换了')
        })

        // 通过 前进 后退 改变的路由 的信息监听
        window.onpopstate = (e)=>{
            console.log(e.state, location.pathname)
            // 分别打印 state的值 和 路由地址
        }

8.hash模式

        const tags = document.getElementById('tags')

        // 首次加载时的hash
        window.addEventListener('DOMContentLoaded', ()=>{
            console.log('hash', window.location.hash)
        })


        // 点击 改变 路由地址
        tags.addEventListener('click', ()=>{
          location.href = '#/user'
        })

        // 监听地址栏的hash变化
        window.onhashchange = function(e){
            console.log('oldUrl', e.oldURL)
            console.log('newUrl', e.newURL)

            console.log('hash', window.location.hash)
        }

9.动态组件使用

<component :is="组件名称"></component>

10.指令在按钮级权限中的应用

store.js

state:{
    AuthButton: {
        add: true,
        delete: false
    }
}

Home.vue

<template>
  <div class="about">
    <div v-has="'add'">增加</div>
    <div v-has="'delete'">删除</div>

  </div>
</template>

<script>
import has from '../directives'
export default {
  directives:{
    has
  }
}
</script>

directives.js

export default {
    inserted(el, bindings, vnode){
        console.log('DOM元素插入')

        let stateValue = bindings.value  // 获取指令值
        // 获取 全局状态(Vuex)中 该用户是否拥有这个按钮的权限(true, false)
        let boolean = vnode.context.$store.state.AuthButton[stateValue] 
        // 如果没有这个按钮的权限 就获取他的父级后 删除该元素
        !boolean && el.parentNode.removeChild(el)
    }
}

自定义指令的参数

bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。(拿不到父节点)

inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。

update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新

componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。

unbind:只调用一次,指令与元素解绑时调用。