Vue.js: 메서드에서 계산된 속성을 사용하면 정의되지 않은 오류가 반환됩니다.
vuex에서 상태를 가져오는 계산된 속성이 있습니다.vuex 내부에서는 api에서 일부 데이터를 가져오기 위해 axios를 사용하여 상태를 설정합니다.문제는 메서드 내에서 이 계산된 속성을 사용하려고 하면 정의되지 않은 오류가 발생한다는 것입니다.데이터가 vuex 스토어에 설정되기 전에 사용하려고 하기 때문입니다.그렇다면 메서드에 사용하기 전에 boardColumnData가 설정되었는지 확인하려면 어떻게 해야 합니까?
오류:
Error in mounted hook: "TypeError: Cannot read property 'total' of undefined"
TypeError: Cannot read property 'total' of undefined
앱 차트.가치관
<template>
<div id="chart_section">
<div id="charts" v-if="boardColumnData">
<DoughnutChart :chart-data="datacollection" :options="chartOptions" class="chart"></DoughnutChart>
<button v-on:click="fillData">Fill Data</button>
</div>
</template>
<script>
import DoughnutChart from './DoughnutChart';
import { mapGetters } from 'vuex';
export default {
components: {
DoughnutChart
},
computed: {
...mapGetters(['boardColumnData']),
},
data() {
return {
datacollection: null,
chartOptions: null
}
},
mounted() {
this.fillData();
},
methods: {
fillData() {
this.datacollection = {
datasets: [{
data: [this.boardColumnData[0].total.$numberDecimal, this.boardColumnData[1].total.$numberDecimal, this.boardColumnData[2].total.$numberDecimal, this.boardColumnData[3].total.$numberDecimal],
backgroundColor: [
'#83dd1a',
'#d5d814',
'#fdab2f',
'#1ad4dd'
],
borderColor: [
'#83dd1a',
'#d5d814',
'#fdab2f',
'#1ad4dd'
],
}]
};
this.chartOptions = {
responsive: true,
maintainAspectRatio: false,
};
}
}
}
</script>
도넛 차트.vue
<script>
import { Doughnut, mixins } from 'vue-chartjs';
const { reactiveProp } = mixins;
export default {
extends: Doughnut,
mixins: [reactiveProp],
props: ['chartData', 'options'],
mounted () {
this.renderChart(this.chartdata, this.options)
}
}
</script>
vuex 스토어:
import axios from 'axios';
const state = {
defaultPosts: [],
boardPosts: [],
boardColumnData: [],
};
const getters = {
boardColumnData: state => state.boardColumnData,
};
const actions = {
getAllBoardPostData: ({commit}) => {
function getBoardColumns() {
return axios.get('http://localhost:5000/api/summary-board/columns');
}
function getBoardPosts() {
return axios.get('http://localhost:5000/api/summary-board/posts');
}
axios.all([getBoardColumns(), getBoardPosts()])
.then(axios.spread((columnData, postData) => {
let rawPosts = postData.data;
let columns = columnData.data;
let posts = Array.from({length: columns.length}, () => []);
rawPosts.forEach((post) => {
// If column index matches post column index value
if(posts[post.column_index]){
posts[post.column_index].push(post);
}
});
columns.forEach((column, index) => {
let columnTotal = 0;
posts[index].forEach((post) => {
columnTotal += post.annual_value;
});
column.total.$numberDecimal = columnTotal;
});
commit('setBoardColumns', columns);
commit('setBoardPosts', posts);
commit('setDefaultPosts', posts);
}))
.catch(error => console.log(error));
}
};
const mutations = {
setDefaultPosts: (state, payload) => {
state.defaultPosts = payload;
},
setBoardPosts: (state, payload) => {
state.boardPosts = payload;
},
setBoardColumns: (state, payload) => {
state.boardColumnData = payload;
}
};
export default {
state,
getters,
actions,
mutations
};
boardColumnData는 다음과 같습니다.
[
{
"name": "Opportunities",
"percentage": {
"$numberDecimal": "0"
},
"total": {
"$numberDecimal": 70269
}
},
{
"name": "Prospects",
"percentage": {
"$numberDecimal": "0.25"
},
"total": {
"$numberDecimal": 0
}
},
{
"name": "Proposals",
"percentage": {
"$numberDecimal": "0.5"
},
"total": {
"$numberDecimal": 5376
}
},
{
"name": "Presentations",
"percentage": {
"$numberDecimal": "0.75"
},
"total": {
"$numberDecimal": 21480
}
},
{
"name": "Won",
"percentage": {
"$numberDecimal": "1"
},
"total": {
"$numberDecimal": 0
}
},
{
"name": "Lost",
"percentage": {
"$numberDecimal": "1"
},
"total": {
"$numberDecimal": 0
}
},
{
"name": "No Opportunity",
"percentage": {
"$numberDecimal": "1"
},
"total": {
"$numberDecimal": 0
}
}
]
Vue는 데이터가 스토어에 도착하면 구성 요소 업데이트의 반응성을 처리할 수 있어야 하며, 구성 요소에 올바르게 전달하기 때문에 구성 요소의 반응성을 높이기 위해 약간의 조정만 하면 된다고 생각합니다.제가 옮길게요datacollection
계산된 속성으로, 그것은 스토어의 정보에만 의존하기 때문입니다.boardColumnData
그리고 나서 당신의 것을 옮겨 주시겠습니까?chartOptions
처음에 정의해야 하나요, 단지 정적인 데이터이기 때문에?
export default {
data: () => ({
// datacollection: null, // remove this
chartOptions: {
responsive: true,
maintainAspectRatio: false,
},
},
//...
computed: {
...mapGetters([
'boardColumnData'
]),
datacollection() { // Property added to computed properties
if (this.boardColumnData.length) { // - check for boardColumnData before using it
return {
datasets: [{
data: [this.boardColumnData[0].total.$numberDecimal, this.boardColumnData[1].total.$numberDecimal, this.boardColumnData[2].total.$numberDecimal, this.boardColumnData[3].total.$numberDecimal],
backgroundColor: [
'#83dd1a',
'#d5d814',
'#fdab2f',
'#1ad4dd'
],
borderColor: [
'#83dd1a',
'#d5d814',
'#fdab2f',
'#1ad4dd'
],
}]
};
} else {
return null;
}
}, // end dataCollection()
},
//... rest of component...
그리고 나서 당신의 템플릿에서, 단지 확인하세요.datacollection
값이 있습니다.예를 들어:
<template>
<div id="chart_section">
<div id="charts" v-if="datacollection">
<DoughnutChart
:chart-data="datacollection"
:options="chartOptions"
class="chart"
/>
</div>
</div>
</template>
마운트된 후크에서 비동기 대기를 사용하여 fillData 메서드를 호출하기 전에 데이터를 설정할 수 있습니다.
앱 차트에 있습니다.vue, 마운트된() 후크 안에서 getAllBoardPostData()를 호출합니다.
`async mounted() {
await this.$store.dispatch('getAllBoardPostData')
this.fillData();
},`
이렇게 하면 구성 요소가 로드될 때와 fillData() 메서드가 호출되기 전에 api에서 데이터를 가져와 저장소를 채웁니다.
언급URL : https://stackoverflow.com/questions/61349241/vue-js-using-computed-property-in-method-returns-undefined-error
'sourcecode' 카테고리의 다른 글
"="와 "<-" 할당 연산자의 차이점은 무엇입니까? (0) | 2023.06.27 |
---|---|
개체와 레코드 유형의 차이 (0) | 2023.06.27 |
Oracle SYS 계정과 SYSTEM 계정의 차이점은 무엇입니까? (0) | 2023.06.27 |
다른 사용자의 스키마에 부여된 권한을 확인하는 방법 (0) | 2023.06.27 |
Python 패키지의 종속성을 찾는 방법 (0) | 2023.06.27 |