目录
官网 Nuxt.js
认识nuxt
nuxt通过对客户端/服务端基础架构的抽象组织,Nuxt.js 主要关注的是应用的 UI 渲染。
Vue 开发一个单页面应用,相信很多前端工程师都已经学会了,但是单页面应用有一个致命的缺点,就是 SEO 极不友好。除非,vue 能在服务端渲染(ssr)并直接返回已经渲染好的页面,而并非只是一个单纯的 <div id="app"></div>
。
SSR: 服务端渲染,在服务器端把vue渲染成html返回浏览器
支持SEO:搜索引擎优化
很多需要搜索引擎来提供流量的网站都需要做SSR,适用于一个项目可能所有页面要做SEO,像新闻、博客、影视等内容网站都需要
它具有一下特性,
● 基于 Vue.js
● 自动代码分层
● 服务端渲染
● 强大的路由功能,支持异步数据
● 静态文件服务
● ES2015+ 语法支持
● 打包和压缩 JS 和 CSS
● HTML 头部标签管理
● 本地开发支持热加载
● 集成 ESLint
● 支持各种样式预处理器: SASS、LESS、 Stylus 等等
● 支持 HTTP/2 推送
学习使用nuxt
安装
● Nuxt.js 十分简单易用。一个简单的项目只需将 nuxt 添加为依赖组件即可。
● 安装node和npm等基本前端开发环境
● 确保安装了 npx(npx 在 NPM 版本 5.2.0 默认安装了)
使用
npx create-nuxt-app <项目名>
yarn create nuxt-app <项目名>
它会让你进行一些选择:
- 在集成的服务器端框架之间进行选择:
● None (Nuxt 默认服务器)
● Express
● Koa
● Hapi
● Feathers
● Micro
● Fastify
● Adonis (WIP) - 选择您喜欢的 UI 框架:
● None (无)
● Bootstrap
● Vuetify
● Bulma
● Tailwind
● Element UI
● Ant Design Vue
● Buefy
● iView
● Tachyons - 选择您喜欢的测试框架:
● None (随意添加一个)
● Jest
● AVA - 选择你想要的 Nuxt 模式 (Universal or SPA)
- 添加 axios module 以轻松地将 HTTP 请求发送到您的应用程序中。
- 添加 EsLint 以在保存时代码规范和错误检查您的代码。
- 添加 Prettier 以在保存时格式化/美化您的代码。
Project name——项目名称
Programming language——程序设计语言
Package manager——包管理器
UI framework——UI框架
Nuxt.js modules——NuxtJS模块(如果需要安装某个需要按"空格"电亮才行)
Linting tools——代码校验工具
Testing framework——测试框架
Universal——渲染模式(SSR:服务端渲染、SSG:静态页面生成)
Deployment target——部署目标
Development tools——开发工具
What is your GitHub username?——GitHub名称
Version control system——版本控制工具
npm run dev
目录结构(Nuxt 与 VueCli 对比)
pages——页面(类似于:src/views)
components——组件(类似于:src/components)
static——静态资源(类似于:scr/assets)
store——vuex状态树(类似于:src/store)
muxt.config.js——全局配置文件(类似于:vue.config.js)
├── .nuxt/ # 自动生成的文件,包含编译后的代码和配置
├── assets/ # 用于存放未编译的静态资源,如CSS、图片、字体
├── components/ # 自定义Vue组件
├── layouts/ # 应用的布局文件,定义页面的通用结构
│ └── default.vue # 默认布局
├── middleware/ # 中间件文件,可以在页面渲染前后执行逻辑
├── pages/ # 应用的路由和视图,每个文件对应一个路由
│ ├── index.vue # 默认首页
│ └── [slug].vue # 动态路由示例
├── plugins/ # 自定义Vue.js插件
├── static/ # 静态资源,会被原样复制到输出目录
├── store/ # Vuex状态管理文件
│ ├── actions.js # Vuex actions
│ ├── mutations.js # Vuex mutations
│ ├── getters.js # Vuex getters
│ └── index.js # Vuex store入口文件
├── nuxt.config.js # Nuxt.js配置文件
├── package.json # 项目依赖和脚本
└── yarn.lock # 或者npm.lock,记录依赖版本
服务端生命周期
nuxt的生命周期分为客户端生命周期,服务端生命周期
客户端生命周期(SPA)
● beforeCreate
:在实例初始化之后,数据观测(data observer)和事件/watcher 设置之前调用。
● created
:在实例创建完成后被调用,在这一步,实例已完成以下的配置:数据观测(data observer),属性和方法的运算,watch/event
事件回调。然而,挂载阶段还没开始,$el
属性目前不可见。
● beforeMount
:在挂载开始之前调用,相关的 render 函数首次被调用。
● mounted
:el 被新创建的 vm.$el
替换,并挂载到实例上去之后调用。
● beforeUpdate
:数据更新时调用,此时虚拟 DOM 已创建完毕,但尚未被实际的 DOM 替换。
● updated
:由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。
● beforeDestroy
:实例销毁之前调用。
● destroyed
:实例销毁后调用,此时所有的事件监听器会被移除,所有的子实例也会被销毁。
服务端生命周期(SSR)
● nuxtServerInit(store,context){}
:类似于vue.js中的main.js。可以在这个生命周期中获取token并存储。store为vuex上下文,context 为nuxt上下文
● middleware({store,route,redirect,params,query,req,res}){}
:类似于vue.js中的导航守卫,可以是全局的,路由的,组件的。可以在这个生命周期中进行用户是否登录判断,在全局nuxt.config.js进行配置,中间件运行,有三种
// 在nuxt.config.js中配置,如下
module.exports = {
router:{
// 指在运行时,指定运行 middlewrae 文件夹下的 auth.js
middleware: 'auth'
}
}
// 在布局layouts里配置
export default {
// 法一:定义在外部即middleware文件夹里
middleware: 'auth'
// 法二:定义在内部
middleware(context){
consle.log('布局级 middleware');
}
}
// pages文件夹下的任意一个页面
middleware(context){
consle.log('页面级 middleware');
}
顺序依次为:nuxt.config.js -> layouts - > page
● validate(仅适用于asyncData和validate)
:在服务端渲染页面之前调用,页面还没有初始化时会先校验参数。
validate({params, query}){
return 校验结果 true/false
// 成功:正常显示页面
// 失败:跳转404页面
}
● asyncData
:异步处理数据,在服务端渲染页面之前调用,可以接收请求的上下文,可以进行数据请求。
// 这里返回的数据会和当前页面的data进行合并,即用this.test就可访问到返回的数据
asyncData(context){
return {
test: '返回的数据'
}
}
● fetch
:异步处理数据,在服务端渲染页面之后,客户端渲染页面之前调用,可以进行数据请求,读取服务端数据提交给vuex。
fetch({store}){
...
}
● head
:用于设置页面的meta信息,在nuxt.config.js中能设置全局的标签。
● beforeCreated(SSR和SPA)
:在实例初始化之后调用。
● created(SSR和SPA)
:在实例被创建之后调用。
Nuxt路由
路由跳转的三种方式
a连接的形式跳转
<a href="/list?id=1">a连接的形式跳转</a><br/>
链接的方式跳转
<nuxt-link :to="{name:'list',query:{id:1},params:{id:2}}">Link的方式</nuxt-link><br/>
js跳转
<template>
<button @click="toList">js跳转</button><br/>
</template>
<script>
toList(){
this.$router.push({
path:'/list',
query:{
id:123
},
params:{
id:321
}
});
}
</script>
使用已有的VueCli路由文件
● 安装插件
npm install @nuxtjs/router -S
● 在【nuxt.config.js】文件的【modules】模块中配置。
modules: [
'@nuxtjs/router'
],
● 在根路径删新建一个【router.js】文件,文件名必须为router。
正常引入之后就是在router.js文件中进行和vue中一样的路由配置,同样也可以进行路由守卫的各种配置
路由守卫
● 有两种方式
router.js
vue-cli中怎么用,next中就怎么用,几乎一样。
//全局导航守卫
router.beforeEach((to,from,next)=>{
if(to.name=="About"){
next("/news")
}else{
next()
}
})
NuxtJS中间件或插件
● 中间件:middleware生命周期创建路由守卫
// 全局:
// nuxt.config.js配置
module.exports = {
router:{
// 指在运行时,指定运行 middlewrae 文件夹下的 auth.js
middleware: 'auth'
}
}
// 全局导航守卫 即配置文件中指向的auth.js文件
export default function(store,route,redirect,parms,query,req,res){
console.log("路由守卫")
}
// 局部:页面级
// 法一:定义在外部即middleware文件夹里
middleware: 'auth'
// 法二:定义在内部
middleware(context){
consle.log('布局级 middleware');
}
● 插件:plugins
// 在【nuxt.config.js】的plugins进行配置
plugins: [
'~/plugins/router.js'
], // 指向plugins文件夹下面的router.js文件
// plugins文件夹下新建一个router.js文件进行配置
export default ({app}) => {
// 全局
app.router.beforeEach((to,from,next)=>{
console.log(to)
next();
})
}
Vuex
Nuxt.js 自动创建了一个 Vuex store。在 store 目录下,你可以创建模块化的 state、mutations、actions 和 getters。例如,创建一个 store/modules/users.js 文件来管理用户数据。
用法和在vue-cli中差不多
页面渲染
在pages/目录下创建一个index.vue文件,这是应用的首页:
<template>
<div>
<h1>Hello from Nuxt.js SSR</h1>
<p>{{ message }}</p>
</div>
</template>
<script>
export default {
data() {
return {
message: 'This content is server-rendered!'
};
},
asyncData() {
// 这里可以在服务器端获取数据
// 返回的数据会作为data的默认值
return { message: 'Data fetched on server' };
}
};
</script>
Nuxt.js 页面渲染的过程分为两个主要阶段:服务器端渲染 (SSR) 和客户端渲染 (CSR)。以下是Nuxt.js页面渲染的详细步骤:
初始化
用户在浏览器中输入URL并发送请求到服务器。
服务器接收到请求后,开始处理。
路由解析
Nuxt.js 使用 nuxt.config.js 中的 routes 配置(如果存在)或自动从 pages/ 目录生成路由。
对应的页面文件被识别,例如 pages/index.vue 或 pages/about.vue。
数据预取
Nuxt.js 查找页面组件中的 asyncData 或 fetch 方法(如果存在)。
这些方法会在服务器端运行,用于从API或其他数据源获取数据。
数据获取后,会被序列化并注入到页面模板中。
模板渲染
Nuxt.js 使用 Vue.js 的渲染引擎将组件和预取的数据转换为HTML字符串。
HTML字符串中包含了客户端需要的所有初始数据,以JSON格式内联在
返回HTML
服务器将生成的HTML响应发送回客户端(浏览器)。
客户端初始化:
浏览器接收到HTML后,开始解析和执行内联的JavaScript。
Nuxt.js客户端库(nuxt.js)被加载并初始化。
客户端渲染
客户端库接管渲染,Vue.js实例被创建,数据从内联的JSON注入到Vue实例。
页面完成初始渲染,用户可以看到完整的页面内容。
此时,页面是交互式的,用户可以触发事件和导航。
后续导航
当用户导航到其他页面时,Nuxt.js 使用客户端路由(Vue Router)进行无刷新跳转。
如果新页面需要数据,asyncData 或 fetch 方法会在客户端运行,获取新的数据并更新视图。
SSG(静态站点生成)
在开发之外,可以使用 nuxt generate 命令生成静态HTML文件。
每个页面都会被预渲染为独立的HTML文件,其中包含所有必要的数据和资源。
使用asyncData
asyncData方法是Nuxt.js特有的,它允许你在服务器端预取数据并在客户端复用这些数据。在上面的示例中,我们简单地更改了message的值,但在实际应用中,你可能会在这里调用API获取数据。
Nuxt.js 配置文件(nuxt.config.js)
export default {
// 项目名称
name: 'nuxt-demo',
// 项目模式:spa, universal, static
mode: 'universal', // 默认值,支持服务器端渲染
// 应用元信息
head: {
title: 'My Nuxt App',
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: 'App description' }
],
link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }]
},
// CSS样式
css: [
'@/assets/css/main.css'
],
// 路由配置
router: {
base: '/nuxt-demo/', // 应用的基础路径
extendRoutes(routes, resolve) {
// 手动扩展或修改路由
}
},
// 构建配置
build: {
transpile: [/^my-vue-component/], // 需要转译的模块
vendor: ['lodash'], // 公共库,提前打包
extractCSS: true, // 提取CSS到单独文件
optimization: {
splitChunks: {
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10,
filename: 'vendors.js'
}
}
}
}
},
// Axios配置
axios: {
baseURL: process.env.BASE_URL || 'http://localhost:3000/api', // API基础URL
browserBaseURL: 'https://api.example.com' // 客户端的API基础URL
},
// Plugins
plugins: [
{ src: '@/plugins/vue-my-plugin', ssr: false } // 异步加载的插件,ssr: false 表示仅客户端加载
],
// Modules
modules: [
'@nuxtjs/axios', // 安装并配置axios模块
'@nuxtjs/pwa' // 安装并配置PWA模块
],
// 环境变量
env: {
apiKey: 'your-api-key',
apiUrl: 'https://api.example.com'
},
// Vuex Store配置
store: true, // 自动创建Vuex store
loading: { color: '#3B8070' }, // 加载指示器颜色
// 服务端中间件
serverMiddleware: [
{ path: '/api', handler: '~/api/index.js' } // 使用自定义的服务器端中间件
],
// 静态生成配置
generate: {
dir: 'dist', // 输出目录
fallback: true, // 对未预渲染的动态路由生成404页面
routes: () => ['/about', '/contact'] // 预渲染的指定路由
}
};