반응형
Vuex 글로벌 상태 변경이 Nuxt의 v-for 루프에서 리렌더 구성 요소를 트리거하지 않음
나는 Vue.js에서 아동 구성 요소 리렌더와 함께 vuex 글로벌 상태 조합을 사용하는 것이 어렵다.글로벌 상태는 변이되지만 데이터를 v-for 루프에서 다시 렌더링하지 않는다.
모든 데이터 목록이 렌더링되지만, 새로운 데이터가 변경될 때 /blog의 구성요소는 데이터의 데이터를 변경하지 않는다.
몇 가지 코드:
/store/index.js
export const state = () => ({
allData: [],
})
export const getters = {
getAllData: (state) => state.allData,
}
export const mutations = {
GET_DATAS(state, payload) {
state.allData = payload
},
UPDATE_DATA(state, payload) {
const item = state.allData[payload.index]
Object.assign(item, payload)
},
}
export const actions = {
getDatas({ commit, state }, payload) {
return fetch(`URL_FETCH`)
.then((data) => data.json())
.then((data) => {
commit('GET_DATAS', data)
})
.catch((err) => console.log(err))
},
updateData({ commit, state }, payload) {
commit('UPDATE_DATA', payload)
},
}
에/layouts/default.vue
beforeCreate() {
this.$store.dispatch('getDatas').then(() => {
connectSocket()
})
},
methods: {
connectSocket() {
// connect & received message from socket
// received message from socket
this.$root.$emit('updateData', {
index: 12,
price: 34,
change: 56,
percent: 78,
})
},
},
에/pages/blog/index.vue
<template>
<div>
<div
v-for="index in getAllData"
:key="index.name"
class="w-100 grid-wrapper"
>
<div>{{ index.price }}</div>
<div>{{ index.change }}</div>
<div>{{ index.percent }}</div>
</div>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
data() {
return {}
},
computed: {
...mapGetters(['getAllData']),
},
mounted() {
this.$root.$on('updateData', (item) => {
this.$store.dispatch('updateData', {
index: item.index,
price: item.price,
percent: item.percent,
change: item.change,
})
})
},
}
</script>
다음은 Vuex를 사용하고 데이터를 Nuxt 앱에 효율적으로 로드하는 방법에 대한 전체 예(주관적이지만 모범 사례를 사용함)이다.
/pages/index.vue
<template>
<div>
<main v-if="!$fetchState.pending">
<div v-for="user in allData" :key="user.id" style="padding: 0.5rem 0">
<span>{{ user.email }}</span>
</div>
</main>
<button @click="fakeUpdate">Update the 2nd user</button>
</div>
</template>
<script>
import { mapState, mapActions } from 'vuex'
export default {
data() {
return {
mockedData: {
name: 'John Doe',
username: 'jodoe',
email: 'yoloswag@gmail.com',
phone: '1-770-736-8031 x56442',
website: 'hildegard.org',
},
}
},
async fetch() {
await this.setAllData()
},
computed: {
...mapState(['allData']),
},
methods: {
...mapActions(['setAllData', 'updateData']),
fakeUpdate() {
this.updateData({ index: 1, payload: this.mockedData })
},
},
}
</script>
/store/index.js
import Vue from 'vue'
export const state = () => ({
allData: [],
})
export const mutations = {
SET_ALL_DATA(state, payload) {
state.allData = payload
},
UPDATE_SPECIFIC_DATA(state, { index, payload }) {
Vue.set(state.allData, index, payload)
},
}
export const actions = {
async setAllData({ commit }) {
try {
const httpCall = await fetch('https://jsonplaceholder.typicode.com/users')
const response = await httpCall.json()
commit('SET_ALL_DATA', response)
} catch (e) {
console.warn('error >>', e)
}
},
updateData({ commit }, { index, payload }) {
commit('UPDATE_SPECIFIC_DATA', { index, payload })
},
}
반응형
'Programing' 카테고리의 다른 글
C 및 C++에서 f()와 f(void)의 차이를 한 번, 그리고 전체적으로 이해 (0) | 2022.05.24 |
---|---|
vuex에 저장된 공리에서 response.data 정의되지 않음 가져오기 (0) | 2022.05.24 |
java.net.URLEncoder.encode(스트링)가 더 이상 사용되지 않는데, 그 대신 무엇을 사용해야 하는가? (0) | 2022.05.24 |
[부유 경고]:v-on 핸들러 오류: "TypeError: Object(...) (...).httpsCallable(...). 그러면 함수가 아님" (0) | 2022.05.23 |
링크된 목록에 노드를 추가할 때 이중 포인터를 사용하는 이유는? (0) | 2022.05.23 |