2

我为 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
    },
  }
}

我将此 mixin 用于其他组件以保持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, stopLoading, 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,
      default: false
    },
  },
  setup () {
    const { startLoading, stopLoading, innerLoading } = useLoading();
  }
})

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

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

4

2 回答 2

9

你也许可以做这样的事情

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 保持一致。

于 2021-03-12T17:03:36.350 回答
3

您可以使用具有 loading 属性的 mixin loadable

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

然后将其导入您的组件并将其添加到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, stopLoading, innerLoading } = useLoading();
  }

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

如果您不想使用 mixins,可以查看此示例

于 2021-03-13T09:42:41.790 回答