programing

데이터 변경 후 업데이트되지 않는 목록 및 컴포넌트 - (VueJ + VueX)

coolbiz 2022. 8. 17. 22:33
반응형

데이터 변경 후 업데이트되지 않는 목록 및 컴포넌트 - (VueJ + VueX)

베스트 프랙티스에 대한 질문(또는 실천 사례도 있음)

리스트가 있습니다(예:To-Do 목록).실제 접근법은 다음과 같습니다.

  • 부모 컴포넌트에서는, 「store.todos」어레이를 채웁니다.getter를 사용하면 v-for 루프를 사용하여 목록에 있는 할 일과 반복을 모두 얻을 수 있습니다.

  • 모든 아이템은 컴포넌트이며, 할 일 아이템을 소품으로 보냅니다.

  • 이 컴포넌트 안에는 "done" 플래그를 업데이트하기 위한 논리가 있습니다.그리고 이 요소는 플래그의 "상태"에 따라 확인란을 표시합니다.이 경우 DB에 대한 작업을 수행하고 저장소 상태를 업데이트합니다.

대신 다음 작업을 수행해야 합니다.

  • 각 목록 항목은 getter를 가지며 아이디만 하위 컴포넌트로 전송합니까?

정상적으로 동작하고 있습니다만, 새로운 아이템을 작업관리 리스트에 추가하면, 이 아이템은 완료라고 표시해도 갱신되지 않습니다.아이 컴포넌트 내부에서 게터가 아닌 소품을 사용하기 때문인지 궁금합니다.

코드:

스토어:

const state = {     
    tasks: []
}

const mutations = {     
CLEAR_TASKS (state) {
    state.tasks = [];
},
SET_TASKS (state, tasks) {
    state.tasks = tasks;
},
ADD_TASK (state, payload) {
    // if the payload has an index, it replaces that object, if not, pushes a new task to the array
    if(payload.index){          
        state.currentSpaceTasks[payload.index] = payload.task;
        // (1) Without this two lines, the item doesn't update
        state.tasks.push('');
        state.tasks.pop();
    }
    else{           
        state.tasks.push(payload.task);
    }
},
SET_TASK_COMPLETION (state, task){

    let index = state.tasks.findIndex(obj => obj.id == task.id);
    state.tasks[index].completed_at = task.completed_at;
}
}

const getters = {   
(...)
getTasks: (state) => (parentId) => {        
    if (parentId) {
        return state.tasks.filter(task => task.parent_id == parentId );
    } else {            
        return state.tasks.filter(task => !task.parent_id );
    }
}
(...)
}

const actions = {   
(...)
/*
* Add a new Task 
* 1st commit add a Temp Task, second updates the first one with real information (Optimistic UI - or a wannabe version of it)
*/
addTask({ commit, state }, task ) {         
        commit('ADD_TASK',{
            task
        });
    let iNewTask = state.currentSpaceTasks.length - 1;

axios.post('/spaces/'+state.route.params.spaceId+'/tasks',task).then(
        response => {
            let newTask = response.data;    
            commit('ADD_TASK',{
                task: newTask,
                index: iNewTask
            });
        },
        error => {
            alert(error.response.data);
        });

},
markTaskCompleted({ commit, dispatch, state }, task ){

        console.log(task.completed_at);
        commit('SET_TASK_COMPLETION', task);
        dispatch('updateTask', { id: task.id, field: 'completed', value: task.completed_at } ).then(
            response => {
                commit('SET_TASK_COMPLETION', response.data);
            },
            error => {
                task.completed_at = !task.completed_at;
                commit('SET_TASK_COMPLETION', task);
            });

},
updateTask({ commit, state }, data ) {              
    return new Promise((resolve, reject) => {       
        axios.patch('/spaces/'+state.route.params.spaceId+'/tasks/'+ data.id, data).then(
        response => {
            resolve(response.data);
        },
        error => {
            reject(error);      
        });
    })
}

}

기본적으로는 부모 컴포넌트와 자녀 컴포넌트입니다.

태스크 목록 구성 요소(Getters에서 태스크를 로드함)(...)

    <task :task = 'item' v-for = "(item, index) in tasks(parentId)" :key = 'item.id"></task>            
(...)

태스크 구성요소는 Fontawome을 사용하여 "체크박스"를 표시합니다.또한 completed_at set/true에 따라 on/off 사이의 변경도 가능합니다.

이 순서는 올바르게 동작합니다.

  1. 작업 목록 액세스
  2. 기존 항목 하나를 완료로 표시 - 확인란이 켜져 있습니다.

이 순서는 실패합니다.

  1. 새 작업을 추가합니다(먼저 '임시' 항목을 추가한 후 Ajax를 반환한 후 실제 정보(ID 등)로 업데이트합니다).ID가 없는 동안 작업에는 확인란 대신 로딩이 표시되고, 업데이트 후에는 확인란이 표시됩니다. 이 작업은 작동합니다!
  2. 새로 추가된 작업을 확인합니다. 요청을 전송하고 항목 및 DB를 업데이트합니다.단, 체크박스는 갱신되지 않습니다:(

Vue.js 문서를 찾아본 후 수정할 수 있었습니다.

Vue.js 및 Vuex는 원래 개체에 없었던 속성으로 반응성을 확장하지 않습니다.

예를 들어 배열에 새 항목을 추가하려면 다음을 수행해야 합니다.

// Vue.set
Vue.set(example1.items, indexOfItem, newValue)

자세한 내용은 이쪽:https://vuejs.org/v2/guide/reactivity.html

및 다음 URL : https://vuejs.org/v2/guide/list.html#Caveats

처음에 그것은 문제의 일부만 해결했다.항목을 어레이에 밀어넣은 후 사용하는 "해크"는 필요하지 않습니다(빈 개체를 눌러 팝업하여 목록을 강제로 새로고침함).

그러나 이 점을 염두에 두고 서버에서 반환된 개체를 확인했는데 getTasks에서는 새 항목을 저장한 후 목록에는 completed_at를 포함한 모든 필드가 포함되지만 설정된 필드만 반환되었습니다(completed_at는 생성 시 null).즉, Vue.js는 이 속성을 추적하지 않았습니다.

서버측(Laravel, btw)에서 반품할 속성을 추가했더니 모두 정상적으로 동작합니다!

이 외에 제 코드에 대한 요점이 있으시면 언제든지 추가해 주세요.

여러분 감사합니다.

언급URL : https://stackoverflow.com/questions/44782852/lists-and-components-not-updating-after-data-change-vuejs-vuex

반응형