IT이야기

Vuex getter JSON.stringify가 반응하지 않음

cyworld 2022. 6. 30. 23:31
반응형

Vuex getter JSON.stringify가 반응하지 않음

여기 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 편집기에서 모든 "블록"을 추적합니다(예: 제목, 이미지, 단락 등).

폼이 제출되었을 때 이 모든 것을 보내려면 이 데이터를 json에게 전달하고 숨겨진 텍스트 필드에 할당해야 합니다.Vue devtools에 따르면 스토어는 올바르게 업데이트되지만 "asString" getter는 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 방식"이 아니며, 엄격한 모드에서는 오류도 많이 발생합니다.

문서에서:

JavaScript의 제한으로 인해 Vue는 어레이에 대한 다음과 같은 변경을 감지할 수 없습니다.인덱스로 항목을 직접 설정하는 경우(예: 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.

언급URL : https://stackoverflow.com/questions/60160883/vuex-getter-json-stringify-is-not-reactive

반응형