Make directives available to all components within a render tree
trainiac opened this issue · 3 comments
What problem does this feature solve?
If you have a directive that relies on a piece of user data (e.g. language), in server side rendering you need to be able to create a new directive per request.
const getTranslateDirective = lang => ( {
bind () {
// access to lang
},
update () {
// access to lang
}
})
const translate = getTranslateDirective(() => parsedLangHeader.language)
// PROBLEM - this sets translate a directive globally across reqeusts
Vue.directive('translate', translate)
However this is a problem because when you call Vue.directive('translate', translate) this changes the translate directive across ALL requests.
What does the proposed API look like?
What is needed is a way to make directives available to a component and all of it's children components
const getTranslateDirective = lang => ( {
bind () {
// access to lang
},
update () {
// access to lang
}
})
const translate = getTranslateDirective(() => parsedLangHeader.language)
new Vue({
directives: {
translate: {
module: translate,
provide: true // Makes the directive available to this component and all of it's children.
}
}
})
FYI directives on the server needs to be implemented in a completely different fashion (as VNode transforms) because there's no DOM access: https://ssr.vuejs.org/en/api.html#directives
Also, I don't see the point of creating fresh directive instances for each request. You should somehow inject parsedLangHeader.language
into your app as a piece of application state so it can be accessed across the app instance for that request.
@yyx990803 Thanks for taking the time to review this. When you say
You should somehow inject parsedLangHeader.language into your app as a piece of application state so it can be accessed across the app instance for that request.
I think for most cases that is appropriate but consider this example.
The desired translation directive is
<!-- The language is implicit -->
<div v-translate>Hello</div>
I could do this instead
<div v-translate='$store.state.language'>Hello</div>
But this feels very verbose to have to do all over the application.
Given Vue's exsiting API I dont see how you can avoid this.
I understand directives don't have DOM access on the server, but my feature request (most likely naive) is to make it easy to provide the application state to a directive at creating time per request so it doesnt have to be passed into the directive throughout the entire application
It looks like this might be solved with vuejs/rfcs#29