When the parent component transmits data, props and emit are usually used. When the parent component transmits data to the grandson component, props is used. If the parent component transmits data to the grandson component, the data needs to be transmitted to the child component first, and then the child component needs to be transmitted to the grandson component.

In this case, provide and inject can be used to solve this problem. No matter how deeply the component is nested, the parent provides data for all its children or grandchildren using provide, and the child or grandchildren inject data. It is also easier to transfer values between sibling components.

Provide/inject use of Vue2

Provide: is an object containing properties and values. Such as:

Provide :{info:" value "}Copy the code

If provide needs to use data within data, this writing will report an error. When accessing a component instance property, you need to convert provide to a function that returns an object.

provide(){
 return{
  info: this.msg
 }
}
Copy the code

Inject: Is an array of strings. Such as:

inject: [ 'info' ]
Copy the code

Receive the info data provided from above, or an object containing the from and default attributes, which can be used as a key for searching the injected content, and the default attribute specifying the default value.

Application of project/Inject in VUe2:

// Parent component export default{provide:{info:" Provides data "}} // child component export default{inject:['info'], Mounted (){console.log(" Receives data: ", this.info) // Receive data: provide data}}Copy the code

Provide/Inject is similar to subscribing and publishing messages. Provide provides or sends data, Inject receives data.

Provide/inject use of Vue3

Provide/Inject is used in the composite API, both of which can only be called during Setup, before being used, the provide/ Inject method must be imported from the VUE display.

The provide function takes two arguments:

provide( name,value )

Name: Defines the name that provides the property.

Value: Indicates the property value.

When using:

Import {provide} from "vue" export default {setup(){provide('info'," value ")}} import {provide} from "vue" export default {setup(){provide('info'," value ")}}Copy the code

The Inject function takes two parameters:

inject(name,default)

Name: the name of the property provided by the receive provide.

Default: Set the default value. This parameter is optional.

When using:

Import {inject} from "vue" export default {setup(){inject('info'," set default value ")}}Copy the code

Full instance 1: provide/ Inject instance

Import {provide} from "vue" export default {setup(){provide('info'," value ")}} </script> // Child component code <template> {{info}} </template> <script> import { inject } from "vue" export default { setup(){ const info = inject('info') return{ info } } } </script>Copy the code

Add responsiveness

To add responsiveness to provide/inject, use ref or Reactive.

Full example 2: Provide/Inject responsive

// Parent component <template> <div> info: {{info}} <InjectCom ></InjectCom> </div> </template> <script> import InjectCom from "./InjectCom" import { Provide,readonly,ref} from "vue" export default {setup(){let info = ref(" today you learn? ) setTimeout(()=>{info.value =" },2000) provide('info',info) return{info}}, Components :{InjectCom}} </script> // InjectCom subcomponent code <template> {{info}} </template> <script> import {inject} from "Vue" export default {setup(){const info = inject('info') setTimeout(()=>{info-value = "update"},2000) return{info}} } </script>Copy the code

In the example above, the value of info is changed in both the parent and child components.

Provide/inject is similar to subscribe and publish messages, following a single data stream in VUE. What does it mean? That is, the data can only be modified where it is, and the data cannot be modified in the data transfer place, which is easy to cause unpredictable state.

When a value is changed within a subscription component, it can be changed normally, but if the value is also used by other components, the state can be confused, so you need to avoid the problem at the source.

Readonly A read-only function. If you add the readonly attribute to a variable, the data can only be read and cannot be changed. If the variable is changed, a warning will be issued but the value will not be changed.

Usage:

Import {readonly} from "vue" let info= readonly(' readonly info value ') setTimout(()=>{info=" update info" // update info value after 2 seconds},2000)Copy the code

After two seconds, the browser warns that the info value cannot be modified.

Therefore, we add a read-only attribute to the data provided to prevent the data sent out from being modified.

Add readOnly to the provide of full instance 2.

provide('info', readonly(info))
Copy the code

There is a read-only alert when a child component changes a value.

To modify the value, you still need to modify the data in the component that provides the published data, so the modification method is added to the component and published at the same time, and can be called in the child component. Such as:

// let info = ref(" Did you learn today?" ) const changeInfo = (val)=>{info.value = val} provide('info',readonly(info)) provide('changeInfo',changeInfo) // Subscribe Const chang = Inject ('changeInfo') Chang (' Dash to front-end engineer ')Copy the code

Full example 3: Modify data

// Parent component <template> <div> info: {{info}} <InjectCom ></InjectCom> </div> </template> <script> import InjectCom from "./InjectCom" import { Provide,readonly,ref} from "vue" export default {setup(){let info = ref(" today you learn? ) const changeInfo = (val)=>{ info.value = val } provide('info',readonly(info)) provide('changeInfo',changeInfo) return{  info } }, Components :{InjectCom}} </script> //InjectCom subcomponent code <template> <div> < button@click ="chang(' go to the front engineer ')"> </div> </template> <script> import { inject } from "vue" export default { setup(){ const info = inject('info') const chang = inject('changeInfo') return{ info, chang } } } </script>Copy the code