在我们使用 Nuxt 框架的时候,往往在 Plugins or Middleware 中用到一些参数($axios、app、store、redirect...
)。很多喜爱研究的小伙伴不知道他们到底如何来的。
- 如中间件中:
// 中间件
export default async function ({ app, $axios, store, error, redirect, req }) {
if (req && req.url === '/__webpack_hmr') return
await store.dispatch('auth/updateToken')
if (!store.state.auth.user.user_uuid) {
return redirect('/auth/login')
}
}
- 再如 Axios 拦截 Plugin 中:
// Axios 拦截
export default ({ redirect, $axios }) => {
$axios.onRequest(config => {});
$axios.onResponse(res => {});
$axios.onError(error => {})
};
今天就来盘一盘 Nuxt Build 好后的源码,看看到底是从哪里传递过来的这些参数。
首先 Nuxt 会在 createApp 里有个根实例对象 app
,app
中有个 context
属性至关重要。
Nuxt 一开始向 app.context
中设置了一些默认属性:
参考 .nuxt/index.js
.nuxt 文件夹见项目根目录
// Set context to app.context
await setContext(app, {
route,
next,
error: app.nuxt.error.bind(app),
store,
payload: ssrContext ? ssrContext.payload : undefined,
req: ssrContext ? ssrContext.req : undefined,
res: ssrContext ? ssrContext.res : undefined,
beforeRenderFns: ssrContext ? ssrContext.beforeRenderFns : undefined
})
并且在 setContext 中还设置了 redirect
属性:
参考 .nuxt/utils.js
export async function setContext(app, context) {
// ...
app.context.redirect = function (status, path, query) {
app.context._redirected = true // Used in middleware
// if only 1 or 2 arguments: redirect('/') or redirect('/', { foo: 'bar' })
let pathType = typeof path
if (typeof status !== 'number' && (pathType === 'undefined' || pathType === 'object')) {
query = path || {}
path = status
pathType = typeof path
status = 302
}
if (pathType === 'object') {
path = app.router.resolve(path).href
}
// ...
}
// ...
}
接着他会处理一些 Plugin,比如 axios(注意此处不是我们自己封装的 axios 拦截 plugin,而是 nuxt 集成的官方 axios)
参考 .nuxt/index.js
// Plugin execution
if (typeof nuxt_plugin_axios_cc389c80 === 'function') await nuxt_plugin_axios_cc389c80(app.context, inject)
此时他会将 app.context
传入到 axios 的 plugin 里面,并且在 axios 的 plugin 里会将 $axios 也设置到 app.context 里面。
参考 .nuxt/axios.js
// axios.js (ctx 即传入的 app.context)
export default (ctx, inject) => {
// ...
// Inject axios to the context as $axios
ctx.$axios = axios
}
接下来他会处理我们写的 Axios 拦截 plugin,并且将 app.context
传递过去,此时的 app.context
就包含了上面所说的各种各样的参数。
参考 .nuxt/index.js
if (process.browser) {
if (typeof nuxt_plugin_axios_6613fe6f === 'function') await nuxt_plugin_axios_6613fe6f(app.context, inject)
}