Я прочитал интересную статью об использовании компонентов без рендеринга в 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.

И смотрите Демо