vue render 渲染函数

vue render 渲染函数

常常看到使用render渲染函数的示例,并且在一些特殊状况下,确实更好使用,能够更加有效地细分组件,于是借助vue-element-admin来学习一波html

render函数分析

  • 函数式组件
  • 基础的使用方式

针对 Link.vue进行改造vue

Link.vuegit

// https://github.com/vuejs/eslint-plugin-vue/issues/462
<template>
  <!-- eslint-disable vue/require-component-is -->
  <component v-bind="linkProps(to)">
    <slot />
  </component>
</template>

<script>
import { isExternal } from '@/utils/validate'
export default {
  props: {
    to: {
      type: String,
      required: true
    }
  },
  methods: {
    linkProps(url) {
      if (isExternal(url)) {
        return {
          is: 'a',
          href: url,
          target: '_blank',
          rel: 'noopener'
        }
      }
      return {
        is: 'router-link',
        to: url
      }
    }
  }
}
</script>

上述方式打开了一个新的使用方式,这样的好处,不须要使用if/else进行处理,还能够减小一个多余的标签【root element】。可是会有一些语法提示错误,虽然添加了eslint-disable来禁止,但仍是不行,并且有些不似vue的用法github

改造开始

  • 版本一 非函数式组件 【Link.vue】
<script>
import { isExternal } from '@/utils/validate'

export default {
  name: 'Link',
  props: {
    to: {
      type: String,
      required: true
    }
  },
  render(h) {
    if (isExternal(this.to)) {
      return h(
        'a',
        {
          attrs: {
            target: '_blank',
            rel: 'noopener',
            href: this.to
          }
        },
        this.$slots.default
      )
    } else {
      return h('router-link',
        {
          props: {
            to: this.to
          }
        },
        this.$slots.default
      )
    }
  }
}
</script>

主要是slot如何处置比较好,其余都好处理,并且使用slot有两种方式 插槽ide

方式一函数

this.$slots.default

方式二oop

this.$scopedSlots.default()
  • 版本二 函数式组件 【Link.vue】
<script>
import { isExternal } from '@/utils/validate'

export default {
  name: 'Link',
  functional: true,
  props: {
    to: {
      type: String,
      required: true
    }
  },
  render(h, context) {
    console.log(context)
    const { props, scopedSlots } = context
    const { to } = props
    if (isExternal(to)) {
      return h(
        'a',
        {
          attrs: {
            target: '_blank',
            rel: 'noopener',
            href: to
          }
        },
        scopedSlots.default()
      )
    } else {
      return h('router-link',
        {
          props: {
            to: to
          }
        },
        // scopedSlots.default()
        context.children
      )
    }
  }
}
</script>

对于上述两种实现方式,大体相同,有一些细节须要注意学习

  • functional: true 添加这个后,只能经过 context来进行上下文关联,而没法调用this,同时这种方式会快一些,只是在使用slot时,会有两种形式link
    • this.$slots.default 更新为 context.children
    • scopedSlots.default() 这种方式依旧在
  • 当时用functional: true,文件名即可以改成js为后缀了,若依旧使用vue时,便须要<script> export default {}</script> 进行包裹了

总结

  • render函数更可能是,不少细节不能使用语法糖来进行处理,致使使用起来不顺手
  • slot插槽这块仍是颇有用的,只是文档说明等没有前面的那么详细了
  • 经过上述方式,便发现原来能够这么玩,并且细粒度已经都要一层标签了,若使用原来的方式,root element怕是就够处理好一下子了
相关文章
相关标签/搜索