邂逅SPA和SSR
SPA:单页面应用程序,SPA应用是在客户端呈现的
SPA的优缺点:
优点:
- 只需要加载一次
- 用户体验更好
缺点:
- 只有一个页面,不利于网站SEO(不利于搜索引擎优化)
- 首屏加载资源过大,影响首屏的渲染
- 不利于构建复杂的项目,复杂 Web 应用程序的大文件可能变得难以维护
搜索引擎的优化(SEO)
方法:
服务器端渲染(SSR)
优点:
- 更快的首屏渲染速度
- 更好的SEO
缺点:
- 增加了一定的开发成本
SSR解决方案
React:Next.js
Vue3:Nuxt3 || Vue2:Nuxt.js
Nuxt3
项目结构
应用入口(App.vue)
Nuxt 会将此文件视为入口点,并为应用程序的每个路由呈现其内容常用于:
定义页面布局Layout 或 自定义布局,如:NuxtLayout
定义路由的占位,如:NuxtPage
编写全局样式
全局监听路由 等等
nuxt.config配置
- runtimeConfig(定义环境变量)
runtimeConfig:运行时配置,即定义环境变量
✓ 可通过.env文件中的环境变量来覆盖,优先级(.env > runtimeConfig)
这是在nuxt.config中的配置文件
这是在根目录下创建的.env文件,优先级(.env > runtimeConfig)
- appConfig(定义公共变量)
应用配置,定义在构建时确定的公共变量
1.在nuxt.config中配置
2.在页面中直接使用(客户端与服务端都能使用)
- app
Nuxt3内置组件
- SEO组件: Html、Body、Head、Title、Meta、Style、Link、NoScript、Base
- NuxtPage:是 Nuxt 自带的页面占位组件,需要显示位于目录中的顶级或嵌套页面 pages/ ,是对 router-view 的封装
- ClientOnly:该组件中的默认插槽的内容只在客户端渲染
全局样式
方式一
- 如果相要写全局样式,则需要在nuxt.config.ts中进行配置css
- 然后在根路径中配置assets/styles....css
- 然后在自己需要的页面中直接进行使用就行了
方式二
- 在assets/styles中编写样式(scss)
- 然后在需要使用的页面使用@use导入,并使用 @use "样式的路径" as *
创建页面路由
Nuxt项目中的页面是在 pages目录 下创建的
在pages目录创建的页面,Nuxt会根据该页面的目录结构和其文件名来自动生成对应的路由。
组件导航
- NuxtLink
是Nuxt内置组件,是对 RouterLink 的封装,用来实现页面的导航
编程式导航
- navigateTo(首选)
编程式路由导航:navigateTo 。但是编程导航不利于SEO。
async function goToCart() {
// navigateTo("/cart")
//对象写法
await navigateTo({
path: '/cart',
query: {
id: 200
}
})
}
- useRouter
总结:在平时开发的时候,如果需要使用useRouter的push,建议使用navigateTo 。如果需要使用back,beforeEach(路由守卫写在app.vue),则需要使用useRouter来完成
动态路由
当你有的路由不确定需要与否,则可以使用动态路由
页面组件目录 或 页面组件文件都 支持 [ ] 方括号语法
在页面访问的时候就可以在cart后面接上任意的值都可以访问路由
获取动态路由的参数
通过 [ ] 方括号语法定义动态路由,比如:/detail/[id].vue,比如:/detail/10010,目标页面通过 route.params 获取动态路由参数
查询字符串参数
通过查询字符串方式传递参数,比如:/detail/10010?name=yjm,目标页面通过 route.query 获取查询字符串参数
404Page
在pages目录下,创建[...slug].vue的组件(slug可以是任意字符串),当捕获不到到所有的路由就会展示这个界面
嵌套路由
- 创建一个一级路由,如parent.vue
- 创建一个与一级路由同名的文件夹,如parent
- 在parent文件夹下,创建所需要的二级路由
- 需要在parent.vue中添加NuxtPage路由占位符
路由中间件
layout布局
每个页面的页眉和页脚组件,这些具有共性的组件我们是可以写到一个Layout布局中。
Layout布局是使用<slot>组件来显示页面中的内容
- 方式一:默认布局
1.在layouts目录下新建默认的布局组件,比如:layouts/default.vue
2.然后在app.vue中通过<NuxtLayout>内置组件来使用
- 方式二:自定义布局
1.继续在layouts文件夹下新建 Layout 布局组件,比如: layouts/custom-layout.vue
2.然后在app.vue中给<NuxtLayout>内置组件 指定name属性 的值为:custom-layout , 也支持在页面中使用 definePageMeta 宏函数来指定 layout 布局(给页面单独定义layout)
eg:在layouts文件夹的default.vue中定义布局:
<template>
// 整体布局
<div class="layout">
//头部
<div class="header">
我是header
</div>
<!-- 插槽是页面的内容 -->
<slot></slot>
//底部
<div class="footer">
我是header
</div>
</div>
</template>
<style scoped>
.header {
border: 1px solid red;
text-align: center;
line-height: 80px;
font-size: 30px;
background-color: red;
}
.footer {
border: 1px solid greenyellow;
text-align: center;
line-height: 80px;
font-size: 30px;
background-color: pink;
}
</style>
在app.vue中使用
<template>
<!-- 布局 -->
<NuxtLayout>
<!-- 页面 -->
<NuxtPage></NuxtPage>
</NuxtLayout>
</template>
渲染模式
Nuxt3是支持多种渲染模式,比如:
客户端渲染模式(CSR): 只需将 ssr 设置为 false
服务器端渲染模式(SSR):只需将 ssr 设置为 true
Nuxt插件
- 方式一:直接使用 useNuxtApp() 中的 provide(name, vlaue) 方法直接创建,比如:可在App.vue中创建
// 创建插件
const nuxtApp = useNuxtApp()
nuxtApp.provide('formatData', () => {
return '2023-12-14'
})
nuxtApp.provide("version", "1.0.0")
//使用插件
console.log(nuxtApp.$formatData());
console.log(nuxtApp.$version);
- 方式二:在 plugins 目录中创建插件(推荐)
1.在plugins中使用defineNuxtPlugin定义插件
export default defineNuxtPlugin((nuxtApp) => {
return {
provide: {
//自定义插件,格式化价格,创建vue实例的时候就会注册好
formatPrice: (price: number) => {
return price.toFixed(2);
},
},
};
});
2.在自己需要的组件中使用useNuxtApp( )来使用插件
const nuxtApp = useNuxtApp()
//使用在plugins中定义的插件
console.log(nuxtApp.$formatPrice(100.888));
生命周期
虽然可以在.vue文件中使用生命周期(在vue文件中,只能监听setup之后的生命周期,setup之前的监听不了),但还是建议在plugins中使用生命周期的hooks
export default defineNuxtPlugin((nuxtApp) => {
//监听App生命周期
nuxtApp.hook("app:created", (vueApp) => {
console.log("app:created");
});
nuxtApp.hook("app:beforeMount", (vueApp) => {
console.log("app:beforeMount");
});
nuxtApp.hook("app:mounted", (vueApp) => {
console.log("app:mounted");
});
});
当在单个vue组件中想使用生命周期还是可以像vue中那样去使用,且不需要导入
onMounted(() => {
console.log('onMounted');
})