I have a problem I'm stuck on right now, which has been bothering me for a few days right now, but I couldn't find a reasonable solution. I'm not even sure if it's possible at all.
What exactly I have in mind: I want to pass properties via to the child components. However, I want to do this without specifying the scope in the parent, like this:
<MyComponent v-slot="foobar">
<MySub :text="foobar.text" />
<MySub :text="foobar.text" />
<MySub :text="foobar.text" />
</MyComponent>
Since these components always occur together, so i would like to make the code cleaner for useability reasons. What I have tried (This is not meant to be working code, but just to illustrate what I want to achieve): Playground Sample
I also tried hacks like:
this.$slots.default().forEach((x) => {x.props.text = 'newText'})
But this seems to be most worst hack i could use (if it still would work :D ).
Hope somebody can help me. Codesamples in Playground:
CodePudding user response:
Seem like the kind of thing that could be solved with provide/inject
docs: https://vuejs.org/guide/components/provide-inject.html
example:
MyComponent.vue
<script>
export default {
data() {
return {
greetingMessage: 'hallo Test'
}
},
provide(){
return {greetingMessage: this.greetingMessage}
}
}
</script>
<template v-slot="foobar">
<div>
<slot :text="greetingMessage"></slot>
</div>
</template>
MySub.vue
<script>
import {inject} from "vue"
export default {
inject: ['greetingMessage'],
}
</script>
<template :text="foobar.text">
<div>
{{ greetingMessage }}
</div>
</template>
This will make the value defined in provide
available to any child (no matter how deep) through inject
.
However not that the provide
does not include reactivity out-of-the-box, so if you are expecting that to be reactive, just wrap in a computed (using composition api)
MyComponent.vue
<script>
import {computed} from "vue"
export default {
data() {
return {
greetingMessage: 'hallo Test'
}
},
provide(){
return {greetingMessage: computed(()=>this.greetingMessage)}
}
}
</script>
<template v-slot="foobar">
<div>
<slot :text="greetingMessage"></slot>
<button @click="greetingMessage = greetingMessage '!'">
change message
</button>
</div>
</template>
link to working example on sfc