Vue的高階組件(HOC)使用舉例


​Vue的高階組件在官方文檔中並未提及,這個是一個舶來品,是React生態才有的一個概念。

但不妨礙我們使用它。

實際上Vue組件就是一個對象。根據高階函數的概念

在數學和計算機科學中,高階函數是至少滿足下列一個條件的函數:

  1. 接受一個或多個函數作為輸入。
  2. 輸出一個函數

高階組件也就是返回一個組件(對象數據)。

我們知道在使用Vue過程中,書寫模板的方式有三種:

  1. 使用render
  2. 使用template屬性
  3. 使用使用template模板

上述三種方式同時存在時,render的優先級是最高的。這在源碼上是Vue首先對render這個參數做個判斷,一旦有就直接使用了。

高階組件有什么用呢?之前遇到一個問題,怎么對某些組件進行全局有效性攔截?我給出的方案是用mixins混入的方案,實際還可以用高階組件。

比如我有一個Base.vue組件,一旦這個組件使用需要打印一些內容。

// Base.vue組件
<template>
  <div>
    <span @click="handleClick">props: {{test}}</span>
    <slot></slot>
  </div>
</template>
<script>

export default {
  name: 'Base',
  props: {
    test: Number
  },
  methods: {
    handleClick () {
      this.$emit('Base-click',{
        msg:'子組件emit'
      })
    }
  }
}
</script>

我們可以使用template構建一個高階組件,然后包裹Base

//template版本
export default function HOC (Base) {
    return {
      template: '<base v-on="$listeners" v-bind="$attrs"/>',
      components: {
        base: Base
      },
      mounted () {
        console.log('我是HOC mounted log')
      }
    }
  }

但是這個方案要求使用的vue是完整版而不是運行時版本。

使用render構建的高階組件

export default function Console (Base) {
    return {
      mounted () {
        console.log('我是HOC mounted log')
      },
      props: Base.props, // 繼承pros
      render (h) {
        const slots = Object.keys(this.$slots)
          .reduce((acc, cur) => acc.concat(this.$slots[cur]), [])
          // 手動更正 context
          .map(vnode => {
            vnode.context = this._self //綁定到高階組件上
            return vnode
          }) // 繼承slots

        return h(Base, {
          on: this.$listeners,
          props: this.$props,
          attrs: this.$attrs
        }, slots)
      }
    }
}

使用高階組件

<template>
  <div>
    <wrapBase @Base-click="click1" :test="100">
       <p>default slot</p>
    </wrapBase>
  </div>
</template>
<script>
//Parent.vue
import Base from "./Base.vue";
// 使用hoc替代minxin
import HOC from "./hoc"; // 這里可以是template版本也可以是render版本
const wrapBase = HOC(Base);

export default {
  components: {
    Base,
    wrapBase,
  },
  methods: {
      click1(msg){
          console.log(msg, 'msg')
      }
  }
  //...
};
</script>

以上案例高階組件用來進行日志輸出。當然也可以用來做權限校驗。

也可以參考文章:https://zhuanlan.zhihu.com/p/181673485


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM