Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Provide/Inject in Vue.js

Isaac
September 05, 2018

Provide/Inject in Vue.js

An explanation of provide/inject, an advanced pattern in Vue.js, with plenty of examples.

Isaac

September 05, 2018
Tweet

Other Decks in Education

Transcript

  1. A thought experiment https://codepen.io/isaaclyman/pen/JayZWb You’re building a component library that

    provides <v-menu> and <v-option> components. You know it will be easier to code if v-option could know about the “type” prop you passed to v-menu.
  2. Possible solutions - Make the user pass all the necessary

    data to every single component ugh - A shared JavaScript singleton with some, uh, IDs and stuff to keep the component reusable - Something with scoped slots this isn’t what scoped slots are for but yolo i guess - Any other ideas?
  3. Provide/Inject: What is it? - A pattern for sneaking stuff

    around in Vue without using props. - A way to send secret messages to child and grandchild components.
  4. Why would I ever use it? If you’re building a

    Vue component library and it simplifies the user interface.
  5. Why would I ever use it? (continued) - You are

    providing two black-box components - One of them is meant to be used inside of the other one - You want the outer one to share data with the inner one - OR, you want the inner one to emit events to the outer one - The user would probably be annoyed if they had to pass the same data as props to both components
  6. Back in days of yore (Vue.js v0.11) <script> var myObject

    = { msg: ‘hello’ }; </script> <my-component v-with=“myObject”> <span>{{ msg }}</span> </my-component>
  7. First, the interface <script> var myObject = { msg: ‘hello’

    }; </script> <c-with :scoped=“myObject”> <c-output property=“msg”></c-output> </c-with>
  8. Then the components <!-- `With` component --> <template> <div> <slot></slot>

    </div> </template> <script> export default { props: { scoped: { required: true } }, provide() { return { scoped: this.scoped } } } </script> <!-- `Output` component --> <template> <span> {{ scoped[property] }} </span> </template> <script> export default { props: { property: { required: true } }, inject: ['scoped'] } </script>