1. 什么是provide和inject
在Vue中,provide和inject是一种跨组件通信的方式,它们是通过祖先组件向后代组件传递数据的方式。
// provide提供数据的组件
export default {
provide: {
name: 'Jerry'
}
}
// inject接收数据的组件
export default {
inject: ['name']
}
在提供数据的组件中使用provide提供数据,在接收数据的组件中使用inject接收数据。
不过需要注意的是,provide和inject并不是响应式的,在provide提供的数据更改时,不会自动触发视图的更新。所以我们需要自行通过watch或其他方式监听数据变化来更新视图。
2. 提示报错
在使用provide和inject的时候,我们可能会遇到以下报错:
[Vue warn]: Injection "xxx" not found
这个错误通常是由于以下原因导致的:
provide和inject的key值写错了
provide和inject的父子组件声明顺序错误,父组件provide的数据还没有被渲染到子组件就已经被子组件使用了
provide和inject在使用时不在同一个组件内
3. 解决方案
3.1 检查provide和inject的key值
请确保provide和inject的key值是相同的,如:
// 错误示例
// 父组件
export default {
provide: {
name: 'Jerry'
}
}
// 子组件
export default {
inject: ['username'] // key值不同
}
// 正确示例
// 父组件
export default {
provide: {
name: 'Jerry'
}
}
// 子组件
export default {
inject: ['name'] // key值相同
}
3.2 检查provide和inject的父子组件声明顺序
请确保provide的数据已经被渲染到子组件中再使用inject,比如以下示例:
// 父组件
export default {
data() {
return {
name: 'Jerry'
}
},
provide: {
username: this.name // 没有等template渲染完毕就使用了
}
}
// 子组件
export default {
inject: ['username']
}
以上示例会导致报错,正确的示例应该是:
// 父组件
export default {
data() {
return {
name: 'Jerry'
}
},
provide() {
return {
username: this.name // 当provide执行时,this指向父组件实例
}
}
}
// 子组件
export default {
inject: ['username']
}
3.3 检查provide和inject是否在同一个组件内
请确保提供和接收数据的组件在同一个组件内,如以下示例:
// 父组件
export default {
data() {
return {
name: 'Jerry'
}
},
provide() {
return {
username: this.name
}
}
}
// 子组件
export default {
inject: ['username']
}
// 在另一个组件中使用子组件
<template>
<div>
<child />
</div>
</template>
以上示例会导致报错,因为provide和inject不在同一个组件中。正确的示例应该是:
// 父组件
export default {
components: {
child: {
inject: ['username'],
template: '<div>{{ username }}</div>'
}
},
data() {
return {
name: 'Jerry'
}
},
provide() {
return {
username: this.name
}
}
}
// 在另一个组件中使用父组件
<template>
<div>
<parent />
</div>
</template>
4. 结语
使用provide和inject需要注意以上几点,在使用时如果遇到了问题可以尝试排除这些因素,并结合Vue官方文档进行问题排查。