I think these days every developer have heard about the context in React.js, So I’ll straightly go over the code and the solution. If you’re not familiar with Reacts context click on the link.
If you are a React developer and thinking like React “context” you cannot work with Vue.js without the Provide and Inject feature (I mean it’s hard, really).
Let’s see a simple example of Provide and Inject:
So basically “Provide” it’s for passing data or methods to the children with “Inject” property, regardless of how deep they are, But what will be solved exactly?
- Not using props to pass the data to children like 5 levels
- Clean, simple and powerful store management and not using the Vuex when it’s not necessary
These two screenshots are part of provide and injection in Vue source code (after normalisation them).
- Provide: You can write it as Object or a function which returns an Object which you can access to the component context (this) and you can pass method or computed properties or whatever in the component.
- Inject: You can write it as an Array of strings or Object with a default value.
- about resolveInjection function: It’s a simple loop over the inject object and looking for the provider with a “while” loop to resolve it.
We’ll build the “famous theme handler” with context to understand how easy and useful is the context.
- Use Vue cli to bootstrap your project.
- Now, You can have a structure like this.
As you see we have a weird “context” folder which we’ll look into it in further steps. :)
- Let’s go to “contexts” folder, Create a JS file and call it “Theme.js”.
- We have two components in the same file with the string templates in this case you need the standalone build, here is a helpful section explaining (of course you can have separate files like ThemeProvider.vue and ThemeConsumer.vue).
- First one is our Provider which provides the data and methods to injectors.
- Second one is our Injector (Consumer) which is able to inject the provided data. actually second one is just a helper to write less code and reuse it every where.
And that’s it, we are good to go. You just need to import the Consumer and then you can access to provided data using “slot-scope”.
- You’ll need to import and wrap the Provider inside your application root. Unfortunately there’s no Hooks in the current versions of Vue yet to use it like React (useContext).
- Let see some magics. We have two components which we’ll see the different use cases.
- First component: We see a component which wrapped with the Consumer and you can access to the data and methods by “slot-scope”. You can bind styles and pass the theme variables or you can bind classes and handle the styles and theme using css!
- Second component: We see a component which wrapped with a “div” in template and includes two ThemeConsumer, this means you can have a lot of Consumers in every where also you can override them easily.
Note: the provide and inject bindings are NOT reactive. This is intentional. However, if you pass down an observed object, properties on that object do remain reactive.
No matter if you are working with React or Vue, “Context is everything”! It’s very simple to understand, divide you application code and structure. It solves the problem of passing stuff deep down your component.
Thanks for reading, If there is anything I have missed, or if there is a better way to do something, then please let me know. 🤙