asyncData
簡介
asyncData 可以用來在客戶端載入 Data 資料之前對其做一些處理,也可以在此發起非同步請求,提前設定資料,這樣在客戶端載入頁面的時候,就會直接載入提前渲染好並帶有資料的 DOM,完成服務端渲染,有助於搜尋引擎的抓取。
注意事項:
- 由於在客戶端建立例項化之前載入,所以不能使用 this,鉤子提供一個引數,可以獲取上下文物件({isDev, route, store, env, params, query, req, res, redirect, error}等),從而做一些簡單操作。
- 只能在路由頁面元件中使用(每次載入頁面都會呼叫),在自定義元件中無效。
- 返回的資料最終將與 data 資料合併,為了保證不發生頁面渲染錯誤,返回的鍵應事先在 data 裡宣告好(如果 template 中沒有使用所需屬性,則並不必宣告)。
- 鉤子在路由轉換期間解析,所以在 return 之前會一直等待內部邏輯處理,阻滯頁面載入。如果要丟擲異常,可以使用引數提供的 error 方法。
使用方式 (Javascript)
按照官網說明 asyncData 有三種使用方式,
使用示例:
-
返回 Promise 物件的方式
export default {
asyncData({ params }) {
return axios.get(`https://my-api/posts/${params.id}`).then(res => {
return { title: res.data.title };
});
}
};
-
使用 async/await 的方式
export default {
async asyncData({ params }) {
const { data } = await axios.get(`https://my-api/posts/${params.id}`);
return { title: data.title };
}
};
-
使用回撥函式的方式(v2.12 棄用)
export default {
asyncData({ params }, callback) {
// asyncData提供兩個引數(已棄用)
axios.get(`https://my-api/posts/${params.id}`).then(res => {
callback(null, { title: res.data.title });
});
}
};
使用方式 (Typescript)
Nuxt 的 ts 版元件,有三種構建風格,
使用示例:
-
選項式 API
export default Vue.extend({
// async/await方式
async asyncData({ params }) {
const { data } = await axios.get(`https://my-api/posts/${params.id}`);
return { title: data.title };
}
// Promise方式
/* asyncData({ params }) {
return axios.get(`https://my-api/posts/${params.id}`).then(res => {
return { title: res.data.title }
})
}, */
});
-
類式元件
類式元件應在裝飾器內傳入該方法,而不是在 Class 內使用。
import { Component, Vue } from "vue-property-decorator";
@Component({
async asyncData({ params }) {
const { data } = await axios.get(`https://my-api/posts/${params.id}`);
return { title: data.title };
}
})
export default class PageIndex extends Vue {
title: string;
}
-
組合式 API(v3.0 以上)
import { defineComponent, ref } from "@vue/composition-api";
import { useAsyncData } from "#app";
export default defineComponent({
async setup() {
const { data } = await useAsyncData("count", () => $fetch("/api/count"));
return {
title: data.title
};
}
});
fetch
簡介
舊版本的 fetch 在元件例項化之前執行,無法使用 this,如同 asyncData,提供了可查詢長下文的引數,且亦只能在頁面級元件中使用,並且只能通過上下文引數操作 store 狀態的資料,而不能設定或合併 data 資料。
注:由於 fetch 鉤子的功能在 nuxt v2.12 以上版本作了較大調整,所以下文只記錄新的使用方式。
fetch 用來在元件載入時預先提取資料,執行於元件例項建立之後(created)頁面渲染完成之前(mounted),並且可以用於任何元件(包括路由頁面或自定義元件)和隨時通過$fetch 方法主動更新資料。
使用方式
預設選項式元件:
export default {
fetchOnServer: false, //可以通過內建的fetchOnServer屬性,來關閉服務端fetch行為。
async fetch() {
const { data } = await axios.get(
`https://my-api/posts/${this.$route.params.id}`
);
this.title = data.title;
}
};
Typescript 類式元件:
import { Component, Vue } from "vue-property-decorator";
@Component
export default class PageBarIndex extends Vue {
async fetch(this: PageBarIndex) {
const { data } = await axios.get(
`https://my-api/posts/${this.$route.params.id}`
);
this.title = data.title;
}
}
asyncData 和 fetch 的區別
- 元件限制
- asyncData 僅限於頁面級元件。
- fetch 可用於任意元件。
- 獲取上下文
- asyncData 不可以使用 this,只能通過回撥引數獲取上下文物件。
- fetch 可以使用 this。
- 資料操作
- asyncData 通過 return 合併 data 資料。
- fetch 可以使用 this 直接修改賦值。
- 呼叫時機
- asyncData 只在頁面建立前呼叫。
- fetch 在頁面例項建立後呼叫,並可以通過$fetch 方法隨時觸發,$fetchState.timestam 屬性可以獲取最後一次觸發的時間戳。
- 錯誤處理
- asyncData 通過 error 引數丟擲錯誤,但並不會在頁面顯示異常。
- fetch 可以使用 throw new Error()來丟擲異常,在頁面呼叫$fetchState.error 方法獲取異常狀態。
- 頁面渲染
- asyncData 在頁面建立前填充資料。
- fetch 可通過 fetchOnServer 屬性設定是否允許在服務端獲取資料,設定為 false 將可以在渲染資料時通過$fetchState.pendinding 獲取載入狀態。