Nuxt.js 扩展了 Vue.js,增加了一个叫 asyncData 的方法,使得我们可以在设置组件的数据之前能异步获取或处理数据。
asyncData 方法
Nuxt.js 提供了几种不同的方法来使用 asyncData 方法,你可以选择自己熟悉的一种来用:
- 返回一个 Promise, nuxt.js 会等待该Promise被解析之后才会设置组件的数据,从而渲染组件.
- 使用 async 或 await
- 使用 回调函数
//返回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 }
}
}
//使用 回调函数
export default {
asyncData({ params }, callback) {
axios.get(`https://my-api/posts/${params.id}`).then(res => {
callback(null, { title: res.data.title })
})
}
}
使用 asyncData 获取异步数据的示例:
// pages/some-page.vue
export default {
async asyncData(context) {
// 可以访问上下文对象,例如从上下文获取请求头或传递的数据
// context.req, context.res, context.params, context.query
// 请检查您是否在服务器端
//1、 使用 req 和 res
if (process.server) {
return { host: req.headers.host }
}
//2、访问动态路由数据
//您可以使用注入asyncData 属性的context对象来访问动态路由数据。
//例如,可以使用配置它的文件或文件夹的名称访问动态路径参数。
//所以,如果你定义一个名为_slug.vue的文件,
//您可以通过context.params.slug来访问它。
const slug = context.params.slug // When calling /abc the slug will be "abc"
return { slug }
//3、监听 query 参数改变
// 默认情况下,query 的改变不会调用asyncData方法。如果要监听这个行为,
//例如,在构建分页组件时,您可以设置应通过页面组件的watchQuery属性监听参数。
export default {
watchQuery: ['page']
}
// 调用 API 获取数据
const dataFromApi = await fetchDataFromApi();
// 返回的数据会作为组件的属性
return {
dataFromApi
};
}
}
使用生命周期钩子获取异步数据
如果你只需要在客户端获取数据,或者想要在组件的其它生命周期钩子中处理数据,你可以使用 Vue 的生命周期钩子,如 created 或 mounted。
// components/SomeComponent.vue
export default {
data() {
return {
dataFromApi: null
};
},
async created() {
this.dataFromApi = await this.fetchDataFromApi();
},
methods: {
async fetchDataFromApi() {
// 调用 API 获取数据
// 这里可以使用 axios, fetch 等 HTTP 客户端
const response = await fetch('https://api.example.com/data');
const data = await response.json();
return data;
}
}
}
客户端导航和数据保持
如果你的应用支持客户端路由导航,并且你希望在客户端导航时保持异步数据,你可以使用 Nuxt.js 的 beforeRouteUpdate 钩子:
export default {
// ... 省略其他代码 ...
beforeRouteUpdate(to, from, next) {
if (to.path !== from.path) {
this.fetchDataFromApi().then(data => {
this.dataFromApi = data;
});
}
next();
}
}