iT邦幫忙

0

Nuxtjs router 換頁時抓不到 Fetch 資料造成 Component 無法渲染

請問各位大大,我卡這個卡了兩天
爬不到解決方案,不知道是我理解錯誤,還是根本寫錯?
懇求各位大大幫幫忙解惑,或者給我點提示,感謝!

問題發生:
第一次載入網站用 nuxt-link 轉頁時,$store 還沒有任何資料,導致 html 無法渲染。
但是換其他頁再回來問題就解決了,由此我猜測就是第一次載入時,$store 還沒有資料,所以加載錯誤。

我以為是非同步/同步的問題,因為我直接使用了 mutations,但我改成用 dispatch 來 commit 問題還是一樣發生噎-_-...

接著我把步驟 console 出來(以下圖片),可以看到問題發生在 Props 傳入是 null,所以跟著渲染就報錯,而 Fetch commit 的資料是在 mounted 之後才拿得到。
https://ithelp.ithome.com.tw/upload/images/20211224/20114904WD9qiiF8jg.png

我發現使用,在 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>

圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 個回答

1
Vision
iT邦新手 5 級 ‧ 2021-12-26 04:14:20
最佳解答

這很明顯呀!
請試著從錯誤訊息中找答案:
1.檔案是 CaroTransform.vue
2.從錯誤就能得知某個 null 值的屬性有錯誤,讀取 0
3.就是你的 carodata 變數問題
4.為何是 null 呢? 可能你傳入 null, 不然就是變成了你 props 設置的預設值 null 了

接著應該就能找到你要的答案了~ (如果你懂 props 的話)

ps: 你有一個觀念是錯的: props type 是 Array, default 卻是 null...

Vision iT邦新手 5 級 ‧ 2021-12-26 04:19:08 檢舉

還有請記得開發時搭配 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..

Vision iT邦新手 5 級 ‧ 2021-12-27 10:30:42 檢舉

okay

我要發表回答

立即登入回答