구성 요소에서 VueJS DOM이 업데이트되지 않음
다른 "DOM 업데이트 안 함" 게시물을 검토했지만 해결 방법을 찾을 수 없었습니다.우선 태스크 앱을 만들려고 하는데 이미 Firestore에서 앱을 불러와서 새로 추가하고 삭제할 수 있습니다.두 가지 문제가 있는데, 첫 번째 문제부터 시작하도록 하겠습니다.데이터를 추가하거나 삭제하면 Vuex 스토어의 각 어레이는 올바르게 업데이트되지만 DOM은 동적으로 업데이트되지 않습니다.페이지를 새로고침하면 업데이트도 됩니다.
컴포넌트 코드와 스토어 코드를 추가했습니다만, 제대로 보고 있으면 좋겠다고 생각합니다만, 뭔가 잘못된 느낌이 듭니다.
잘 부탁드립니다
스토어 코드:
import Vue from 'vue'
import Vuex from 'vuex'
// import firebase from 'firebase'
import router from '@/router'
import db from '@/db'
import firebase from '@/firebase'
Vue.use(Vuex)
export const store = new Vuex.Store({
state: {
appTitle: 'My Awesome App',
addedTask: false,
loadedTasks: false,
deletedTasks: false,
user: null,
error: null,
loading: false,
tasks: [],
task: {
title: '',
description: '',
tags: [],
dueTime: '',
dueDate: '',
reminderFlag: Boolean,
quadrant: '',
userId: '',
timestamp: ''
}
},
// Mutations (synchronous): change data in the store
mutations: {
setUser (state, payload) {
state.user = payload
state.task.userId = firebase.auth().currentUser.uid
},
setError (state, payload) {
state.error = payload
},
setLoading (state, payload) {
state.loading = payload
},
addedTask (state, payload) {
state.addedTask = payload
},
loadedTasks (state, payload) {
state.loadedTasks = true
},
deletedTask (state, payload) {
state.deletedTask = payload
}
},
// Actions (asynchronous/synchronous): change data in the store
actions: {
autoSignIn ({ commit }, payload) {
commit('setUser', { email: payload.email })
},
userSignUp ({ commit }, payload) {
commit('setLoading', true)
firebase.auth().createUserWithEmailAndPassword(payload.email, payload.password)
.then(firebaseUser => {
commit('setUser', { email: firebaseUser.user.email })
commit('setLoading', false)
router.push('/home')
commit('setError', null)
})
.catch(error => {
commit('setError', error.message)
commit('setLoading', false)
})
},
userSignIn ({ commit }, payload) {
commit('setLoading', true)
firebase.auth().signInWithEmailAndPassword(payload.email, payload.password)
.then(firebaseUser => {
commit('setUser', { email: firebaseUser.user.email })
commit('setLoading', false)
commit('setError', null)
router.push('/home')
})
.catch(error => {
commit('setError', error.message)
commit('setLoading', false)
})
},
userSignOut ({ commit }) {
firebase.auth().signOut()
commit('setUser', null)
router.push('/')
},
addNewTask ({ commit }, payload) {
commit('addedTask', false)
db.collection('tasks').add({
title: payload.title,
userId: firebase.auth().currentUser.uid,
createdOn: firebase.firestore.FieldValue.serverTimestamp(),
description: payload.description,
dueDateAndTime: new Date(payload.dueDate & ' ' & payload.dueTime),
reminderFlag: payload.reminderFlag,
quadrant: payload.quadrant,
tags: payload.tags
})
.then(() => {
commit('addedTask', true)
this.state.tasks.push(payload)
commit('loadedTasks', true)
})
.catch(error => {
commit('setError', error.message)
})
},
getTasks ({ commit }) {
commit('loadedTasks', false)
db.collection('tasks').orderBy('createdOn', 'desc').get().then(querySnapshot => {
querySnapshot.forEach(doc => {
const data = {
'taskId': doc.id,
'title': doc.data().title,
'quadrant': doc.data().quadrant
}
this.state.tasks.push(data)
})
commit('loadedTasks', true)
})
},
deleteTask ({ commit }, payload) {
db.collection('tasks').doc(payload).delete().then(() => {
this.state.tasks.pop(payload)
commit('deletedTask', true)
commit('loadedTasks', true)
}).catch(function (error) {
console.error('Error removing document: ', error)
commit('deletedTask', false)
})
}
},
// Getters: receive data from the store
getters: {
isAuthenticated (state) {
return state.user !== null && state.user !== undefined
}
}
})
컴포넌트(Vue app -> Home -> Grid -> Task List (이것) :
<template>
<v-card>
<v-card-title primary class="title">{{title}}</v-card-title>
<v-flex v-if="tasks.length > 0">
<v-slide-y-transition class="py-0" group tag="v-list">
<template v-for="(task, i) in tasks" v-if="task.quadrant === Id">
<v-divider v-if="i !== 0" :key="`${i}-divider`"></v-divider>
<v-list-tile :key="`${i}-${task.text}`">
<v-list-tile-action>
<v-checkbox v-model="task.done" color="info darken-3">
<div slot="label" :class="task.done && 'grey--text' || 'text--primary'" class="text-xs-right" v-text="task.title +' ('+ task.taskId +')'"></div>
</v-checkbox>
</v-list-tile-action>
<v-spacer></v-spacer>
<v-scroll-x-transition>
<v-btn flat icon color="primary" v-show="!deleteConfirmation" @click="deleteConfirmation = !deleteConfirmation">
<v-icon>delete</v-icon>
</v-btn>
</v-scroll-x-transition>
<v-scroll-x-transition>
<v-btn flat icon color="green" v-show="deleteConfirmation" @click="deleteConfirmation = !deleteConfirmation">
<v-icon>cancel</v-icon>
</v-btn>
</v-scroll-x-transition>
<v-scroll-x-transition>
<v-btn flat icon color="red" v-show="deleteConfirmation" @click="deleteConfirmation = !deleteConfirmation; deleteTask(task.taskId)">
<v-icon>check_circle</v-icon>
</v-btn>
</v-scroll-x-transition>
</v-list-tile>
</template>
</v-slide-y-transition>
</v-flex>
</v-card>
</template>
<script>
export default {
data () {
return {
deleteConfirmation: false
}
},
props: ['Id', 'title'],
computed: {
tasks () {
return this.$store.state.tasks
}
},
methods: {
deleteTask (taskId) {
console.log(taskId)
this.$store.dispatch('deleteTask', taskId)
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.container {
max-width: 1200px;
}
</style>
실제로 변이를 일으킬 수 있는 변이가 없습니다.tasks
예를 들어 어레이입니다.this.state.tasks.pop(payload)
에서 발생하다deleteTask
행동이지 돌연변이가 아니야
Vuex 스토어에서 실제로 상태를 변경하는 유일한 방법은 변환을 커밋하는 것입니다.https://vuex.vuejs.org/guide/mutations.html
따라서 새로고침 후 올바른 결과를 볼 수 있습니다.Firestore 구현은 정상이며 그 값을 업데이트합니다.업데이트 및 새로 가져온 항목이 표시됩니다.tasks
어레이는 새로고침 후이지만 Vuex 상태는 새로고침 전에 변경되지 않으므로 Vue의 표시는tasks
어레이는 그대로입니다.
이에 대한 해결책은 매우 간단합니다.
새 변환 생성:
REMOVE_FROM_TASKS (state, payload) {
// algorithm to remove, e. g. by id
state.tasks = state.tasks.filter(e => {
return e.id !== payload;
});
},
액션에 다음 변환을 사용합니다.
deleteTask ({ commit }, payload) {
db.collection('tasks').doc(payload).delete().then(() => {
commit('REMOVE_FROM_TASKS', payload)
commit('deletedTask', true)
commit('loadedTasks', true)
}).catch(function (error) {
console.error('Error removing document: ', error)
commit('deletedTask', false)
})
}
이제 삭제 시 DOM이 올바르게 업데이트됩니다.구성 요소의 구조를 조금 변경합니다.현재:Vue app -> Home -> Grid -> 태스크리스트 -> TaskListItem.아직 다음과 같은 문제가 발생하고 있습니다.항목을 추가하면 DOM이 갱신되지만, 예를 들어 다른 제목을 가진 여러 엔트리가 추가되면 Firestore에 올바르게 입력되지만 DOM에서는 완전히 새로고침할 때까지 동일한 엔트리가 표시됩니다.
아래 코드를 확인하십시오.
스토어:
import Vue from 'vue'
import Vuex from 'vuex'
// import firebase from 'firebase'
import router from '@/router'
import db from '@/db'
import firebase from '@/firebase'
Vue.use(Vuex)
export const store = new Vuex.Store({
state: {
appTitle: 'My Awesome App',
taskFormVisible: false,
addedTask: false,
loadedTasks: false,
deletedTasks: false,
user: null,
error: null,
loading: false,
tasks: [],
task: {
title: '',
description: '',
tags: [],
dueTime: '',
dueDate: '',
reminderFlag: Boolean,
quadrant: '',
userId: '',
timestamp: ''
}
},
// Mutations (synchronous): change data in the store
mutations: {
setUser (state, payload) {
state.user = payload
state.task.userId = firebase.auth().currentUser.uid
},
setError (state, payload) {
state.error = payload
},
setLoading (state, payload) {
state.loading = payload
},
addedTask (state, payload) {
state.addedTask = payload
},
loadedTasks (state, payload) {
state.loadedTasks = true
},
deletedTask (state, payload) {
state.deletedTask = payload
},
DELETE_TASK (state, payload) {
state.tasks = state.tasks.filter(task => {
return task.taskId !== payload
})
},
ADD_NEW_TASK (state, payload) {
// algorithm to remove, e. g. by id
// console.log(payload)
state.tasks.push(payload)
/* state.tasks = state.tasks.filter(e => {
return e.id !== payload
}) */
},
GET_TASKS (state, payload) {
state.tasks = payload
},
MAKE_TASKFORM_VISIBLE (state, payload) {
state.taskFormVisible = payload
}
},
// Actions (asynchronous/synchronous): change data in the store
actions: {
autoSignIn ({ commit }, payload) {
commit('setUser', { email: payload.email })
},
userSignUp ({ commit }, payload) {
commit('setLoading', true)
firebase.auth().createUserWithEmailAndPassword(payload.email, payload.password)
.then(firebaseUser => {
commit('setUser', { email: firebaseUser.user.email })
commit('setLoading', false)
router.push('/home')
commit('setError', null)
})
.catch(error => {
commit('setError', error.message)
commit('setLoading', false)
})
},
userSignIn ({ commit }, payload) {
commit('setLoading', true)
firebase.auth().signInWithEmailAndPassword(payload.email, payload.password)
.then(firebaseUser => {
commit('setUser', { email: firebaseUser.user.email })
commit('setLoading', false)
commit('setError', null)
router.push('/home')
})
.catch(error => {
commit('setError', error.message)
commit('setLoading', false)
})
},
userSignOut ({ commit }) {
firebase.auth().signOut()
commit('setUser', null)
router.push('/')
},
makeTaskformVisible ({ commit }) {
if (this.state.taskFormVisible === false) {
commit('MAKE_TASKFORM_VISIBLE', true)
} else {
commit('MAKE_TASKFORM_VISIBLE', false)
}
},
addNewTask ({ commit }, payload) {
db.collection('tasks').add({
title: payload.title,
userId: firebase.auth().currentUser.uid,
createdOn: firebase.firestore.FieldValue.serverTimestamp(),
description: payload.description,
dueDateAndTime: payload.dueTimestamp,
reminderFlag: payload.reminderFlag,
quadrant: payload.quadrant,
tags: payload.tags,
updatedOn: firebase.firestore.FieldValue.serverTimestamp()
})
.then(() => {
commit('ADD_NEW_TASK', payload)
})
.catch(error => {
commit('setError', error.message)
})
},
getTasks ({ commit }) {
// commit('loadedTasks', false)
db.collection('tasks').orderBy('createdOn', 'desc').get().then(querySnapshot => {
querySnapshot.forEach(doc => {
const data = {
'taskId': doc.id,
'title': doc.data().title,
'quadrant': doc.data().quadrant
}
this.state.tasks.push(data)
})
// commit('loadedTasks', true)
commit('GET_TASKS', this.state.tasks)
})
},
deleteTask ({ commit }, payload) {
db.collection('tasks').doc(payload).delete().then(() => {
commit('DELETE_TASK', payload)
}).catch(function (error) {
// console.error('Error removing document: ', error)
commit('setError', error.message)
})
}
},
// Getters: receive data from the store
getters: {
isAuthenticated (state) {
return state.user !== null && state.user !== undefined
}
}
})
작업 목록:
<template>
<ul>
<li>
<h4>{{title}}</h4>
</li>
<li v-for="task in tasks" :key="task.taskId" v-if="task.quadrant === Id" class="collection-item">
<task-list-item v-bind:task="task"></task-list-item>
</li>
</ul>
</template>
<script>
import TaskListItem from './TaskListItem'
export default {
components: {
'task-list-item': TaskListItem
},
data () {
return {
}
},
props: ['Id', 'title'],
computed: {
tasks () {
return this.$store.state.tasks
}
},
methods: {
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>
TaskListItem:
<template>
<div>{{task.title}} ({{task.taskId}})<v-spacer></v-spacer>
<v-scroll-x-transition>
<v-btn flat icon color="primary" v-show="!deleteConfirmation">
<v-icon>edit</v-icon>
</v-btn>
</v-scroll-x-transition>
<v-scroll-x-transition>
<v-btn flat icon color="primary" v-show="!deleteConfirmation" @click="deleteConfirmation = !deleteConfirmation">
<v-icon>delete</v-icon>
</v-btn>
</v-scroll-x-transition>
<v-scroll-x-transition>
<v-btn flat icon color="green" v-show="deleteConfirmation" @click="deleteConfirmation = !deleteConfirmation">
<v-icon>cancel</v-icon>
</v-btn>
</v-scroll-x-transition>
<v-scroll-x-transition>
<v-btn flat icon color="red" v-show="deleteConfirmation" @click="deleteConfirmation = !deleteConfirmation; deleteTask(task.taskId)">
<v-icon>check_circle</v-icon>
</v-btn>
</v-scroll-x-transition>
</li>
</div>
</template>
<script>
export default {
data () {
return {
deleteConfirmation: false
}
},
props: ['task'],
computed: {
},
methods: {
deleteTask (taskId) {
this.$store.dispatch('deleteTask', taskId)
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>
언급URL : https://stackoverflow.com/questions/52504091/vuejs-dom-not-updating-in-component
'programing' 카테고리의 다른 글
vuejs 앱에서 실행할 때 Axios 응답 헤더에 데이터가 누락됨 (0) | 2022.07.21 |
---|---|
사용자 로그 vue.js의 이름을 유지하려면 어떻게 해야 합니까? (0) | 2022.07.21 |
특정 Array List 항목을 가져옵니다. (0) | 2022.07.21 |
Java에서 메서드 실행 시간을 어떻게 측정합니까? (0) | 2022.07.21 |
vuex 모듈에서 getter를 정의하는 방법 (0) | 2022.07.21 |