Vue中的provide和inject

126 阅读1分钟

一 考虑一键换肤场景

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

  1. 在提供数据的地方写一个provide
  2. 在需要注入数据的地方写inject
//ChangeThemeButton.vue
<template>
    <div>
        <button @click="this.change">换肤</button>
    </div>
</template>

<script>
    export default {
        name: 'ChangeThemeButton',
        inject:["themeName","change"]
    };
</script>

三 总结

  1. 祖先提供,子代注入,作用是大范围隔N代共享信息。
  2. provide 和 inject 主要在开发高阶插件/组件库时使用。并不推荐用于普通应用程序代码中。这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在其上下游关系成立的时间里始终生效。这与 React 的上下文特性很相似。