Vuex getter JSON .stringify не реагирует - PullRequest
1 голос
/ 11 февраля 2020

У меня есть следующее хранилище Vuex:

const store = new Vuex.Store({
    state: {
        renderedBlocks: []
    },
    getters: {
        asString: (state) => () => {
            return JSON.stringify(state.renderedBlocks);
        },
        block: (state) => (k) => {
            return state.renderedBlocks[k];
        }
    },
    mutations: {
        updateBlock(state, data) {
            if (!state.renderedBlocks[data.id]) { return; }
            state.renderedBlocks[data.id].params = data.params;
            state.renderedBlocks[data.id].content = data.content;
        },
        updateBlockIndex(state, data) {
            var s = state.renderedBlocks[data.id];
            s.content[data.index] = data.value;
            state.renderedBlocks[data.id] = s;
        }
    }
});

Это состояние отслеживает все «блоки» в редакторе Wisiwyg (например, «Заголовок», «Изображение», «Абзац» и т. Д. c).

Чтобы отправить все это при отправке формы, мне нужно передать эти данные в json и назначить их скрытому текстовому полю. Согласно Vue devtools, хранилище обновляется правильно, но метод получения asString не обновляет JSON.

. Здесь находятся все компоненты для всех зарегистрированных блоков (то есть видимых в редакторе). рендерится:

<template>
    <div class="zg-content">
        <component v-for="(block, c) in $store.state.renderedBlocks" :is="block.component" :key="c"></component>
    </div>
</template>

Вот где происходит вывод:

<template>
    <input type="hidden" :name="name" :value="asString">
</template>

<script>
export default {
    computed: {
        asString() {
            return this.$store.getters.asString();
        }
    }
};
</script>

И здесь может произойти обновление одного блока:

<template>
    <ul ref="input">
        <li :key="key" v-on:keydown.enter="addElement(key, $event)" v-for="(point, key) in innerContent" contenteditable="true" v-html="point.content" @blur="updateContent(key, $event)"></li>
    </ul>
</template>

<script>
export default {

    props: {},

    computed: {
        params: {
            set(v) {},
            get() { return this.$store.getters.block(this.$vnode.key).params; }
        },
        innerContent: {
            set(v) {},
            get() { return this.$store.getters.block(this.$vnode.key).content; }
        }
    },

    methods: {
        addElement(index, event) {
            var self = this;
            event.preventDefault();

            this.innerContent.splice(index+1, 0, {content: ''});

            this.$store.commit('updateBlock', {
                id: this.$vnode.key,
                params: this.params,
                content: this.innerContent
            });
        },
        updateContent(key, event) {
            this.$store.commit('updateBlockIndex', {
                id: this.$vnode.key,
                index: key,
                value: {'content': event.target.innerHTML }
            });
        }
    }
};
</script>

Итак Когда я добавляю новый элемент или изменяю существующий, событие размытия 'li' срабатывает. Мое состояние обновлено правильно - это означает, что Элемент видим с {'content': 'NewContent'} в хранилище. Но JSON в скрытом вводе все еще является старым.

Я понял, что когда я создаю «приватную» версию всех элементов списка прямо внутри моего компонента листинга, это работает как ожидается. Но это не совсем «путь Vuex», и в строгом режиме я также получаю много ошибок.

1 Ответ

2 голосов
/ 11 февраля 2020

Из документов :

Из-за ограничений в JavaScript, Vue не может обнаружить следующие изменения в массиве: когда вы непосредственно устанавливаете элемент с помощью index, например vm.items [indexOfItem] = newValue

Вы можете использовать splice или Vue.set, чтобы преодолеть это, потому что они оба обнаружимы. Например, в updateBlockIndex, заменив последнюю строку следующим:

state.renderedBlocks.splice(data.id, 1, s);

или

Vue.set(state.renderedBlocks, data.id, s);

Если вы используете Vue.set, вам также необходимо:

import Vue from 'vue'

Вы должны сделать то же самое в updateBlock. Я предполагаю, что причина, по которой он «работает» сейчас, заключается в том, что от splice до innerContent.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...