Lala的前端大補帖

歡迎一起鑽研前端技術😊

0%

Nuxt 生命週期及執行順序

Imgur

因為 Nuxt 又有牽扯到 Server 的部分,所以 Nuxt 的生命週期會跟 Vue 的 Nuxt 有一點不太一樣

nuxt

asyncData

在 Server 執行階段,瀏覽器渲染之前的生命週期,Server 端處理非同步時,如 API 需要做到 SEO,需在 asyncData 處理,asyncData 只會執行一次。
🔸 asyncData 只有在頁面選染前才會執行,所以只有在 pages 裡的 component 才能使用 asyncData,如其他資料夾的 component 也需要 SEO,需把資料往下傳遞或是存進 Vuex 渲染
🔸 不能使用 this,在 Server 階段執行還沒產生 Vue 實體
🔸 不能使用瀏覽器有關的 API,如 windiw.alert、document 等,因在 Server 階段執行還沒建構出網站內容

asyncData 的內容如跟 data 同名 ,asyncData 會覆蓋掉 data

1
2
3
<div>
{{name}} // Bobee
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
export default {
asyncData() {
const name = 'Bobee';
return {
name,
};
},
data() {
return {
name: 'Lala',
};
},
};

如想修改 asyncData 裡面的值,由於 asyncData 只會執行一次,所以不能被其他 methods 給抓取,直接在 data 新增一樣的內容,再去做控制就可以改變了。

1
2
3
<div @click="name = 'Lala'">
{{name}}
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
export default {
asyncData() {
const name = 'Bobee';
return {
name,
};
},
data() {
return {
name: '',
};
},
};

官方有提到,想確保 API 的資料已經回來,可使用 async await 的方式

1
<img v-for="item in res" :key="item.url" :src="item.url" />
1
2
3
4
5
6
7
8
async asyncData() {
const res = await axios.get(
"https://vue-lessons-api.herokuapp.com/photo/list"
);
return {
res: res.data,
};
}

打開檢查原始碼將會發現,這些圖片都被 Server render 到畫面上來了

fetch

nuxt 2.12+的新功能,fetch 跟 asyncData 一樣都是由 Server 端執行,並 render 到畫面上來,不過有以下幾點跟 asyncData 不太一樣
🔸 可在任何一個 component 執行
🔸 可取得 this,因在 created 之後
🔸 不行 return 資料到 template,只能透過覆寫的方式

1
{{name}} // 這邊會被覆寫為Bobee
1
2
3
4
5
6
7
8
data() {
return {
name: "Lala",
};
},
fetch() {
this.name = "Bobee";
}

fetchOnServer

1
fetchOnServer: false;

如果把 fetchOnServer 設定成 false,那這樣 fetch 就只會在 client 端被執行,在檢視原始碼裡面就不會找到 fetch 的資料


keep-alive
可以把內容緩存起來,不用重複 render 造成效能問題,只有用 keep-alive 時才可以調用 activated 生命週期,每當重新進入頁面都會觸發 activated


Fetch 提供的參數
$fetchState.pending ( true | false ) : 讓你在 client 端去判斷 API 載入完成沒有
$fetchState.error ( null | { } ) : 當發生畫面上的內容發生錯誤的時候,去判斷錯誤的部分
$fetchState.timestamp ( Integer ) : 顯示最後一次非同步處理的時間

範例:
layouts/default.vue

1
2
3
<NuxtLink to="/">HOME</NuxtLink>
<NuxtLink to="/about">About</NuxtLink>
<Nuxt keep-alive />

pages/index.vue

1
2
3
<h1 v-if="$fetchState.pending">Loading...</h1>
<h1 v-if="$fetchState.error">ERROR {{$fetchState.error}}</h1>
<img v-for="item in res" :key="item.url" :src="item.url" />
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import axios from 'axios';
export default {
data() {
return {
res: [],
};
},
fetchOnServer: false,
activated() {
// 判斷上次執行的 timestamp 跟現在的時間如相差超過 10 秒,將會重新執行 fetch
if (this.$fetchState.timestamp <= Date.now() - 10000) {
this.$fetch();
}
},
async fetch() {
this.res = await axios.get('https://vue-lessons-api.herokuapp.com/photo/list').then((res) => res.data);
},
};

生命週期執行順序

將生命週期 console.log 出來

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
asyncData() {
console.log("asyncData");
},
beforeCreate() {
console.log("beforeCreate");
},
created() {
console.log("created");
},
mounted() {
console.log("mounted");
},
fetch() {
console.log("fetch");
}

順序為
asyncData → beforeCreatecreated → fetch → beforeCreatecreated → mounted
將會發現 beforeCreate、created 會被執行兩次,原因是 Server 端和 Client 端都會有 beforeCreate、created,所以需要再做一些判斷或處理,不然有可能重複的東西會被執行兩次。



🚀線上課程分享

線上課程可以加速學習的時間,省去了不少看文件的時間XD,以下是我推薦的一些課程
想學習更多關於前後端的線上課程,可以參考看看。

Hahow

Hahow 有各式各樣類型的課程,而且是無限次數觀看,對學生或上班族而言,不用擔心被時間綁住



六角學院

如果你是初學者,非常推薦六角學院哦!
剛開始轉職也是上了六角的課,非常的淺顯易懂,最重要的是,隨時還有線上的助教幫你解決問題!


Udemy

Udemy 裡的課程非常的多,品質普遍不錯,且價格都滿實惠的,CP值很高!
也是很多工程師推薦的線上課程網站。
❤️