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.
Если я сделаю такой подход, то получу журнал ошибок 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 не мог работать с большими структурами объектов, а мой редактор объектов содержал множество функций и вложенных подобъектов конфигурации и массивов. Есть два способа решить эту проблему.
- Изменить структуру объекта vuex
- Сделайте глубокий клон объекта в мутации в магазине Vuex.