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?
props
can't be declared insidesetup()
. Sincesetup()
itself receives theprops
values as its second argument,props
would have to be declared beforesetup()
is even invoked. Currently, the only way to declareprops
is using the Options API. – tony19loading
prop in the watcher within the composable? – DonkarnashuseLoading
andwithLoading
. TheuseLoading
contains the whole logic andwithLoading
returns 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. – mspidervuseLoading
where you have all the logic how do you access theprops
of component which is using theuseLoading
composable? I can understand that in the consuming component you include...withLoading()
to declare the proploading
but then how do you get access to the prop inuseLoading
? – Donkarnashexport function useLoading (props, ctx) { props.loading; }
But of course, you need to passprops
andctx
touseLoading
like this:setup (props, ctx) { const { ... } = useLoading(props, ctx); return [ ... ] }
Another syntax is this:setup(props, ctx) { return [ ...useLoading(props, ctx) ] }
or this:setup: useLoading
– mspiderv