zoukankan      html  css  js  c++  java
  • 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

    我站在山顶看风景!下面是我的家乡!
  • 相关阅读:
    效果1时间展示隐藏
    css书写轮播图样式
    jquery案例1导航栏事件
    jquery案例三导航展示
    go并发
    效果2滑动滑入效果
    php解决导出大数据execl问题
    jquery案例3模仿京东轮播图
    jquery案例2手风琴案例
    latex自适应resize超长表格
  • 原文地址:https://www.cnblogs.com/zhensg123/p/14699982.html
Copyright © 2011-2022 走看看