Open Echo-mz opened 2 years ago
中间件可以是异步的。为此,请返回 a Promise 或使用 async/await 中间件middleware/stats.js
import http from 'http'
export default function ({ route }) {
return http.post('http://my-stats-api.com', {
url: route.fullPath
})
}
然后在 nuxt.config.js,使用 router.middleware 配置项
export default {
router: {
middleware: 'stats'
}
}
每次路由更改都会调用中间件pages/index.vue /layouts/defalt.vue
export default {
middleware: ['auth', 'stats']
}
您可以通过在middleware/ 目录中创建一个文件来创建命名中间件 ,文件名将是中间件名称middleware/authenticated.js
export default function ({ store, redirect }) {
// If the user is not authenticated
if (!store.state.authenticated) {
return redirect('/login')
}
}
使用当前中间件
<template>
<h1>Secret page</h1>
</template>
<script>
export default {
middleware: 'authenticated'
}
</script>
如果只需要为特定页面使用中间件,则可以直接为其使用函数(或函数数组):
<template>
<h1>Secret page</h1>
</template>
<script>
export default {
middleware({ store, redirect }) {
// If the user is not authenticated
if (!store.state.authenticated) {
return redirect('/login')
}
}
}
</script>
路由更改时,首先依次调用调用项目中间件,直至完成,接着Vue.use(Router)
中间件功能可以执行以下任务:
根据中间件的使用场景,大致可以分为以下几类中间件
1、中间件允许您定义一个自定义函数运行在一个页面或一组页面渲染之前。
在 Nuxt 的项目里面,有一个 middleware 的目录,放置中间件。
核心知识点:
1、它能做什么?
The middleware lets you define custom function to be ran before rendering a page or a group of pages (layouts).
翻译过来就是: 定义一个自定义函数运行在一个页面或者一组页面渲染之前
比如权限判断之类的可以通过中间件来完成。看一个简单的代码片段:
middleware 文件夹里面有一个 admin.js export default ({ store, error, redirect, res, }) => { const { token } = store.state if (!token) { redirect('/login') } }
上面这个代码片段就是从 store 的 state 里面获取 token,没有 token 就重定向到登录。
对比官方给了一个示例(没有箭头函数的简单版本):
export default function (context) { context.userAgent = process.server ? context.req.headers['user-agent'] : navigator.userAgent }
2、函数接受的参数 context 到底包含哪些?
简称上下文,包含的内容太多了,打印的数据太大,比如:
app 最重要的根实例 store error redirect 服务端的 res 和 req 路由里面的 params 和 query 环境配置的 env 当前环境的判断 isClient 改成了 process.client isServer 改成了 process.server isDev
3、配置的地方?
只是在 middleware 里面定义一个函数的 js 文件是不够的,还需要配置
(1)、一般情况下在 nuxt.config.js 里面:
类型是字符串或者数组 router: { middleware: ['user', 'auth'] },
(2)、当然还可以在 .vue 里面配置: middleware: 'auth'
内部深入:
我们看看本地的 .nuxt 文件夹里面有一个 middleware.js const middleware = {} middleware['auth'] = require('../middleware/auth.js') middleware['auth'] = middleware['auth'].default || middleware['auth']
export default middleware
在 server.js 里面如何处理?
1、引入上面的 middleware.js
import middleware from './middleware.js'
2、nuxt.config.js 按顺序配置的其实不只是字符串名字
先拿过来
let midd = ["user","auth"]
然后 map 循环一下,注意下面的 middleware[name] 就和上面呼应了
midd = midd.map((name) => { if (typeof name === 'function') { return name } if (typeof middleware[name] !== 'function') { app.context.error({ statusCode: 500, message: 'Unknown middleware ' + name }) } return middleware[name] })
再处理 layout 和 page 的 .vue 文件里面的 middleware 配置 midd = []
layout 的部分: if (layout.options.middleware) { midd = midd.concat(layout.options.middleware) }
middleware 的部分: Components.forEach((Component) => { if (Component.options.middleware) { midd = midd.concat(Component.options.middleware) } })
有数组了,类似上面的 map 处理:
midd = midd.map((name) => { if (typeof name === 'function') { return name } if (typeof middleware[name] !== 'function') { app.context.error({ statusCode: 500, message: 'Unknown middleware ' + name }) } return middleware[name] })
在 client.js 里面如何处理?
第一步还是引入: import middleware from './middleware.js'
有一个函数 callMiddleware
function callMiddleware (Components, context, layout) { }
里面的代码类似上面,不过不是分开处理,是在一起处理
middleware 中间件
其目录结构目录
该 middleware 目录包含您的应用程序中间件。中间件允许您定义可以在呈现页面或一组页面(布局)之前运行的自定义函数。共享中间件应该放在 middleware/ 目录中。文件名将是中间件的名称(middleware/auth.js 将是 auth 中间件)。
在通用模式下,中间件将在服务器端(对 Nuxt 应用程序的第一个请求,例如直接访问应用程序或刷新页面时)和客户端在导航到进一步路由时调用一次。使用ssr: false,在两种情况下都会在客户端调用中间件。
中间件将按以下顺序依次执行:
nuxt.config.js (按文件内的顺序)
匹配的布局
匹配的页面