I wrote a "loading state" mixin for Vue 2:
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
},
}
}
I use this mixin for other components to hold the loading state. For example for forms, buttons, tables etc.
Now, Im trying to rewrite this mixin to composition API style for Vue 3. Ideally, I would like to use my loading composable like this:
// components/Table.vue
import 'useLoading' from 'src/composables/loading'
export default defineComponent({
setup () {
const { startLoading, stopLoading, innerLoading } = useLoading()
// ...
return { startLoading, stopLoading, innerLoading, ... }
}
})
My question:
// How can I define the loading prop inside the setup() function?
props: {
loading: {
type: Boolean,
default: false
},
},
Of course I can define my component like this:
import 'useLoading' from 'src/composables/loading'
export default defineComponent({
props: {
loading: {
type: Boolean,
default: false
},
},
setup () {
const { startLoading, stopLoading, innerLoading } = useLoading();
}
})
But imagine, I have 20 components using this mixin/composable. So I want to define that loading prop only ONCE (like I did in mixin).
Is there a way how to do it with composition API?
propscan't be declared insidesetup(). Sincesetup()itself receives thepropsvalues as its second argument,propswould have to be declared beforesetup()is even invoked. Currently, the only way to declarepropsis using the Options API.loadingprop in the watcher within the composable?useLoadingandwithLoading. TheuseLoadingcontains the whole logic andwithLoadingreturns props exactly like @Daniel said (stackoverflow.com/a/66604160/2987610). I don't use watcher in my new implementation, but't it seems to me like you are asking something else.useLoadingwhere you have all the logic how do you access thepropsof component which is using theuseLoadingcomposable? I can understand that in the consuming component you include...withLoading()to declare the proploadingbut then how do you get access to the prop inuseLoading?export function useLoading (props, ctx) { props.loading; }But of course, you need to passpropsandctxtouseLoadinglike this:setup (props, ctx) { const { ... } = useLoading(props, ctx); return [ ... ] }Another syntax is this:setup(props, ctx) { return [ ...useLoading(props, ctx) ] }or this:setup: useLoading