版本:nuxt 2.15.8
说到 Nuxt,必须先从 Vue.js 说起,Vue.js 为专注在视图层(View) 的 JS 框架,为 SPA(Single Page Application)应用程式,简而言之整个网站应用只有单一页面,一但页面被加载进来后,就不会再进行该页面请求,由于 Vue 是利用 JS 载入资料,并动态产生元件,SEO 只能抓取到 HTML 内容,因此 SEO 表现趋近于零。
而 Nuxt 是基于 Vue.js、Node.js、Webpack 以及 Badel.js 的轻量框架,可以同时创建 SSR(Server Side Render)及 SPA,在页面载入前即渲染(伺服器回传完整 HTML 档,每次跳转页面,浏览器都需要刷新),搜寻引擎爬虫可以取得资料,大幅解决 SEO 的问题。
以下图片说明:
接下来一起来尝试创建一个 Nuxt 专案吧!
如同 Vue CLI,Nuxt 也有类似的指令列(command-line)工具 create-nuxt-app,
依据官方文件提供的专案包建置方式:
npx create-nuxt-app <project-name>
接着会跑出一些选项:
Project name:设定专案名称Programming language:选择程式语言Package manager:软体套件管理系统 npm / yarnUI framework:css 模板Template engine:样版引擎Nuxt.js modules:相依套件Linting tools:程式码检查工具Testing framework:测试工具Rendering mode:渲染模式Deployment target:运行模式 (在此示範 Server Side Render)Development tools:开发工具Version control system:版控工具以上选择完毕就开始安装专案包
运行完成就可以开始编译专案
跟着提示讯息执行:
cd test
npm run dev
在 package.json 内可以看到相关指令
"scripts": { "dev": "nuxt", "build": "nuxt build", "start": "nuxt start", "generate": "nuxt generate"}
接下来就可以看到画面啰 ?
使用 create-nuxt-app 安装完成后,可以看到以下的资料夹结构
assets, layouts, middleware, mixins, plugins 以上资料夹在当前版本是需要手动建置的,
依照顺序介绍各资料夹功能:
assets
跟 Vue 专案相同,用来存放像是 css, scss, images 需要被 webpack 编译的静态资源,如不需被编译,则存放于 static。
components
自订的元件档,例如我们常会建立共用的 Navbar.vue, Sidebar.vue …,通常为大写命名,然后在需要的页面引入该档案即可使用,使用方式基本上跟 Vue 专案相同。
如果不想要个别引入元件,Nuxt 也有提供很便利的作法,只要在 nuxt.config.js 档内设定:
export default { components: true}
就会全局引入元件,使用方式只要遵循资料夹结构输入元件名称就可以了
範例:
元件路径:components/home/Banner.vue
使用元件:<HomeBanner></HomeBanner>
layouts
共用模板。
大家还记得在 Vue 专案下,只要在 App.vue,或是在 router 建立一个巢状路由,外层设定共用容器,再将嵌套路由放入 children,子路由就可以共享外层模板
export default [ { path: '/products', component: Product, children: [ { path: 'food', component: Food }, { path: 'drink', component: Drink } ] }]
但是在 Nuxt 架构下,并不存在 App.vue 这只档案,router 也会自动配置,那该怎么做到模板共用呢?其实很简单,只要在 layouts 资料夹内,新增 default.vue 档,预设所有 pages 内的档案都会共享该版面
<template><div class="default-wrap"><Navbar /><Nuxt /><Footer /></div></template>
<Nuxt />
类似 Vue 的 <router-view />
(嵌套路由)
如果想要新增更多模板,只要在 layouts 内新增档案,例如 layouts/products.vue,在欲使用的页面引入,该页就可以读到 layouts/products.vue 模板
export default { layout: 'products'}
middleware
前面有说到 Nuxt 专案会自动依 pages 内的资料夹结构产生对应的静态/动态路由,
但如果说我们想要使用 路由守卫(Navigation Guards) 来进行路由监听,像是 Vue router 内的 beforeEach callback,该怎么做呢?
Vue 专案:
const router = new VueRouter({mode: 'history',routes});router.beforeEach(async (to, from, next) => {if (!store.permissions.includes(route.path)) {next({ statusCode: 403 });}next();});export default router;
Nuxt 专案:
我们可以手动建立一个 middleware 资料夹,在里面新增要进行路由监听的档案 routeAuth.js
export default ({ from, route, redirect, store, error }) => {if (!store.isLogin) {redirect('/login');}if (!store.permissions.includes(route.path)) {error({ statusCode: 403 });}};
然后在需要进行监听的档案加入 middleware
export default middleware: 'routeAuth',data() {return {};}};
或是在 nuxt.config.js 设定全域监听
export default { router: { middleware: [ 'routeAuth' ] }}
mixins
mixins 提供弹性方式让页面可以重複使用方法,可以包含任何 Vue 组件项目(data, computed, watch, 生命週期),将共用方法包装进去,首先在 mixins 新增档案 mixins/utils.js
export default {data() {return {number: 0};}methods: {count() {this.number++;}}};
全域注册:
全域宣告 mixin 务必小心使用,因为会影响到所有 Vue 档(pages, components)
在 mixins 新增一支档案 global-mixins.js,将欲全域注册的档案加入 Vue 实例
import Vue from 'vue';import utils from '@/mixins/utils';// 避免重複注册if (!Vue.__utils_mixin__) { Vue.__utils_mixin__ = true; Vue.mixin(utils);}
接着加入 nuxt.config.js 内
export default { plugins:[{ src: '@/mixins/global-mixins' } ]}
局部注册:
局部注册很简单,只要在欲使用档案引入即可,这里假设在 pages/about.vue
import utils from '@/mixins/utils';export default {name: 'About', mixins:[ utils ]}
这样在 About 页面就可以取得参数 number 的值跟呼叫 count() 方法啰!
pages
主要的页面档案,Nuxt 专案会自动依照 pages 内的资料夹结构配置路由,
换句话说,就不需要像 Vue 专案一样需要自行设定 vue-router,为小写命名(命名会直接是路径名称),每个 .vue 档都是已经被注册的页面
以首页为例:pages/index.vue → http://localhost:3000
巢状路由:
直接举例,先建立一支档案 pages/about.vue
<template> <div> about: <nuxt-child /> </div></template>
接在 about 资料夹新增两只档案,可取得配置的巢状路径如下
pages/about/index.vue → http://localhost:3000/about
pages/about/claire.vue → http://localhost:3000/about/claire
动态路由:
如果想要显示动态路由,只要在档名前加上下底线就可以了:
pages/about/ _name.vue → http://localhost:3000/about/claire
这样就可以在档案内取得动态路由参数
export default { created () { console.log(this.$route.params.name); }}
plugins
Nuxt 插件,于 Vue.js 执行前引入第三方套件,以 vue-notification 为例
首先使用 npm 安装 npm i vue-notification
然后在 plugins 页面新增 notification.js 档
import Vue from 'vue';import Notifications from 'vue-notification';Vue.use(Notifications);
在 nuxt.config.js 配置 plugins
export default { plugins: [{ src: '@/plugins/notification.js' }]}
就可以在所有页面中使用该套件 <Notifications></Notifications>
static
静态资源资料夹,用来存放不需要被编译的档案,像是图片档,或是可以供使用者下载的範例档等,如需被编译,则存放于 assets。
store
放置 Vuex 状态管理工具,用来存放全域共用的方法、资料,使用方式与 Vue 大致相同,Vuex 在使用时会碰到一个问题,当页面重新整理,其会被还原为初始状态,至于要怎么解决这个问题,后续会单独介绍。
参考文章:
https://israynotarray.com/vue/20211011/3406447097/
https://dev.to/husteadrobert/how-to-use-global-navigation-guards-with-nuxt-middleware-and-why-you-absolutely-should-not-7bl
https://medium.com/@seyijosh44/how-to-use-mixins-in-nuxt-js-826724fa251
https://medium.com/web-design-zone/建立nuxt-js专案初体验-21920735e38b
https://levelup.gitconnected.com/spa-ssg-ssr-and-jamstack-a-front-end-acronyms-guide-6add9543f24d