1、SSR
将组件或页面通过服务器生成html字符串,再发送到浏览器,简单理解就是服务器返回的不是接口数据,而是一整个页面的HTML结构
优点:
- 响应快,首屏渲染快
- 对搜索引擎友好,搜索引擎爬虫可以看到完整的程序源码,有利于SEO
2、Nuxt3介绍
Nuxt
Nuxt.js 是一个基于 Vue.js 的通用应用框架,一个用于Vue.js 开发SSR应用的一站式解决方案。它的优点是将原来几个配置文件要完成的内容,都整合在了一个nuxt.config.js,封装与扩展性完美的契合。
Nuxt3
Nuxt3,整合vite + vue3 + composition api + ts、CLI、DevTools、Nuxt Kit,这是一个体系完备的通用开发框架,能提供良好的代码组织、极高的开发效率、开发体验和服务端渲染/静态网站生成(SSR/SSG)能力。
Nuxt 3 的重构精简了内核,并且让速度更快,开发体验更好。
新特性:
- 相当于75倍小的服务器部署,和更小的客户端包;
- 基于Nitro的动态代码分离和冷启动;
- 在任一组件中,渲染前和渲染后过程中,都可以获取数据;
- 使用Composition API和Nuxt 3的可组合组件来实现真正的代码重用;
- 零依赖的脚手架,便于模块集成;
- 在浏览器中,能够快速处理信息以及快速修复;
- 更快的构建时间,更小的包的体积,并且不需要额外配置;
- 快如闪电般的HMR,当你用了Vite;
- Vue3是你下一个应用程序的重要基石;
- 使用原生的TypeScript和ESM构建,也不需要额外的步骤。
Nitro引擎
在开发环境中,它使用了Rollup和Node.js workers对你的服务器代码和上下文进行了隔离。它还通过server/api下的文件和server/middleware下的服务器中间件,来生成你的Api。
在生产环境中,它会把你的程序和server一起放到.output里,这个.output很轻,它被简化过了,并移除了Node.js的modules(polyfills除外)。你也可以发布这个output到任一支持Javascript的Nodejs、Serverless、Workers、Edge-side rendering或者纯静态的系统当中去。
output包含了可以运行的代码,在任一环境中运行你Nuxt server(包括实验性的浏览器Service Workers),并且output也会给你静态文件,使它成为一个真正的JAMStack混合框架,此外它也实现了本地存储层,支持多个源,驱动和本地资源。
3、实战
-
Quick Start
npx nuxi init nuxt3-app
可以看到以上就是一个最小应用,在nuxt3中如果没有pages/目录,则表示不会包含vue-router依赖,打包体积更小,有pages目录才会引入路由库
nuxt3 在开发过程中,多数都是基于约定的开发模式,即: 根目录创建一个 pages 目录, servers 目录,components目录这些,都是约定好的。只需要按约定的规则开发即可
-
目录结构
- components
Nuxt3 会自动导入在 components 目录里的组件。实际是继承自 Nuxt2 中的 @nuxt/components , 扫描代码中出现的组件来达到 build 时的一种 "Tree Shaking" 。
| components/
--| TheHeader.vue
--| TheFooter.vue
<template>
<div>
<TheHeader />
<slot />
<TheFooter />
</div>
</template>
- composables
在Nuxt2没有,是 3 新加的文件夹,类似于我们写 react 时存放的一些公共 hooks ,也是全局 自动导入 的
- pages
pages 这一块大抵和原先类似,不过值得注意的是,动态路由(Dynamic Routes) 有变化 ,它抛弃了原先那种 _xxx 变量的用法,采用中括号形式。
- plugins
plugins 改动最大的地方,就是它无需在 nuxt.config.[ts/js] 中手动注册了,只要放在这个目录里的,都会进行 自动注册(auto-registered) 。
- server
server 这个文件夹,有点像原先 serverMiddleware 的用法,里面存放着一些 服务端中间件 还有 API endpoints。
-
路由
-
动态路由
如果在pages目录下文件名或者文件夹名称里面包含了方括号,它们将被转换为动态路由参数。目录结构如下:
<template>
<div>
{{ $route.params.group }}
{{ $route.params.id }}
</div>
</template>
通过 /users-admins/123 导航即可
-
嵌套路由
目录和文件同名,就制造了嵌套路由
child.vue
<template>
<div>
<h1>child page</h1>
</div>
</template>
父组件中使用NuxtChild组件显示嵌套子组件内容
<template>
<div>
<h1>parent page</h1>
<!-- 子组件出口 -->
<NuxtChild></NuxtChild>
</div>
</template>
-
数据获取
- useAsyncData
在页面、组件或插件中都可以使用useAsyncData获取那些异步数据
const {
data: Ref<DataT>, // 返回的数据
pending: Ref<boolean>, // 加载状态指示器
refresh: (force?: boolean) => Promise<void>, // 强制刷新函数
error?: any // 请求失败错误信息
} = useAsyncData(
key: string, // 唯一键用于多次请求结果去重
handler: (ctx?: NuxtApp) => Promise<Object>, // 返回数值的异步函数
options?: { lazy: boolean, server: boolean } // lazy:是否在路由之后请求数据;server:是否在服务端请求数据
)
- useFetch
页面、组件或者插件中可以使用useFetch获取任意URL资源。
useFetch是对useAsyncData包装,自动生成key同时推断响应类型,用起来更简单。
const {
data: Ref<DataT>,
pending: Ref<boolean>,
refresh: (force?: boolean) => Promise<void>,
error?: any
} = useFetch(url: string, options?)
- useLazyAsyncData 和 useLazyFetch 等效于
useAsyncData和useFetch,仅设置了lazy选项为true,所以它不会阻塞路由导航,所以需要处理data为null的情况