一 考虑一键换肤场景
APP.vue默认颜色为pink,APP.vue中包含Child1,Child2,Child3三个子组件,其中Child1组件中有一个一键换肤按钮。要考虑的问题是,如何通过子组件中的按钮改变APP.vue中的颜色属性,改为skyblue。即如何通过ChangeThemeButton按钮更改APP.vue中的themeName属性。
//APP.vue
<template>
<div :class="`app theme-${themeName}`">
<Child1></Child1>
<Child2></Child2>
<Child3></Child3>
</div>
</template>
<script>
import Child1 from './components/Child1';
import Child2 from './components/Child2';
import Child3 from './components/Child3';
export default {
name: 'App',
data(){
return {
themeName:'pink',//orange,skyblue
}
},
components: {
Child1,
Child2,
Child3
}
}
</script>
<style>
.app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
.app.theme-pink{
color:pink
}
.app.theme-pink button{
border: none;
background:pink;
margin: 10px;
}
.app.theme-skyblue{
color:skyblue
}
.app.theme-skyblue button{
border: none;
background:skyblue;
margin: 10px;
}
</style>
//Child1.vue
<template>
<div>child1
<ChangeThemeButton/>
</div>
</template>
二 使用provide和inject
- 在提供数据的地方写一个provide
- 在需要注入数据的地方写inject
//ChangeThemeButton.vue
<template>
<div>
<button @click="this.change">换肤</button>
</div>
</template>
<script>
export default {
name: 'ChangeThemeButton',
inject:["themeName","change"]
};
</script>
三 总结
- 祖先提供,子代注入,作用是大范围隔N代共享信息。
- provide 和 inject 主要在开发高阶插件/组件库时使用。并不推荐用于普通应用程序代码中。这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在其上下游关系成立的时间里始终生效。这与 React 的上下文特性很相似。