Home  >  Article  >  Web Front-end  >  How to implement component-level base classes in Vue3

How to implement component-level base classes in Vue3

PHPz
PHPzforward
2023-05-23 15:19:491256browse

Use mixins and extends

vue3 provides mixins and extends, but after trying it, I found that these two methods only support pure OptionAPI. The set data will be recognized, but the reactive of return in the set setup is completely Invalid, setup is not executed.
So this method can only be used in the first method.

Use hooks (function, class)

Since the official does not provide it, let’s find a way ourselves. Let's first observe the component code (second case):

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

defineComponent method receives an object, which needs to have several specific attributes, such as name, components, props, setup, etc.
In other words, we can make a function to return such an object.
For example, let's create a js (or ts) file first:

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

It's a bit like template mode.

Pass in name and a callback function, props, and context as parameters. Internal members can also be passed as parameters.
Such a simple base class is created. If you think function is not good-looking, you can change it to 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
      }
    }
  }
}

After having class, you can also set subclasses, but it feels a bit cumbersome. In short, it can be achieved anyway.

What to do with script setup

The above method should also support pure composition API, but there is a slight problem. defineProps and defineEmits are not ordinary js functions, but a kind of "macro" .
Quoting the explanation from the official website:

defineProps and defineEmits are compiler macros that can only be used in 5101c0cdbdc49998c642c71f6b6410a8. They do not need to be imported and will be compiled along with the 5101c0cdbdc49998c642c71f6b6410a8 process.
That is to say, the defineXXX series will only be recognized inside the 5101c0cdbdc49998c642c71f6b6410a8 tag. If it is in a separate js file, it will not be recognized.

This results in defineProps and defineEmits not being able to be made into base classes.
If the required base class does not involve defineProps and defineEmits, then you can still define a function or class in a separate js file (that is, make a comprehensive hook).

I haven't thought of a solution to defineProps and defineEmits. (Only the second way)

The above is the detailed content of How to implement component-level base classes in Vue3. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:yisu.com. If there is any infringement, please contact admin@php.cn delete