Функция provide в Vue3


Vue3 选项式 APIVue3 Options API

provideЭта функция — это функция высшего порядка, предоставляемая Vue3 и используемая для передачи данных от родительских компонентов к дочерним компонентам в дереве компонентов. По сравнению с традиционнымpropsпо сравнению,provideиinjectона обеспечивает более гибкий способ обмена данными, особенно когда иерархия компонентов глубока.

Использованиеprovideфункцию, родительский компонент может через неё предоставить дочернему компоненту некоторые данные или методы, а дочерний компонент может черезinjectфункцию для получения этих данных или методов.


Базовое использование функции provide

Ниже приведён простой пример, показывающий, как использоватьprovideфункцию для предоставления данных в родительском компоненте, а в дочернем компоненте черезinjectфункцию для получения данных.

Родительский компонент

Пример

<template>
  <div>
    <ChildComponent />
  </div>
</template>

<script>
import { provide } from 'vue';
import ChildComponent from './ChildComponent.vue';

export default {
  components: {
    ChildComponent
  },
  setup() {
    const message = 'Hello from Parent!';
    provide('message', message);
  }
};
</script>

Дочерний компонент

Пример

<template>
  <div>
    <p>{{ injectedMessage }}</p>
  </div>
</template>

<script>
import { inject } from 'vue';

export default {
  setup() {
    const injectedMessage = inject('message');
    return {
      injectedMessage
    };
  }
};
</script>

В этом примере родительский компонент черезprovideфункция передаёт строкуmessage, а дочерний компонент черезinjectфункция получает и отображает это сообщение.


Продвинутое использование функции provide

provideФункция может передавать не только простые данные, но также методы, объекты и даже реактивные данные. Это делает её очень полезной в сложных сценариях приложений.

Передача реактивных данных

В Vue3 мы можем использоватьrefилиreactiveчтобы создавать реактивные данные и передавать их черезprovideфункцию дочернему компоненту.

Пример

<template>
  <div>
    <ChildComponent />
  </div>
</template>

<script>
import { provide, reactive } from 'vue';
import ChildComponent from './ChildComponent.vue';

export default {
  components: {
    ChildComponent
  },
  setup() {
    const state = reactive({
      count: 0
    });

    provide('state', state);

    return {
      state
    };
  }
};
</script>

В дочернем компоненте мы можем с помощьюinjectфункции получить этот реактивный объект и работать с ним.

Пример

<template>
  <div>
    <p>Количество: {{ state.count }}</p>
    <button @click="state.count++">Увеличить</button>
  </div>
</template>

<script>
import { inject } from 'vue';

export default {
  setup() {
    const state = inject('state');
    return {
      state
    };
  }
};
</script>

Примечания о функции provide

При использованииprovideо функции, нужно учесть следующие моменты:

1. Конфликты имен

При использованииprovideиinject, если несколько родительских компонентов предоставляют данные с одинаковым именем, дочерний компонент получит данные, предоставленные ближайшим родительским компонентом. Поэтому во избежание конфликтов имен рекомендуется использовать уникальные имена.

2. Обработка реактивных данных

При передаче реактивных данных дочерний компонент может напрямую изменять эти данные. Если вы хотите, чтобы дочерний компонент только читал данные, не изменяя их, вы можете использоватьreadonlyфункцию для обертывания реактивных данных.

Пример

import { provide, reactive, readonly } from 'vue';

export default {
  setup() {
    const state = reactive({
      count: 0
    });

    provide('state', readonly(state));
  }
};

Vue3 选项式 APIVue3 Options API

Другие расширения