简体   繁体   English

如何在tiptap文本编辑器中将嵌套的vuex object绑定到vuejs属性?

[英]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.我正在尝试将嵌套的 Vuex state object 绑定到tiptap的编辑器内容组件的编辑属性。

The state looks like this: state 看起来像这样:

<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.存储在 nuxt 框架中。

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 object 位于 vuex 商店的 editors 数组中,如下图所示。

Vuex 存储结构 img

If I do this approach, then I get this error log of vue.如果我这样做,那么我会得到这个 vue 的错误日志。 When I did it via vue data properties, it was working like a charm but the upgrade to vuex is quite problematic to me and I don't know why.当我通过 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)

Finally, I found the solution.最后,我找到了解决方案。 The main problem was that the Vuex could not work with large object structures and my object editor contained many of functions and nested configuration subobjects and arrays.主要问题是 Vuex 无法使用大型 object 结构,而我的 object 编辑器包含许多函数和嵌套配置子对象以及 arrays。 There are two ways to solve this.有两种方法可以解决这个问题。

  1. Change the structure of the vuex object改变vuex object的结构
  2. Make a deep clone of the object in mutations in Vuex store.在 Vuex 商店的突变中对 object 进行深度克隆。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM