美文网首页
Vue3实现组件级基类的几种方法

Vue3实现组件级基类的几种方法

作者: 自然框架 | 来源:发表于2023-04-27 08:38 被阅读0次

    Vue3的组件有三种代码组织方式

    1. 纯Option API (不含setup)
    2. option API + setup
    3. 纯 setup (即composition API)

    对于这三种形式,设置基类的方法也略有不同。

    使用 mixins、extends

    vue3提供了 mixins和extends,但是尝试之后发现这两种方法只支持纯OptionAPI,设置的data会被识别,但是设置的setup里return 的 reactive,完全无效,setup也没有被执行。
    所以这种方式只能使用于第一种方式。

    使用 hooks (function、class)

    既然官方没有提供,那么我们自己来想想办法。我们先观察一下组件的代码(第二种情况):

    <template>
      <!--模板-->
      举例
    </template>
    
    <script lang="ts">
      import { defineComponent } from 'vue'
    
      export default defineComponent({
        name: 'ui-core-',
        components: {
          // 注册共用组件
        },
        props: {
          // 定义共用属性
        },
        setup(props, context) {
          // 各种共用操作
          _logger()
          _setTitle()
          // 共用成员
          const foo = reactive ({})
          return {
            foo
          }
        }
      })
    </script>
    

    defineComponent 方法接收一个对象,对象需要有特定的几个属性,比如name、components、props、setup等。
    那么也就是说,我们可以做一个函数返回这样的对象即可。
    比如我们先建立一个js(或则ts)文件:

    export function base (name, callback) {
      return {
        name: 'ui-' + name,
        components: {
          // 注册共用组件
        },
        props: {
          // 定义共用属性
        },
        setup(props, context) {
          // 各种共用操作
          _logger()
          _setTitle()
          // 共用成员
          const foo = reactive ({})
    
          // 执行其他操作
          const re = callback(props, context)
          return {
            foo,
            ...re
          }
        }
      }
    }
    

    有点像模板模式。

    传入name和一个回调函数,props, context作为参数进行传递。内部成员也可以作为参数传递。
    这样一个简单的基类就做成了,如果你觉得function不好看,那么可以换成class。

    export default class BaseComponent {
      name: string
      components: any
      props: any
      setup: any
    
      constructor (name: string, callback: (props: any, context: any) => any) {
        this.name = name
        this.components = {}
        this.props = {}
        this.setup = (props: any, context: any) => {
          // 各种共用操作
          _logger()
          _setTitle()
    
          // 执行其他操作
          const re = callback(props, context)
    
          return {
            ...re
          }
        }
        
      }
    }
    

    有了class之后,还可以设置子类,不过感觉有点繁琐。总之,反正可以实现就对了。

    script setup怎么办

    上述这种方法应该也是可以支持纯composition API的,但是有点小问题,defineProps 和 defineEmits 并不是普通 js 函数,而是一种“宏”。
    引用官网的解释:

    defineProps 和 defineEmits 都是只能在 <script setup> 中使用的编译器宏。他们不需要导入,且会随着 <script setup> 的处理过程一同被编译掉。
    也就是说 defineXXX系列 只有在 <script setup> 标签内部才会被识别,如果在单独的js文件里面,不会被识别。

    这就导致 defineProps 和 defineEmits 无法做成基类的形式。
    如果需要的基类不涉及 defineProps 和 defineEmits 的话,那么还是可以在单独的js文件里面定义一个function或者class的,(即做一个综合的hooks)。

    如果涉及 defineProps 和 defineEmits,那么,我也没想出来办法。(只能第二种方式)

    相关文章

      网友评论

          本文标题:Vue3实现组件级基类的几种方法

          本文链接:https://www.haomeiwen.com/subject/obybjdtx.html