基本用法

App.vue

<template>
  <inject-child></inject-child>
</template>

<script>
import injectChild from '@/components/injectChild';
import { provide } from 'vue';
export default {
  name: 'App',
  components: {
    injectChild
  },
  // provide: { // Vue2写法
  //   name: 'Lance',
  //   age: 28
  // },
  setup() {
    // Vue3写法
    provide('name', 'Lance');
    provide('age', 28);
  }
}
</script>

injectChild.vue

<template>
  <div>
    <div>{{ name }}</div>
    <div>{{ age }}</div>
  </div>
</template>
<script>
import { inject } from 'vue';
export default {
  name: 'InjectChild',
  // inject: ['name', 'age'] // Vue2写法
  setup() {
    // Vue3写法
    const name = inject('name');
    const age = inject('age', 'loading...');
    return {
      name,
      age
    }
  }
}
</script>

Untitled

provide 响应式

父组件更新 provide

App.vue

<template>
  <div>
    <inject-child></inject-child>
    <button @click="changeName">改变名字</button>
  </div>
</template>

<script>
import injectChild from '@/components/injectChild';
import { provide, ref } from 'vue';
export default {
  name: 'App',
  components: {
    injectChild
  },
  setup() {
    const name = ref('Lance');
    provide('name', name);
    provide('age', 28);

    const changeName = () => {
      name.value = 'GC'; // 子组件能监听到父组件对name的更改
    }

    return {
      changeName
    }
  }
}
</script>

injectChild.vue

<template>
  <div>
    <div>{{ name }}</div>
    <div>{{ age }}</div>
  </div>
</template>
<script>
import { inject } from 'vue';
export default {
  name: 'InjectChild',
  setup() {
    const name = inject('name');
    const age = inject('age', 'loading...');
    return {
      name,
      age
    }
  }
}
</script>

子组件更新 provide

App.vue

<template>
  <div>
    <inject-child></inject-child>
  </div>
</template>

<script>
import injectChild from '@/components/injectChild.vue';
import { provide, ref } from 'vue';
export default {
  name: 'App',
  components: {
    injectChild
  },
  setup() {
    const name = ref('Lance');
    const changeName = () => {
      name.value = 'GC';
    }

    provide('name', name);
    // 父组件把更改函数通过 provide 传递给 子组件
    provide('changeName', changeName);
  }
}
</script>

injectChild.vue

<template>
  <div>
    <div>{{ name }}</div>
    <button @click="changeName">改变名字</button>
  </div>
</template>
<script>
import { inject } from 'vue';
export default {
  name: 'InjectChild',
  setup() {
    const name = inject('name');
    const changeName = inject('changeName');
    return {
      name,
      changeName
    }
  }
}
</script>

如果不希望子组件更改 provide,可以用 readonly 包裹 provide