Как работают Provide и Inject в Vue

В 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.

Оцените статью
devanswers.ru
Добавить комментарий