Nuxt3-Vue3
《距离上次在掘金发布文章已经在上次了,哈哈哈!!!🙃🙃🙃》
《掌握api使用即可,因为大部分还是开发思想最重要,只是对Nuxt3的一些API实现记录吧》
《官方文档阅读最重要吧,建议阅读原生的英文!!!》
- 学习 ssr 的好处:
- 可以深刻的理解SEO优化具体是如何做的,以及通过配置项来直观的感受到 meta 元数据的配置以及预加载和预获取的实现吧
- 增加自己的面试竞争力以及快速适应公司业务开发,同时拓展自己本身的技术栈吧
- nuxt.com/docs/ 官方文档阅读推荐
Nuxt3 创建项目方式
- 第一种: 使用官方脚手架进行对应的开发模式
npx create nuxt <project-name>npx nuxi init <project-name>
- 第二种直接下载模板解压即可
https://codeload.github.com/nuxt/starter/tar.gz/refs/heads/v3- 这种相对较快很多
- 第三种配置本地 hosts 映射表
185.199.108.133 raw.githubusercontent.com185.199.108.133:443 raw.githubusercontent.com- 测试后,感觉没啥用,推荐使用第二种方案吧
Nuxt3 项目目录结构
- .nuxt 项目的类型文件生成吧
- pnpm run prepare 后会生成这个目录
- .output 项目的编译目录
- server 项目的服务端目录
- static 项目的静态资源目录
- public 项目的公共资源目录
- nuxt.config.ts 项目的配置文件
- package.json 项目的依赖文件
- tsconfig.json 项目的 ts 配置文件
- app.vue 项目的入口文件
Nuxt3 开发目录整合
assets项目的静态资源目录components项目的组件目录composables项目的组合式 API 目录layouts项目的布局目录middleware项目的中间件目录pages项目的页面目录plugins项目的插件目录server项目的服务端目录store项目的状态管理目录types项目的类型目录utils项目的工具目录app.vue项目的入口文件app.config.ts项目的配置文件nuxt.config.ts项目的配置文件package.json项目的依赖文件tsconfig.json项目的 ts 配置文件
Nuxt3 nuxt.config.ts 配置
nuxt.config.ts runtimeConfig 配置
- runtimeConfig
pnpm run dev运行时的配置 - 在组件中使用我们的
useRuntimeConfig方法获取我们的配置吧 - 在组件中通过我们的
import.meta.client和import.meta.server判断我们的环境吧 - 底层使用的是使用
dotenv来实现获取我们的环境的呐 - 这样的我们的一些配置的话还可以在
.env中进行配置的吧- 优先级的话是:
.env > nuxt.config.ts
- 优先级的话是:
typescript
//PAGES
const runtimingConfig: ReturnType<typeof useRuntimeConfig> = useRuntimeConfig()
if (import.meta.server) {
// Only available on the server
console.log('This is running on the server')
console.log('runtimingConfig', runtimingConfig.appKey)
console.log('runtimingConfig', runtimingConfig.public.appBase)
} else if (import.meta.client) {
// Only available on the client
console.log('This is running on the client')
console.log('runtimingConfig', runtimingConfig.public.appBase)
} else {
// Available on both the server and the client
console.log('This is running on both the server and the client')
console.log('runtimingConfig', runtimingConfig.public.appBase)
}
typescript
//TDOD nuxt.config.ts
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
runtimeConfig: {
//TODO 定义一些运行时候的全局配置
appKey: '1234567890', // server-side can access
public: {
//TODO 定义一些公开的全局配置
baseURL: '/api', // server-side and client-side can access
}
}
})
nuxt.config.ts appConfig 配置
- 同时该配置和上面的配置一样的,都是具备对应的解决方案吧
- 可以将对应的配置进行抽取到我们的
app.config.ts中进行配置的吧defineAppConfig方法进行定义我们的配置
- 优先级的话是:
app.config.ts > nuxt.config.ts - 页面中获取的操作是:
useAppConfig方法
typescript
//Components Page
//TODO 获取AppConfig配置
const appConfig: ReturnType<typeof useAppConfig> = useAppConfig()
console.log('appConfig', appConfig.author, appConfig.title)
typescript
//nuxt.config.ts
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
appConfig: {
//TODO 定义应用的一些配置
title: "vue-nuxt", //TITLE CONFIG
description: "vue-nuxt", //DESCRIPTION CONFIG
author: "JUWENZHANG", //AUTHOR CONFIG
copyright: "vue-nuxt", //COPYRIGHT CONFIG
keywords: "vue-nuxt", //KEYWORDS CONFIG
lang: "zh-CN", //LANG CONFIG
}
})
typescript
//app.config.ts
//TODO 全局app配置文件
export default defineAppConfig({
title: "vue-nuxt", //TITLE CONFIG
description: "vue-nuxt", //DESCRIPTION CONFIG
author: "JUWENZHANG", //AUTHOR CONFIG
copyright: "vue-nuxt", //COPYRIGHT CONFIG
keywords: "vue-nuxt", //KEYWORDS CONFIG
lang: "zh-CN", //LANG CONFIG
themeColor: { //TODO 主题色配置
primary: "#1989fa", //主色
success: "#07c160", //成功色
warning: "#ff9900", //警告色
danger: "#ed3f14", //危险色
info: "#909399", //信息色
},
logo: { //TODO 项目logo配置
src: "/logo.png", //logo路径
alt: "vue-nuxt", //logo描述
}
})
nuxt.config.ts app 配置
- 主要是时进行的是对我们的入口文件 app 的配置吧
- 也就是属性
app吧 - 实现的是对我们的网站进行做 SEO 优化在 nuxt 中核心配置吧
- 主要是配置的是我们的武网页中的 head 中的 meta 元素的配置吧
title标题SEO优化keywords关键字SEO优化description描述SEO优化author作者SEO优化lang语言SEO优化viewport视口SEO优化
预获取和预加载- 两个都是资源请求方式,都是为了提高我们的网站的性能以及实现一些性能指标的吧,link 标签来实现的吧
preload预加载- 是一种声明式的资源请求方式,用于告诉浏览器在页面加载时预先加载资源,以提高页面加载速度。
- 预加载的资源可以是图片、字体、视频、音频等。
预加载的资源会在页面加载时开始下载,但是不会立即执行,而是在页面加载完成后再执行。- 预加载的主要目的是确保关键资源在需要时能够快速可用,减少页面渲染的延迟。
- 是为了提高我们的首屏加载吧,将
FMP的资源今早实现展示吧
prefetch预获取也是一种资源请求方式,不过它主要用于告诉浏览器在空闲时间去下载未来可能会用到的资源- 这些资源通常是用户接下来可能访问的页面或功能所需的资源,预获取的目的是提高后续页面的加载速度。
- 浏览器缓存策略
- 预加载和预获取的资源都是会被浏览器进行缓存,并且呐下一次进行访问界面的时候,会直接从缓存中获取资源,而不会再次进行请求的吧
- 通过缓存策略可以
实现降低服务器的负载,提高用户的二次访问速度,减少网络请求的次数,提高页面的加载速度。
- ssr 中的使用
- useHead 的使用,可以动态的给我们的每个页面进行添加对应的进行SEO优化的内容吧
- app的配置和我们的appConfig的配置有一定的不同,是可以进行修改的呐
- 该配置是可以全局配置的,同时也是可以进行对应的每个
pages一个head配置吧- 主要是分为我们的全局配置或者说独立性的页面配置吧
- useHead 的使用,可以动态的给我们的每个页面进行添加对应的进行SEO优化的内容吧
- 优先级配置:
elementConfig>useHead>nuxt.config.ts
typescript
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
app: {
head: {
//TODO TITLE 配置
title: 'vue-nuxt',
charset: 'utf-8',
//TODO META 配置
meta: [
{ name: 'description', content: 'vue-nuxt' },
{ name: 'keywords', content: 'vue-nuxt' },
{ name: 'author', content: 'JUWENZHANG' },
{ name: 'copyright', content: 'vue-nuxt' },
{ name: 'lang', content: 'zh-CN' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1.0,maximum-scale=1.0, user-scalable=no' },
{ name: 'theme-color', content: '#1989fa' },
{ name: 'apple-mobile-web-app-capable', content: 'yes' },
{ name: 'apple-mobile-web-app-status-bar-style', content: 'black' },
],
//TODO 引入一些全局的样式文件
link: [
{
rel: 'icon',
type: 'image/x-icon',
href: '/favicon.ico'
},
//TODO 图片懒加载
{
rel: 'preload',
as: 'image',
href: '/logo.png',
},
//TODO 字体懒加载
{
rel: 'preload',
as: 'font',
href: '/fonts/iconfont.woff2',
crossorigin: 'anonymous',
},
//TODO 视频懒加载
{
rel: 'preload',
as: 'video',
href: '/video.mp4',
},
//TODO 音频懒加载
{
rel: 'preload',
as: 'audio',
href: '/audio.mp3',
},
//TODO 预获取资源
{
rel: 'prefetch',
as: 'image',
href: '/logo.png',
},
{
rel: 'prefetch',
as: 'font',
href: '/fonts/iconfont.woff2',
crossorigin: 'anonymous',
},
{
rel: 'prefetch',
as: 'video',
href: '/video.mp4',
},
{
rel: 'prefetch',
as: 'audio',
href: '/audio.mp3',
}
],
//TODO 引入一些全局的脚本文件, 可以是 CDN 也可以是本地的文件, CDN 优化吧
script: [],
style: [],
}
}
})
typescript
const seoConfig: ReturnType<typeof useHead> = useHead({
title: "76433",
meta: [
{ name: "description", content: "76433, juwenzhang, 橘子" },
{ name: "keywords", content: "juwenzhang, nuxt, 76433" },
{ name: "author", content: "JUWENZHANG" }
//...
],
link: [
{
rel: 'icon',
type: 'image/x-icon',
href: '/favicon.ico'
},
//TODO 图片懒加载
{
rel: 'preload',
as: 'image',
href: '/logo.png',
},
//TODO 字体懒加载
{
rel: 'preload',
as: 'font',
href: '/fonts/iconfont.woff2',
crossorigin: 'anonymous',
},
],
style: [],
script: [
{
head: true,
}
],
})
console.log(seoConfig)
nuxt.config.ts ssr 配置
- nuxt是默认开启了我们的
ssr服务端渲染模式的呐 - 但是也是可以通过自定义来实现对应的决定是否开启的呐:
ssr: <boolean>即可实现设置吧ssr: false的话就是说明的是是客户端渲染,这个时候我们的SEO获取得到的结果空白,还是以前的 spa 的js来实现渲染内容的呐ssr: true的话就是说明的是是服务端渲染,这个时候浏览器的SEO获取到的是很多的内容
nuxt.config.ts router 配置
- 该配置主要是决定我们的前端路由主要是以什么的形式进行的呐
- 主要是通过
router.options.hashMode: <boolean>来决定我们前端使用的路由模式的呐- 非
hash模式就是history模式 - ssr 服务端渲染的话主要使用的是
history路由模式
- 非
typescript
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
ssr: true,
router: {
options: {
hashMode: true, // TODO 使用hash路由模式
// hashMode: false, // false的话就是 history 模式的路由配置吧
}
}
})
nuxt.config.ts alias 配置
- 主要实现的是对路径进行别名的配置,任然是为了我们的开发时的提升效率吧
typescript
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
alias: {
"@": "src/",
"@component": "src/component"
}
})
nuxt.config.ts css配置
- 可以指定配置我们的全局CSS样式吧
- less 和 scss 的预处理器的添加,直接安装:
less和sass预处理器即可- less 和 scss 的一些高级的语法可以去看看,为自己的开发增加更多的工程化规范(抽离代码有用以及组件库封装亮点之一)
- css 方案的话还有原子化方案:
tailwindcss或者说unocss方案吧 - CSS工程化方案具备
*.module.css模块化方案less | sass预处理器方案- css 定义变量:
-- - less 定义变量:
@ - sass 定义变量:
$
- css 定义变量:
tailwindcss | unocss原子化方案
Nuxt3 中间件
- 中间件主要是定义在
middleware目录下的呐 - 可以定义的一些中间件的话含有:
- 类型区分:
全局中间件和路由中间件和局部中间件 - 在原本的 spa 界面中的话,我们的中间件是通过
router.beforeEach来实现的对路由进行的守卫拦截
- 类型区分:
局部中间件定义- 主要就是使用我们的
definePageMeta方法来定义的局部中间件吧,书写位置在pages中的每一个*.vue页面中
- 主要就是使用我们的
typescript
definePageMeta({
//TODO 多个中间件的执行顺序就是按照定义的顺序进行执行的呐
middleware: [
/**
* TODO 路由中间件的定义
* 当然从我们的架构分析的话,这种中间件都是可以往外面进行抽取的呐
* 毕竟内部就是一个一个简单的callback的回调嘛
* to 需要前往的路由
* from 当前路由
*/
function (to, from) {
console.log(to)
console.log(from)
},
/**
* TODO 第二个中间件定义
*/
function (to, from) {
console.log(to)
console.log(from)
return //由于已经具备了返回值,所以说后续的中间件就不会执行了呐
//return abortNavigation() //中止导航,后续的中间件也不会执行了呐
}
],
layout: 'default', //TODO 布局组件的定义
meta: {}, //TODO 页面的元数据的定义
})
具名中间件- 主要是通过
defineNuxtRouteMiddleware方法来定义的中间件吧,书写位置在middleware目录下的每一个*.ts文件中
- 主要是通过
typescript
//TODO 鉴权功能中间件
const authMiddleware = defineNuxtRouteMiddleware((to, from) => {
const token: string = localStorage.getItem('token')
if (token) {
if (to.path !== '/login') {
return navigateTo('/')
} else {
return
}
} else {
return abortNavigation()
}
})
export {
authMiddleware,
}
全局中间件defineNuxtRouteMiddleware方法来定义的中间件吧,书写位置在middleware目录下的每一个*.global.ts文件中- 自动化的转化为
全局中间件了吧
typescript
export default defineNuxtRouteMiddleware((to, from) => {
const token: string = localStorage.getItem('token')
if (token) {
if (to.path !== '/login') {
return navigateTo('/')
} else {
return
}
} else {
return abortNavigation()
}
})
Nuxt3 内置组件
SEO组件
- 不是前面的文档中我们的 app 配置部分主要讲述了关于优先级问题迈
- 那些对应的就是原生中的:
head元素内部的配置,内部包含我们的:link meta title style script - 同时使用 useHead 进行的对应的配置也是一样的呐,也是这样的配置流程吧
- 同样额外的配置就是通过 elementConfig 的配置实现吧
- 在 ssr 中每个页面相对独立,又相对耦合吧,每个页面之间具备相同的配置,也具备独立的配置吧
Html组件Body组件Head组件Title组件Meta组件Style组件Link组件NoScript组件Base组件- 注意,我们的 ssr 中是不具备
index.html的,这个注意一下吧 - 是通过
hydration以及模板字符串的形式实现动态渲染的
NuxtWelcome组件
- 该组件就是形成对应的网站欢迎界面的组件吧,是
@nuxt/ui的一部分
NuxtLayout组件
- 是Nuxt自带的页面布局组件
NuxtPage组件
- 是在 Nuxt SSR 项目中的一个路由占位组件吧
- 该组件就是对
vue-router中的router-view组件进行的进一步的封装完成的吧
NuxtLink组件
- 就是进行路由切换的组件
- 该组件就是对我们的
vue-router中的router-link进行的进一步封装吧
ClientOnly组件
- 指定那些部分内容只在客户端进行渲染
NuxtErrorBoundary组件
- 就是实现的类似于 REACT 中常谈的
ErrorBoundary异常捕获组件吧 - 可以实现对应的
UI降级操作
Nuxt3 layout布局
- 主要是通过
layouts目录下的*.vue文件来定义的布局组件吧 - 布局组件的话主要是通过
NuxtLayout组件来实现的呐- 内部具备 name 属性,默认值为
default,来实现动态的决定使用何布局组件的吧
- 内部具备 name 属性,默认值为
- 主要就是将网页中公共的部分进行抽取的一个架构设计吧,这个很简单的呐
Nuxt3 渲染模式
- 浏览器和服务端都是可以实现解析 JavaScript 代码的呐,
- 都是可以在属于自己的平台实现将React或者Vue代码生成HTML代码的呐,这个过程就是我们的渲染过程了吧
- 在客户端实现渲染的过程,就是我们的
CSR客户端渲染模式了吧 - 在服务端实现渲染的过程,就是我们的
SSR服务端渲染模式了吧 - 同时还具备我们的混合渲染模式:
SSR | CSR | SSG | SWR | ISR服务端渲染 | 客户端渲染 | 静态站点生成 | 数据获取策略 | 增量静态重新生成
- Nuxt3 中出现这样的混合渲染模式主要是因为所有的东西在SSR中进行渲染,反倒不是特别的好,物极必反
- 所以说这个时候就出现了将
一部分内容交给客户端渲染即可,一部分内容交给服务端渲染即可 - 这样就实现了合理的应用我们的
CSR和SSR的混合渲染模式了呐,既满足了我们的SEO优化,又满足了我们的性能优化,实现最终的综合优化
- 所以说这个时候就出现了将
- 实现的方式: 就是通过配置: nuxt.config.ts 中的
routeRules来实现的呐- routeRules 指定不同
pages的渲染模式吧
- routeRules 指定不同
Nuxt3 plugins插件
- 创建插件的两种方式:
useNuxtApp()方法来获取全局的应用实例对象
- 使用插件
useNuxtApp().$pinia方法来获取全局的状态管理实例对象useNuxtApp().$router方法来获取全局的路由实例对象useNuxtApp().$route方法来获取全局的路由对象useNuxtApp().$i18n方法来获取全局的国际化实例对象useNuxtApp().$config方法来获取全局的配置对象useNuxtApp().$axios方法来获取全局的 axios 实例对象useNuxtApp().$fetch方法来获取全局的 fetch 实例对象useNuxtApp().$cookies方法来获取全局的 cookies 实例对象useNuxtApp().$device方法来获取全局的 device 实例对象
- 自定义插件
- 可以通过
defineNuxtPlugin方法来定义我们的插件吧 - 该方法的返回值是一个对象,对象中包含
provide和install两个属性 provide是一个函数,该函数的返回值是一个对象,该对象中包含我们的插件的一些全局的属性和方法吧install是一个函数,该函数的返回值是一个对象,该对象中包含我们的插件的一些全局的属性和方法吧
- 可以通过
- 定义插件的时候分为两种,一种客户端插件,一种服务端插件
*.server.ts服务端插件*.client.ts客户端插件- 使用的时候需要进行区分对应的环境吧
import.meta来进行对应的区分吧
typescript
//TODO 自定义插件
export default defineNuxtPlugin((nuxtApp) => {
return {
provide: {
//TODO 全局属性和方法
myPlugin: {
name: 'myPlugin',
version: '1.0.0',
author: 'JUWENZHANG',
}
},
install: (app, options) => {
//TODO 全局属性和方法
app.config.globalProperties.$myPlugin = {
name:'myPlugin',
version: '1.0.0',
author: 'JUWENZHANG',
}
},
}
})
//components
const nuxtApp: ReturnType<typeof useNuxtApp> = useNuxtApp()
console.log(nuxtApp.$myPlugin) //TODO use myPlugin
Nuxt3 lifeCycle生命周期
- nuxtApp.hooks 的定义形式吧
- 生命周期的话,官网推荐在 plugins 中进行使用吧
- 和小程序开发就很类似了,生命周期的话具备:
应用的生命周期,页面的生命周期,组件的生命周期
typescript
//TODO setup 的话,已经包含了 beforeCreate 和 created 两个生命周期了呐
const nuxtApp: ReturnType<typeof useNuxtApp> = useNuxtApp()
nuxtApp.hooks.hook('app:beforeCreate', () => {
//TODO 在应用实例创建之前执行的逻辑
})
nuxtApp.hooks.hook('app:created', () => {
//TODO 在应用实例创建之后执行的逻辑
})
nuxtApp.hooks.hook('app:beforeMount', () => {
//TODO 在应用实例挂载之前执行的逻辑
})
nuxtApp.hooks.hook('app:mounted', () => {
//TODO 在应用实例挂载之后执行的逻辑
})
nuxtApp.hooks.hook('app:beforeUpdate', () => {
//TODO 在应用实例更新之前执行的逻辑
})
nuxtApp.hooks.hook('app:updated', () => {
//TODO 在应用实例更新之后执行的逻辑
})
nuxtApp.hooks.hook('app:beforeUnmount', () => {
//TODO 在应用实例卸载之前执行的逻辑
})
nuxtApp.hooks.hook('app:unmounted', () => {
//TODO 在应用实例卸载之后执行的逻辑
})
Nuxt3 其他注意点
静态资源问题
- 资源的存放在 public 目录下,页面引入的话直接使用
public --> /即可
路由问题
路由组件的定义:- 路由组件存放于
pages目录下的呐,这是规定好了的吧 - 注意书写路由组件前的话,一定要具备展示路由组件的占位组件:
NuxtPage,一般在app.vue中占位即可
- 路由组件存放于
路由映射关系:pages/index.vue-->domain:port/推荐pages/<other>.vue-->domain:port/<other>不推荐(不利于拓展嵌套路由组件)pages/<other>/index.vue-->domain:port/<other>推荐pages/<other1>/<other2>.vue-->domain:port/<other1>/<other2>推荐pages/<[id]>.vue-->domain:port/:id动态路由pages/<[id]>/index.vue-->domain:port/:id动态路由pages/<[id]>/<[other]>.vue-->domain:port/:id/:other动态路由
控制路由跳转方式:NuxtLink组件来实现路由跳转,使用方法等同于router-linkto active-class href replace target no-prefetch no-referrer external- 很多的属性和 a 标签的属性是一致的呐,因为其底层就是通过 a 标签来实现的呐
no-prefetch是指在预加载资源的时候,不进行预加载该路由的资源no-referrer是指在请求该路由的时候,不携带 referrer 信息,该信息是指当前页面的地址external跳转 cors 的时候,一定要加上这个属性,否则会报错的呐
useRouter方法实现路由跳转- 调用
useRouter hooks后,可以直接获取全局路由示例对象router - 获取得到该路由对象后,就可以通过该路由对象来实现路由跳转的呐
- 主要是应用于编程式导航中吧
- 核心 api:
push replace back forward go和原生的location api是类似的呐
- 调用
useRoute方法实现路由跳转- 调用
useRoute hooks后,可以直接获取全局路由对象route - 可以用来获取当前路由的一些信息,比方说我们的
路由参数,路由名称,路由路径,路由元数据等等 route.params获取路由参数route.query获取路由查询参数route.hash获取路由哈希值route.fullPath获取路由完整路径route.matched获取路由匹配信息route.name获取路由名称route.path获取路由路径route.meta获取路由元数据route.redirectedFrom获取路由重定向来源
- 调用
navigateTo实现路由跳转- 不推荐使用,不利用进行SEO优化吧
- 调用方式:
navigateTo('/')navigateTo({ path: '/' })navigateTo({ path: '/', query: { id: 1 } })navigateTo({ path: '/', hash: '#top' })navigateTo({ path: '/', replace: true })navigateTo({ path: '/', external: true })navigateTo({ path: '/', noPrefetch: true })navigateTo({ path: '/', noReferrer: true })navigateTo({ path: '/', noScroll: true })navigateTo({ path: '/', noScrollBehavior: true })
编写接口
- nuxt3 也是支持实现书写属于自己的后端接口的呐
- 接口的书写位置:
server/api目录下的*.ts文件中 - 这个感兴趣的可以自行探究吧,和 express 或者说 koa 差不多的实现
- 书写接口的时候先把计算机网络看看比较好吧,以及熟悉 restful 规范吧
- 在客户端部分的代码调用接口的话可以使用:
useFetch方法来进行发送对应的请求即可吧
nuxt.config.ts 总配置demo
typescript
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
devtools: { enabled: true },
sourcemap: {
server: true,
client: true,
},
runtimeConfig: {
//TODO 定义一些运行时候的全局配置
appKey: '1234567890', // server-side can access
public: {
//TODO 定义一些公开的全局配置
apiBase: '/api', // server-side and client-side can access
}
},
app: {
head: {
//TODO TITLE 配置
title: 'vue-nuxt',
charset: 'utf-8',
//TODO META 配置
meta: [
{ name: 'description', content: 'vue-nuxt' },
{ name: 'keywords', content: 'vue-nuxt' },
{ name: 'author', content: 'JUWENZHANG' },
{ name: 'copyright', content: 'vue-nuxt' },
{ name: 'lang', content: 'zh-CN' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1.0,maximum-scale=1.0, user-scalable=no' },
{ name: 'theme-color', content: '#1989fa' },
{ name: 'apple-mobile-web-app-capable', content: 'yes' },
{ name: 'apple-mobile-web-app-status-bar-style', content: 'black' },
],
//TODO 引入一些全局的样式文件
link: [
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' },
//TODO 图片懒加载
{
rel: 'preload',
as: 'image',
href: '/logo.png',
},
//TODO 字体懒加载
{
rel: 'preload',
as: 'font',
href: '/fonts/iconfont.woff2',
crossorigin: 'anonymous',
},
//TODO 视频懒加载
{
rel: 'preload',
as: 'video',
href: '/video.mp4',
},
//TODO 音频懒加载
{
rel: 'preload',
as: 'audio',
href: '/audio.mp3',
},
//TODO 预获取资源
{
rel: 'prefetch',
as: 'image',
href: '/logo.png',
},
{
rel: 'prefetch',
as: 'font',
href: '/fonts/iconfont.woff2',
crossorigin: 'anonymous',
},
{
rel: 'prefetch',
as: 'video',
href: '/video.mp4',
},
{
rel: 'prefetch',
as: 'audio',
href: '/audio.mp3',
}
],
//TODO 引入一些全局的脚本文件, 可以是 CDN 也可以是本地的文件, CDN 优化吧
script: [
{
src: ""
}
],
//TODO 引入一些全局的样式文件, 可以是 CDN 也可以是本地的文件, CDN 优化吧
style: [],
}
},
ssr: true,
router: {
options: {
hashMode: true, // TODO 使用hash路由模式
// hashMode: false, // false的话就是 history 模式的路由配置吧
}
},
css:[],
routeRules: {
//TODO 为所有路由设置默认规则
'/**': {
ssr: true,
headers: {
'Cache-Control': 's-maxage=1, stale-while-revalidate=59'
}
},
//TODO 为特定路由设置规则
'/static-page': {
prerender: true,
headers: {
'Cache-Control': 's-maxage=31536000, immutable'
}
},
//TODO 重定向路由
'/old-page': {
redirect: '/new-page'
},
//TODO 关闭特定路由的服务端渲染
'/client-only-page': {
ssr: false
}
}
})
- 官网还有很多有趣的内容,可以自行探究,大部分开发思想的话和原本的 spa 是差不多的
- 只是在我们的原本的开发基础上新添了一定的内置开发规则罢了(这也是目前技术的有限性的体现吧)
- 有些功能的完成只能在特定的指定规则下才可以进行对应的开发吧