How to bind nested vuex object to vuejs property in tiptap text editor?

I'm trying to bind the nested Vuex state object to editor property of tiptap's editor-content component.

The state looks like this:

<template>
  <table
    :style="{ backgroundColor: element.options.backgroundColor }"
    class="main"
    width="100%"
    cellspacing="0"
    cellpadding="0"
    border="0"
    align="center"
    style="display: table;"
    data-type="title"
  >
    <tbody>
      <tr>
         <td>
             class="border-9/5 border-dashed border-transparent hover:border-blue-200"
            :class="{
              'border-builder-blue shadow border-dashed cursor-auto hover:border-builder-blue':
                element.active,
              'cursor-pointer': !element.active,
            }"
          >
            <div
              :align="element.options.align"
              :style="{
                paddingTop: element.options.padding[0],
                paddingRight: element.options.padding[1],
                paddingBottom: element.options.padding[2],
                paddingLeft: element.options.padding[3],
              }"
              style="color: #757575;"
              data-block-id="background"
            >
              <editor-content :editor="computedEditor" />
            </div>
          </div>
        </td>
      </tr>
    </tbody>
  </table>
</template>

<script>
import { EditorContent, Editor } from 'tiptap';

export default {
  components: {
    EditorContent,
  },
  props: ['element'],
  data() {
    return {
      content: null,
      options: {},
      id: '',
    };
  },
  computed: {
    computedEditor: {
      get() {
        return this.$store.state.email.editors[0].editor;
      },
      set(value) {
        this.$store.commit('email/testEditorUpdate', value);
      },
    },
  },
};
</script>

<style></style>

Store in nuxt framework.

import { ELEMENTS_DATA, DEFAULT_OPTIONS_DATA, ICONS_DATA } from '../components/editor/editor.data';

export const state = () => ({
  testEditor: null,
  currentElement: null,
  currentEditor: null,
  editors: [],

  elements: [],
  html: '',
  emailSettings: {
    options: {
      paddingTop: '50px',
      // paddingLeft: '5px',
      paddingBottom: '50px',
      // paddingRight: '5px',
      backgroundColor: '#EDF2F7',
    },
    type: 'emailSettings',
  },
});

export const getters = {
  getEditorById: (state) => (elementId) => {
    debugger;
    const { editor } = state.editors.find((editor) => editor.elementId === elementId);
    return editor;
  },
};

export const mutations = {
  addNewElement(state, newElement) {
    if (Array.isArray(newElement)) {
      state.elements.push(newElement[0]);
    }
    state.elements.push(newElement);
  },
  addNewEditor(state, newEditor) {
    state.editors.push(newEditor);
  },
  updateElements(state, elements) {
    state.elements = [...elements];
  },
  setCurrentElement(state, element) {
    if (state.currentElement) {
      state.currentElement.active = false;
    }
    state.currentElement = element;
    state.currentElement.active = true;
  },
  setCurrentEditorById(state, id) {
    state.currentEditor = state.editors.find((item) => item.elementId === id);
    state.currentEditor.editor.options.editable = true;
  },
  updateCurrentEditor(state, editor) {
    state.currentEditor.editor = { ...editor };
  },
  testEditorUpdate(state, editor) {
    state.editors[0].editor = editor;
  },
  setEditable(state, id) {
    const currentEditor = state.email.editors.find((item) => item.elementId === id);
    currentEditor.editor.options.editable = true;
  }, 
  toggleElementActive(state, element) {
    element.active = !element.active;
  },
};

The nested vuex object is located in editors array in vuex store shown in picture below.

Структура магазина Vuex img

Если я сделаю такой подход, то получу журнал ошибок vue. Когда я делал это с помощью свойств данных vue, это работало как шарм, но обновление до vuex было для меня довольно проблематичным, и я не знаю почему.

client.js?06a0:97 Error: [vuex] do not mutate vuex store state outside mutation handlers.
    at assert (vuex.esm.js?2f62:135)
    at Vue.store._vm.$watch.deep (vuex.esm.js?2f62:889)
    at Watcher.run (vue.common.dev.js?4650:4563)
    at Watcher.update (vue.common.dev.js?4650:4537)
    at Dep.notify (vue.common.dev.js?4650:741)
    at EditorView.reactiveSetter [as _props] (vue.common.dev.js?4650:1066)
    at EditorView.update (index.es.js?576a:4594)
    at EditorView.setProps (index.es.js?576a:4607)
    at Editor.setParentComponent (tiptap.esm.js?cd42:1296)
    at VueComponent.eval (tiptap.esm.js?cd42:1604)
_callee$ @ client.js?06a0:97
tryCatch @ runtime.js?96cf:63
invoke @ runtime.js?96cf:293
eval @ runtime.js?96cf:118
asyncGeneratorStep @ asyncToGenerator.js?1da1:3
_next @ asyncToGenerator.js?1da1:25
eval @ asyncToGenerator.js?1da1:32
eval @ asyncToGenerator.js?1da1:21
eval @ client.js?06a0:59
globalHandleError @ vue.common.dev.js?4650:1875
handleError @ vue.common.dev.js?4650:1844
run @ vue.common.dev.js?4650:4565
update @ vue.common.dev.js?4650:4537
notify @ vue.common.dev.js?4650:741
reactiveSetter @ vue.common.dev.js?4650:1066
update @ index.es.js?576a:4594
setProps @ index.es.js?576a:4607
setParentComponent @ tiptap.esm.js?cd42:1296
eval @ tiptap.esm.js?cd42:1604
eval @ vue.common.dev.js?4650:1985
flushCallbacks @ vue.common.dev.js?4650:1911
Promise.then (async)
timerFunc @ vue.common.dev.js?4650:1938
nextTick @ vue.common.dev.js?4650:1995
Vue.$nextTick @ vue.common.dev.js?4650:3520
computeIndexes @ vuedraggable.common.js?310e:2229
realList @ vuedraggable.common.js?310e:2198
run @ vue.common.dev.js?4650:4563
flushSchedulerQueue @ vue.common.dev.js?4650:4307
eval @ vue.common.dev.js?4650:1985
flushCallbacks @ vue.common.dev.js?4650:1911
Promise.then (async)
timerFunc @ vue.common.dev.js?4650:1938
nextTick @ vue.common.dev.js?4650:1995
Vue.$nextTick @ vue.common.dev.js?4650:3520
emit @ vuedraggable.common.js?310e:1969
dispatchEvent @ sortable.esm.js?aa47:916
_dispatchEvent @ sortable.esm.js?aa47:961
_onDrop @ sortable.esm.js?aa47:2166
handleEvent @ sortable.esm.js?aa47:2269
client.js?06a0:97 RangeError: Maximum call stack size exceeded
    at Function.keys (<anonymous>)
    at _traverse (vue.common.dev.js?4650:2149)
    at _traverse (vue.common.dev.js?4650:2151)
    at _traverse (vue.common.dev.js?4650:2151)
    at _traverse (vue.common.dev.js?4650:2151)
    at _traverse (vue.common.dev.js?4650:2151)
    at _traverse (vue.common.dev.js?4650:2151)
    at _traverse (vue.common.dev.js?4650:2151)
    at _traverse (vue.common.dev.js?4650:2151)
    at _traverse (vue.common.dev.js?4650:2151)

1 ответ

Наконец, я нашел решение. Основная проблема заключалась в том, что Vuex не мог работать с большими структурами объектов, а мой редактор объектов содержал множество функций и вложенных подобъектов конфигурации и массивов. Есть два способа решить эту проблему.

  1. Изменить структуру объекта vuex
  2. Сделайте глубокий клон объекта в мутации в магазине Vuex.
Другие вопросы по тегам