Here is an example of a problem I once encountered, written directly in the form of my OWN QA
The official website gives an example, says itself is not support responsive data, but can pass in responsive data, then provide,inject can realize responsive
My understanding here should be correct, there is wrong place please point out.
I wrote my own demo and made the following changes
The parent page:
export default {
provide() {return {foo:this.fonnB}
},
data() {return {fonnB:'old word'}}created() {
setTimeout(()=>{
this.fonnB="new words"; Foo = this._provided. Foo ="new words"; // The update foo changes, but the child component still gets old words console.log(this._provided)},1000)},}Copy the code
The child page:
export default {
inject:['foo'].data() {return {chilrfoo:this.foo}
}
}
Copy the code
With the above two methods, it is verified that the child component page cannot implement the response to update the value of this.foo. Please explain. Thank youCopy the code
The above questions are my own, and the following questions are answered by myself after MY basic understanding
Now the following modifications have been made, so that the parent component can be changed, and the following grandson component can update data. This is passing in responsive data, and if two-way data is needed, you need to manually write the set function in computed on the Child page, which is itself just a GET function.
Note that childfooOld does not respond in the Child page data. I haven’t figured that out yet.
The parent page:
export default {
provide() {return {foo:this.fonnB}
},
data() {return {
fonnB:{a:'old word'}}}created() {
setTimeout(()=>{
this.fonnB.a="new words"; // This update foo changes, but the child component still gets old words},1000)},}Copy the code
The child page:
export default {
inject:['foo'].data() {return {
childfooOld:this.foo.a
}
},
computed:{
chilrfoo() {return this.foo.a
}
}
}
Copy the code
The source code for Prodive and Inject is as follows
export function initInjections (vm: Component) {
const result = resolveInject(vm.$options.inject, vm)
if (result) {
observerState.shouldConvert = false
Object.keys(result).forEach(key => {
defineReactive(vm, key, result[key])
})
observerState.shouldConvert = true</pre>
}
}
Copy the code
As you can see, ProDive also uses defineReactive to add its own set and GET functions, which are also reactive data, as shown below
Set /get is added explicitly, but the printout results also include set/get
export functionresolveInject (inject: any, vm: Component): ? Object {if(Inject) {// Inject is :any because the stream is not smart enough to point to the cache const result = object.create (null) // Get the key array of inject options const keys = hasSymbol ? Reflect.ownKeys(inject).filter(key => { /* istanbul ignore next */return Object.getOwnPropertyDescriptor(inject, key).enumerable
})
: Object.keys(inject)
for (let i = 0; i < keys.length; i++) {
const key = keys[i]
const provideKey = inject[key].from
let source = vm
while (source) {
if (source._provided && provideKey in source._provided) {
result[key] = source._provided[provideKey]
break
}
source = source.$parent
}
if (!source) {
if ('default' in inject[key]) {
const provideDefault = inject[key].default
result[key] = typeof provideDefault === 'function'
? provideDefault.call(vm)
: provideDefault
} else if(process.env.NODE_ENV ! = ='production') {
warn(`Injection "${key}" not found`, vm)
}
}
}
return result
}
}
Copy the code
With computed, values are passed up and down, and the personal problem is the Child page, where foo is directly bound to the data property, and the data in the child does not change when Foo changes. According to the truth, there is get/set in data, should also be a response, ask god to share the error found in the article, or have better suggestions, welcome to comment or enter the front full stack group: 866109386, to exchange and discuss the water.
Here is an example of a problem I once encountered, written directly in the form of my OWN QA
You can also access the SegmentFault address directly if you want
The official website gives an example, says itself is not support responsive data, but can pass in responsive data, then provide,inject can realize responsive.
My understanding here should be correct, there is wrong place please point out.
I wrote my own demo and made the following changes
The parent page:
export default {
provide() {return {foo:this.fonnB}
},
data() {return {fonnB:'old word'}}created() {
setTimeout(()=>{
this.fonnB="new words"; Foo = this._provided. Foo ="new words"; // The update foo changes, but the child component still gets old words console.log(this._provided)},1000)},}Copy the code
The child page:
export default {
inject:['foo'].data() {return {chilrfoo:this.foo}
}
}
Copy the code
With the above two methods, it is verified that the child component page cannot implement the response to update the value of this.foo. Please explain. Thank youCopy the code
The above questions are my own, and the following questions are answered by myself after MY basic understanding
Now the following modifications have been made, so that the parent component can be changed, and the following grandson component can update data. This is passing in responsive data, and if two-way data is needed, you need to manually write the set function in computed on the Child page, which is itself just a GET function.
Note that childfooOld does not respond in the Child page data. I haven’t figured that out yet.
The parent page:
export default {
provide() {return {foo:this.fonnB}
},
data() {return {
fonnB:{a:'old word'}}}created() {
setTimeout(()=>{
this.fonnB.a="new words"; // This update foo changes, but the child component still gets old words},1000)},}Copy the code
The child page:
export default {
inject:['foo'].data() {return {
childfooOld:this.foo.a
}
},
computed:{
chilrfoo() {return this.foo.a
}
}
}
Copy the code
The source code for Prodive and Inject is as follows
export function initInjections (vm: Component) {
const result = resolveInject(vm.$options.inject, vm)
if (result) {
observerState.shouldConvert = false
Object.keys(result).forEach(key => {
defineReactive(vm, key, result[key])
})
observerState.shouldConvert = true</pre>
}
}
Copy the code
As you can see, ProDive also uses defineReactive to add its own set and GET functions, which are also reactive data, as shown below
Set /get is added explicitly, but the printout results also include set/get
export functionresolveInject (inject: any, vm: Component): ? Object {if(Inject) {// Inject is :any because the stream is not smart enough to point to the cache const result = object.create (null) // Get the key array of inject options const keys = hasSymbol ? Reflect.ownKeys(inject).filter(key => { /* istanbul ignore next */return Object.getOwnPropertyDescriptor(inject, key).enumerable
})
: Object.keys(inject)
for (let i = 0; i < keys.length; i++) {
const key = keys[i]
const provideKey = inject[key].from
let source = vm
while (source) {
if (source._provided && provideKey in source._provided) {
result[key] = source._provided[provideKey]
break
}
source = source.$parent
}
if (!source) {
if ('default' in inject[key]) {
const provideDefault = inject[key].default
result[key] = typeof provideDefault === 'function'
? provideDefault.call(vm)
: provideDefault
} else if(process.env.NODE_ENV ! = ='production') {
warn(`Injection "${key}" not found`, vm)
}
}
}
return result
}
}
Copy the code
With computed, values are passed up and down, and the personal problem is the Child page, where foo is directly bound to the data property, and the data in the child does not change when Foo changes. According to the truth, there is get/set in data, should also be a response, ask god to share the error found in the article, or have better suggestions, welcome to comment or enter the front full stack group: 866109386, to exchange and discuss the water.