# 1.provide & inject 基本使用

vue
// App
<template>
  <div>
    <h2>-------------App--------------</h2>
    <h2>App name: {{ name }}</h2>
    <h2>App age: {{ age {{</h2>
    <h2>-------------Home--------------</h2>
    <home />
  </div>
</template>
<script>
import { provide } from "vue";
import Home from "./Home.vue";
export default {
  components: {
    Home,
  },
  setup() {
    const name = "Nekoaimer";
    let age = 16;
    provide("name", name);
    provide("age", age);
    return {
      name,
      age,
    };
  },
};
</script>
<style scoped></style>
vue
// Home
<template>
  <div>
    <h2>Home:{{ name }}</h2>
    <h2>Home:{{ age }}</h2>
  </div>
</template>
<script>
import { inject } from "vue";
export default {
  setup() {
    const name = inject("name");
    let age = inject("age");
    return {
      name,
      age,
    };
  },
};
</script>
<style scoped></style>

参考结果:

provide&inject_basic

# 2. 不是响应式

vue
// App
<template>
  <div>
    <h2>-------------App--------------</h2>
    <h2>App name: {{ name }}</h2>
    <h2>App age: {{ age }}</h2>
    <button @click="appIncrement">App+1</button>
    <h2>-------------Home--------------</h2>
    <home />
  </div>
</template>
<script>
import { provide } from "vue";
import Home from "./Home.vue";
export default {
  components: {
    Home,
  },
  setup() {
    const name = "Nekoaimer";
    let age = 16;
    const appIncrement = () => {
      age++;
      console.log("App", age);
    };
    provide("name", name);
    provide("age", age);
    return {
      name,
      age,
      appIncrement,
    };
  },
};
</script>
<style scoped></style>
vue
// Home
<template>
  <div>
    <h2>{{ name }}</h2>
    <h2>{{ age }}</h2>
    <button @click="homeIncrement">home+1</button>
  </div>
</template>
<script>
import { inject } from "vue";
export default {
  setup() {
    const name = inject("name");
    let age = inject("age");
    const homeIncrement = () => {
      age++;
      console.log("Home:", age);
    };
    return {
      name,
      age,
      homeIncrement,
    };
  },
};
</script>
<style scoped></style>

参考结果:数据已经改变但页面显示没有变化

provide&inject_basic

# 3. 使用 ref 响应式

vue
// App
<template>
  <div>
    <h2>-------------App--------------</h2>
    <h2>App name: {{ name }}</h2>
    <h2>App age: {{ age }}</h2>
    <button @click="appIncrement">App+1</button>
    <h2>-------------Home--------------</h2>
    <home />
  </div>
</template>
<script>
import { provide, ref } from "vue";
import Home from "./Home.vue";
export default {
  components: {
    Home,
  },
  setup() {
    const name = ref("Nekoaimer");
    let age = ref(16);
    const appIncrement = () => {
      age.value++;
      console.log("App", age);
    };
    provide("name", name);
    provide("age", age);
    return {
      name,
      age,
      appIncrement,
    };
  },
};
</script>
<style scoped></style>
vue
// Home
<template>
  <div>
    <h2>{{ name }}</h2>
    <h2>{{ age }}</h2>
    <button @click="homeIncrement">home+1</button>
  </div>
</template>
<script>
import { inject } from "vue";
export default {
  setup() {
    const name = inject("name");
    let age = inject("age");
    const homeIncrement = () => {
      age.value++;
      console.log("Home:", age);
    };
    return {
      name,
      age,
      homeIncrement,
    };
  },
};
</script>
<style scoped></style>

参考结果:但是不推荐子组件也能改父组件的数据

provide&inject_ref

# 4. 使用 readonly 单向管理

向子组件传值尽量用 readonly

vue
// App
<template>
  <div>
    <h2>-------------App--------------</h2>
    <h2>App name: {{ name }}</h2>
    <h2>App age: {{ age }}</h2>
    <button @click="appIncrement">App+1</button>
    <h2>-------------Home--------------</h2>
    <home />
  </div>
</template>
<script>
import { provide, ref, readonly } from "vue";
import Home from "./Home.vue";
export default {
  components: {
    Home,
  },
  setup() {
    const name = ref("Nekoaimer");
    let age = ref(16);
    const appIncrement = () => {
      age.value++;
      console.log("App", age);
    };
    provide("name", readonly(name));
    provide("age", readonly(age));
    return {
      name,
      age,
      appIncrement,
    };
  },
};
</script>
<style scoped></style>
vue
// Home
<template>
  <div>
    <h2>{{ name }}</h2>
    <h2>{{ age }}</h2>
    <button @click="homeIncrement">home+1</button>
  </div>
</template>
<script>
import { inject } from "vue";
export default {
  setup() {
    const name = inject("name");
    let age = inject("age");
    const homeIncrement = () => {
      age.value++;
      console.log("Home:", age);
    };
    return {
      name,
      age,
      homeIncrement,
    };
  },
};
</script>
<style scoped></style>

参考结果:

provide&inject_readonly