Я прочитал интересную статью об использовании компонентов без рендеринга в VueJ, написанную Маркусом Оберленером. Компонент без рендеринга не отображает ни HTML, ни шаблон сам по себе, а предоставляет данные другим компонентам через слот с заданной областью. В своей статье Маркус показывает, как создать компонент без рендеринга, который обрабатывает операции CRUD. Результатом является многократно используемый компонент, который предоставляет данные и методы CRUD внутренним компонентам. Создание компонентов без рендеринга для обработки операций CRUD в Vue.js
Мне очень понравился этот подход, но он оставил мне один вопрос. Данные хранятся внутри родительского компонента. Что, если нам нужно получить доступ к этим данным из нескольких компонентов? В таком сценарии мы будем использовать vuex store. Но можем ли мы использовать компонент без рендеринга, подключенный к хранилищу vuex? Кроме того, можем ли мы сократить шаблонный код отображения нашего состояния и действий внутри компонентов?
В результате должен получиться компонент без рендеринга с таким интерфейсом:
Компонент StoreProvider без рендеринга подключается к хранилищу vuex и отображает состояние и действия, определенные в реквизитах. Другие компоненты, отображаемые в слоте с ограниченной областью видимости, могут получить доступ к состоянию и действиям, ничего не зная о хранилище. В этом примере раздел отображается внутри слота с заданной областью и может получить доступ к state.posts и action.addPost. Родительский компонент не заботится ни о каких данных или действиях.
Начнем с простого магазина Vuex.
Мы абстрагируем и скрываем всю информацию о магазине внутри нашего компонента StoreProvider.
Компонент принимает в качестве свойств два массива. Имена полей внутри состояния, о котором мы заботимся, и имена действий, которые мы хотим использовать.
Самая важная часть - это два метода, называемые watchState
и setAction
. Мы не можем просто отобразить магазин, используя методы mapState
и mapActions
vuex. Причина этого в том, что для создания универсального и многоразового компонента мы определяем, какое состояние и действия нам важны, внутри свойств StoreProvider. Эта информация пока недоступна при использовании mapState и mapActions в определении вычисляемых методов и методов. Кроме того, мы не можем добавлять какие-либо вычисленные свойства после создания компонента. Но выход есть.
Внутри watchState
мы перебираем каждый ключ, определенный в массиве состояний, и наблюдаем за состоянием хранилища с помощью $ watch. Каждый раз, когда состояние магазина изменяется, мы обновляем данные нашего StoreProvider. Эти данные доступны в слоте с заданной областью действия.
Метод setActions
попроще. Для каждого имени действия, определенного в реквизитах, мы создаем функцию, которая отправляет действие. Доступ к этим функциям можно получить с помощью переменной actions внутри слота с заданной областью действия.
Ознакомьтесь с полным примером, включая состояние, действия и геттеры, на Github.
И смотрите Демо