В Vue очень просто предоставлять/сдавать реквизиты или свойства дочернему элементу. Свойства в Vue являются одним из основных способов передачи данных от родительского элемента или шаблона vue к дочернему элементу. Например, в приведенном ниже коде мы наделяем наш дочерний элемент PopularList
свойством name
и устанавливаем его в Most Popular Posts
. Это означает, что PopularList
теперь может получить доступ к данным Most Popular Posts
:
<PopularList name="Most Popular Posts" />
Однако иногда дочерние элементы могут содержать другие дочерние элементы. Если мы хотим передать данные от родительского компонента к внучатому, то проще всего это сделать с помощью provide/inject. Это позволяет нам предоставлять данные на родительском уровне и вводить их на любом уровне ниже.
Это означает, что если у нас есть свойство, которое не используется дочерним компонентом, но используется внуком, нам не нужно без необходимости передавать его через оба компонента, например Parent → Child → GrandChild
— вместо этого мы можем просто передать его как Parent → Grandchild
, как показано на схеме ниже:
Как использовать provide и inject в Vue
Если вы используете API композиции, вы можете provide
любой набор данных с помощью функции provide
:
<script setup>
import { provide } from 'vue'
provide('myKey', 'message');
</script>
provide
имеет ключ и значение — выше, ключом является myKey
, а значением — message
. Как и в случае с props, это может быть объект, или число, или любой другой допустимый тип. Мы также можем сделать это свойство реактивным, чтобы оно оставалось актуальным в дочернем элементе с помощью функции ref
:
<script setup>
import { provide, ref } from 'vue'
const message = ref('message');
provide('myKey', message);
</script>
Если вместо этого вы используете API Options, вы можете предоставить данные в компоненте, используя следующую структуру:
export default {
provide: {
myKey: 'message'
}
}
Если вам нужна версия реактивности API Options в provide
, вы должны использовать computed
. Как таковой, API композиции немного более прост в использовании с provide/inject
. Нам также нужно использовать обозначение provide()
, если мы передаем состояние каждого экземпляра — то есть, если данные поступают из функции data()
.
export default {
data() {
return {
message: 'message'
}
},
provide() {
return {
// This sets `myKey` to the message property from data().
// Putting it in `computed()` makes it reactive.
myKey: computed(() => this.message)
}
}
}
Теперь, когда мы предоставили данные, к ним можно получить доступ в любом дочернем компоненте на любом уровне с помощью функции inject
.
Доступ к родительским данным с помощью функции inject в Vue
Теперь, когда мы определили provide
в компоненте, вы можете получить доступ к этим данным с помощью inject
. В дочернем или внучатом компоненте мы можем получить доступ к myKey
, чтобы обратиться к message
. Например, предположим, что у нас есть компонент Vue, который выглядит следующим образом:
<script setup>
import { ref, provide } from 'vue'
import ChildElement from './Child.vue';
const message = ref('message');
provide('myKey', message);
</script>
<template>
<p>Hello World!</p>
<ChildElement />
</template>
… А затем дочерний элемент (Child.vue
), который выглядит следующим образом:
<script setup>
import GrandChildElement from './GrandChildElement.vue';
</script>
<template>
<GrandChildElement />
</template>
Внутри GrandChildElement
мы можем получить доступ к myKey
, поскольку мы предоставили его в родительском элементе. Мы также могли бы сделать это в Child.vue
, но для этого мы также можем просто использовать props. provide
дает нам возможность получать данные с нескольких уровней вверх. Чтобы получить доступ к этим данным в GrandChildElement
, мы используем inject
. Наш файл GrandChildElement.vue
может выглядеть примерно так:
<script setup>
import { inject } from 'vue'
const message = inject('myKey')
</script>
const message
здесь вернет текст message
, поскольку именно так мы задали myKey
с помощью provide
. Если вы используете API Options, вы можете сделать это вместо него:
export default {
inject: [ 'myKey' ],
created() {
// Can access this.myKey here
}
}
Теперь значение myKey
доступно внучатому компоненту, без необходимости передавать его сначала дочернему компоненту через props.