provide() 基础使用
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
Vue.config.productionTip = false
// 孙子组件
const ChildComponent = {
template: '<div>child - component {{value}}</div>',
inject: ['yeye', 'value'],
mounted () {
console.log(this.$parent.$options.name); // comp
console.log(this.yeye); // Vue 对象
console.log(this.value); // 123
}
}
// 子组件
const compoent = {
name: 'comp',
components: {
ChildComponent
},
template: `
<div :style="style">
<slot value="456" :text="text"></slot>
<child-component></child-component>
</div>
`,
data () {
return {
style: {
width: '200px',
height: '200px',
border: '1px solid #aaa'
},
text: 'dzm'
}
},
mounted () {
console.log(this.$parent.$options.name); // Vue 对象
}
}
// 父组件
new Vue({
el: '#app',
components: {
compOne: compoent
},
provide () {
return {
yeye: this,
value: this.value
}
},
data () {
return {
value: '123'
}
},
mounted () {
console.log(this.$refs.comp, this.$refs.span);
},
template: `
<div>
<comp-one ref="comp">
<span slot-scope="props" ref="span">{{props.value}} {{props.text}} {{value}}</span>
</comp-one>
<input type="text" v-model="value">
</div>
`
})
但是上面这种方式在使用里面 input 标签输入内容的时候会发现,子组件里面使用到的 value 值会跟着变化, 但是孙子组件里面的 value 是不会发生变化的,因为 provide() 不会去监听这个值的改变,那么就需要用到下面的这种方式:
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
Vue.config.productionTip = false
// 孙子组件
const ChildComponent = {
template: '<div>child - component {{data.value}}</div>',
inject: ['yeye', 'data'],
mounted () {
console.log(this.$parent.$options.name); // comp
console.log(this.yeye); // Vue 对象
console.log(this.data.value); // 123
}
}
// 子组件
const compoent = {
name: 'comp',
components: {
ChildComponent
},
template: `
<div :style="style">
<slot value="456" :text="text"></slot>
<child-component></child-component>
</div>
`,
data () {
return {
style: {
width: '200px',
height: '200px',
border: '1px solid #aaa'
},
text: 'dzm'
}
},
mounted () {
console.log(this.$parent.$options.name); // Vue 对象
}
}
// 父组件
new Vue({
el: '#app',
components: {
compOne: compoent
},
provide () {
const data = {}
Object.defineProperty(data, 'value', {
get: () => this.value, // 每次调用 value 的时候就会每次调用这个 get 方法, get方法就会每次取读取最新的值
enumerable: true // 设置可以被读取
})
return {
yeye: this,
data
}
},
data () {
return {
value: '123'
}
},
mounted () {
console.log(this.$refs.comp, this.$refs.span);
},
template: `
<div>
<comp-one ref="comp">
<span slot-scope="props" ref="span">{{props.value}} {{props.text}} {{value}}</span>
</comp-one>
<input type="text" v-model="value">
</div>
`
})