請問各位大大,我卡這個卡了兩天
爬不到解決方案,不知道是我理解錯誤,還是根本寫錯?
懇求各位大大幫幫忙解惑,或者給我點提示,感謝!
問題發生:
第一次載入網站用 nuxt-link 轉頁時,$store 還沒有任何資料,導致 html 無法渲染。
但是換其他頁再回來問題就解決了,由此我猜測就是第一次載入時,$store 還沒有資料,所以加載錯誤。
我以為是非同步/同步的問題,因為我直接使用了 mutations,但我改成用 dispatch 來 commit 問題還是一樣發生噎-_-...
接著我把步驟 console 出來(以下圖片),可以看到問題發生在 Props 傳入是 null,所以跟著渲染就報錯,而 Fetch commit 的資料是在 mounted 之後才拿得到。
我發現使用,在 Create 時,直接跟 $store 拿東西是拿得到的
created() {
console.log('Page Created', this.$store.state.pageHome)
}
但如果這時候改成再取得子資料反而會 null,這不知道為什麼?
created() {
console.log('Page Created', this.$store.state.pageHome.homeSliders)
}
接著我嘗試在 Created 時把資料放到 Data,Console this.firstData,會變成 null,而直接 Console $store 則可以拿到資料,我也搞不懂這裡?
created() {
this.firstData = this.$store.state.pageHome
},
以下附上我的程式
page/index.vue
<template>
<div class="page_home">
<section>
<CaroTransform :carodata="homeData.homeSliders" />
</section>
</template>
import CaroTransform from '~/components/carousel/CaroTransform'
export default {
async fetch () {
await this.$axios({
method: API.pageHome.method,
url: API.pageHome.url
}).then((res) => {
this.$store.commit('page_home', {
...res.data
})
}).catch((err) => {
console.error('error', err)
})
},
created() {
console.log('Page Created', this.$store.state.pageHome)
},
mounted () {
console.log('Page Mounted', this.$store.state.pageHome)
}
}
store/index.js
export const state = () => ({
pageColor: 'black',
header: {
isOpen: false,
topnavs: [],
btmnavs: [],
headnavs: [],
lang: []
},
footer: {},
pageHome: {
homeSliders: [],
events: [],
activities: [],
announce: [],
posts: []
},
pageAbout: {}
})
export const mutations = {
page_home: (state, payload) => {
state.pageHome.homeSliders = payload
console.log('Fetch Mutations Commit', payload)
}
}
components/carousel/CaroTransform.vue
<template>
<div
:style="{opacity: caroOpacity}"
class="caro_transform">
<div
class="container"
:data-disp="require('~/assets/img/disp.png')"
:data-hover="require('~/assets/img/dispHover.png')" />
<h1>
<span class="din">{{ carodata[0].date }}</span>
<strong>{{ carodata[0].title }}</strong>
</h1>
<div class="imgs">
<img
v-for="(slide, idx) in carodata"
:key="idx"
:data-title="slide.title"
:data-date="slide.date"
:data-to="slide.to"
:src="slide.img.src"
:alt="slide.img.alt">
</div>
<div class="caro_checkout">
<i class="icon-arrow-right" />
<i class="icon-arrow-right" />
</div>
<div class="caro_dots">
<i
v-for="(dot, dotidx) in carodata"
:key="dotidx"
:data-id="dotidx" />
<span class="din">/ 01</span>
</div>
<div class="caro_deco">
<p class="din">Promotion</p>
</div>
</div>
</template>
import { ImgTransform } from '~/assets/js/effects.js'
export default {
name: 'CaroTransform',
props: {
carodata: {
type: Array,
default: null
}
},
data () {
return {
caroOpacity: 1,
firstData: [],
distortion: null
}
},
beforeDestroy () {
this.distortion = null
},
created() {
console.log('Component props 傳入', this.carodata)
},
mounted() {
this.distortion = new ImgTransform({
debug: false,
duration: 1.5,
uniforms: {![](http://)
intensity: { value: 1, type: 'f', min: 0.0, max: 3 }
}
})
}
}
</script>
這很明顯呀!
請試著從錯誤訊息中找答案:
1.檔案是 CaroTransform.vue
2.從錯誤就能得知某個 null
值的屬性有錯誤,讀取 0
3.就是你的 carodata 變數問題
4.為何是 null 呢? 可能你傳入 null, 不然就是變成了你 props 設置的預設值 null 了
接著應該就能找到你要的答案了~ (如果你懂 props 的話)
ps: 你有一個觀念是錯的: props type 是 Array, default 卻是 null...
還有請記得開發時搭配 ESLint:
就能避免出現: props type 是 Array, default 卻是 null
一直都有使用 ESLint 的習慣
因為 default 還沒寫就先暫時放個 null..
感謝大大協助給的方向,因此找到解決方案了。
確實是 ajax 拿資料的同步時間問題。在另外爬文找到此篇。 https://ithelp.ithome.com.tw/articles/10224501
最後這樣解決
<CaroTransform
v-if="$store.state.pageHome.homeSliders"
:carodata="$store.state.pageHome.homeSliders" />
剛好也不用幫 threejs 寫等資料齊全再渲染XD..
okay