Vue 3 Composition API - 如何在 setup() 中指定道具

问题描述

我为 Vue 2 编写了一个“加载状态”mixin:

export default {
  props: {
    loading: {
      type: Boolean,default: false
    },},data () {
    return {
      innerLoading: false,}
  },mounted () {
    this.innerLoading = !!this.loading
  },methods: {
    startLoading () {
      this.$emit('update:loading',this.innerLoading = true)
    },stopLoading () {
      this.$emit('update:loading',this.innerLoading = false)
    },computed: {
    isLoading () {
      return !!this.innerLoading
    },isNotLoading () {
      return !this.innerLoading
    },watch: {
    loading (loading) {
      this.innerLoading = !!loading
    },}
}

我将此混合用于其他组件以保持 loading 状态。例如表单、按钮、表格等。

现在,我试图将这个 mixin 重写为 Vue 3 的组合 API 样式。理想情况下,我想像这样使用我的 loading 组合:

// components/Table.vue

import 'useLoading' from 'src/composables/loading'

export default defineComponent({
  setup () {
    const { startLoading,stopLoading,innerLoading } = useLoading()

    // ...
    
    return { startLoading,innerLoading,... }
  }
})

我的问题:

// How can I define the loading prop inside the setup() function?
props: {
  loading: {
    type: Boolean,default: false
  },

当然我可以这样定义我的组件:

import 'useLoading' from 'src/composables/loading'

export default defineComponent({
  props: {
    loading: {
      type: Boolean,setup () {
    const { startLoading,innerLoading } = useLoading();
  }
})

但是想象一下,我有 20 个组件使用这个 mixin/composable。所以我只想定义 loading 属性 ONCE(就像我在 mixin 中所做的那样)。

有没有办法使用组合 API 来做到这一点?

解决方法

你也许可以做这样的事情

import {withProps,useLoading} from "src/composables/loading";

export default defineComponent({
  props: {
    ...withProps()
  },setup () {
    const { startLoading,stopLoading,innerLoading } = useLoading();
  }
})

其中 withProps 是一个具有您定义的函数

export const withProps = () => ({
  loading: {
    type: Boolean,default: false
  },})

当然它不需要是一个函数,但在某些情况下它可能会有所帮助,先发制人地使其成为一个函数可以使 api 保持一致。

,

您可以使用一个名为 loadable 的 mixin,它具有加载属性:

export default{
 props: {
  loading: {
    type: Boolean,},}

然后将其导入到您的组件中并将其添加到 mixins 选项中:

import useLoading from 'src/composables/loading'
import loadable from 'src/mixins/loadable'

export default defineComponent({
 mixins:[loadable],// you could also add other mixins that contain other props like colorable
  setup (props) {
    // here you could use props.loading
    const { startLoading,innerLoading } = useLoading();
  }

注意:mixin 可以定义其他选项,例如 datacomputed,如果您只想使用组合 API,mixin 应该只定义 props 来使您的代码一致。

如果你不想使用 mixins,你可以检查 this example