搭建Nuxt3项目分享
Nuxt3
自从Vue3发布后,学习Vue3就形成了一个趋势和热潮。
Vue3相比Vue2,引入tree-shaking,使得打包的整体体积变小了;在兼顾vue2的options API的同时还推出了composition API,大大增加了代码的逻辑组织和代码复用能力;采用proxy替换了之前的defineProperty,proxy有多达13种拦截方法;增加了TypeScript支持来对项目的规范做更进一步的约束等等。
Nuxt3 就是基于 Vue3 来做的一款混合式 Vue框架。
我们可以用Nuxt3来开发服务端渲染的项目,也就是常说的ssr;
SPA
SPA(单页面应用),只有一个HTML页面,通过路由实现页面内的局部切换,公共资源部分只加载一次。而Vue框架所开发的项目就属于SPA项目。
平常写的普通页面就是MPA(多页面应用),通过a标签实现页面切换,每次切换页面都要重新加载公共资源部分。
优点
1.无刷新界面,内容的改变不需要重新加载整个页面,良好的交互体验;
2.基于spa这一点,减轻服务器压力,吞吐能力会提高几倍;
3.前后端工作分离模式;
缺点
1.首屏加载慢,业务随着代码量增加而增加,不利于首屏优化;
2.各个浏览器的版本兼容性不一样;
3.不利于seo,即搜索引擎抓取内容非常少;
4.页面复杂度提高;
SPA(单页面应用) 既有它的优点也有它的缺点,我们只能根据我们开发项目的业务的实际需求来进行酌情取舍。
对于SPA(单页面应用) 的首屏加载慢,我们可以采取的一些常见措施:
1.减少入口文件体积
2.静态资源本地缓存以及一些资源的压缩处理
3.UI组件按需加载
4.避免重复加载组件
5.开启gzip压缩
6.使用SSR
而SSR也就是我们所说的服务端渲染,组件或页面通过服务器生成html字符串,再发送到浏览器。关于Vue项目的SSR,Vue3官网有给出一些解决方案:更通用的解决方案
而这里分享,我们则采用Nuxt3框架,它是一个构建于 Vue 生态系统之上的全栈框架,为编写 Vue SSR 应用提供开发,同时还可以把它当作一个静态站点生成器来用。
CSR 与 SSR
渲染分为客户端渲染(CSR)和服务端渲染(SSR)。
CSR
CSR(client side render) 服务端只提供json格式的数据,渲染成什么样子由客户端通过JavaScript控制,而SPA的Vue项目则就是这种CSR(client side render) 客户端渲染。
<!DOCTYPEhtml><htmllang="zh-CN"><head><metacharset="UTF-8"/><linkrel="icon"href="/favicon.ico"/><metaname="viewport"content="width=device-width,initial-scale=1.0"><title>后台管理系统</title></head><body><noscript><strong>很抱歉,在没有启用JavaScript的情况下,默认不能正常工作</strong></noscript><divid="app"></div><scripttype="module"src="/src/main.ts"></script></body></html>
从以上代码,我们可以看到在index.html的这个文件里面,body里面只有一个div
<divid="app"></div>
和一个script的引入
<scripttype="module"src="/src/main.ts"></script>
在main.ts中,我们可以看到Vue3是将项目的App.vue页面组件挂载到 id 为 app 的dom节点上的。
import{ createApp }from'vue';import App from'./App.vue';import router from'./router';const app =createApp(App);
app.use(router);
router.isReady().then(()=> app.mount('#app'));
Vue通过createApp创建了Vue实例对象,并通过mount进行挂载。
而CSR(client side render) 客户端渲染通过加载解析index.html,对遇到引入的script加载运行,进行页面的信息和数据的渲染。
SSR
SSR(server side render) 服务端渲染,就是组件或页面通过服务端装填内容数据生成html,客户端进行接收和解析。
SSR vs. SSG
静态站点生成 (Static-Site Generation,缩写为 SSG),也被称为预渲染,是另一种流行的构建快速网站的技术。如果用服务端渲染一个页面所需的数据对每个用户来说都是相同的,那么我们可以只渲染一次,提前在构建过程中完成,而不是每次请求进来都重新渲染页面。预渲染的页面生成后作为静态 HTML 文件被服务器托管。
SSG 保留了和 SSR 应用相同的性能表现:它带来了优秀的首屏加载性能。同时,它比 SSR 应用的花销更小,也更容易部署,因为它输出的是静态 HTML 和资源文件。这里的关键词是静态:SSG 仅可以用于消费静态数据的页面,即数据在构建期间就是已知的,并且在多次部署期间不会改变。每当数据变化时,都需要重新部署。
SSG 也非常适合构建基于内容的网站,比如文档站点或者博客。
Nuxt3安装
通过终端执行安装命令创建Nuxt3项目
npx nuxi init 项目名
安装依赖
npm i
以开发模式启动项目
npm run dev
启动成功后,我们可以通过3000的端口打开项目访问。
Naive-UI
Naive UI 是一个 Vue3 的组件库,用 TypeScript 编写,主题可调。
安装
npm i -D naive-ui
我们可以在 SFC 中按需导入使用
<template><n-button>按钮</n-button></template><script>import{ defineComponent }from'vue'import{ NButton }from'naive-ui'exportdefaultdefineComponent({components:{
NButton
}})</script>
关于naive-ui在Nuxt3的应用,naive-ui官网可以参考服务端渲染
Nuxt3使用naive-ui的步骤:
1.我们需要确保naive-ui的版本 >= 2.29.0
2.需要安装 naive-ui 和 @css-render/vue3-ssr
3.在Nuxt3项目自动生成的 nuxt.config.ts 文件增添下列配置:
import{ defineNuxtConfig }from'nuxt'// https://v3.nuxtjs.org/api/configuration/nuxt.configexportdefaultdefineNuxtConfig({build:{transpile:
process.env.NODE_ENV==='production'?['naive-ui','vueuc','@css-render/vue3-ssr','@juggle/resize-observer']:['@juggle/resize-observer']},vite:{optimizeDeps:{include:
process.env.NODE_ENV==='development'?['naive-ui','vueuc','date-fns-tz/esm/formatInTimeZone']:[]}}})
4.Nuxt3项目的plugins的文件夹中增加 naive-ui.ts 文件:
import{ setup }from'@css-render/vue3-ssr'import{ defineNuxtPlugin }from'#app'exportdefaultdefineNuxtPlugin((nuxtApp)=>{if(process.server){const{ collect }=setup(nuxtApp.vueApp)const originalRenderMeta = nuxtApp.ssrContext?.renderMeta
nuxtApp.ssrContext = nuxtApp.ssrContext ||{}
nuxtApp.ssrContext.renderMeta=()=>{if(!originalRenderMeta){return{headTags:collect()}}const originalMeta =originalRenderMeta()if('then'in originalMeta){return originalMeta.then((resolvedOriginalMeta)=>{return{...resolvedOriginalMeta,headTags: resolvedOriginalMeta['headTags']+collect()}})}else{return{...originalMeta,headTags: originalMeta['headTags']+collect()}}}}})
5.在Nuxt3项目中的app.vue中配置naive-ui,调整主题:
<template><NConfigProvider:locale="zhCN":date-locale="dateZhCN":theme-overrides="themeOverrides"inline-theme-disabled><nuxtLayout><NuxtPage/></nuxtLayout></NConfigProvider></template><scriptsetup>import{ zhCN, dateZhCN, NConfigProvider }from"naive-ui";/**
* js 文件下使用这个做类型提示
* @type import('naive-ui').GlobalThemeOverrides
*/const themeOverrides ={common:{primaryColor:"#FC8952",primaryColorHover:"#FC8952",primaryColorPressed:"#FC8952",primaryColorSuppl:"#FC8952",},Button:{textColor:"#FC8952",border:"1px solid #FF763B",textColor:"#FF763B",}};</script>
6.脱离上下文的 API的应用:
在Nuxt3项目中,我们会碰到需要在一些在setup外调用 dialog、message、notification、loadingBard 的情况;naive-ui为我们提供了 createDiscreteApi 来构建对应的 API;需要调用的API则在参数的数组中注册;
示例:
import{
createDiscreteApi
}from"naive-ui"const{ message }=createDiscreteApi(["message"])
message.error(msg ||'服务端错误')
在Nuxt3项目的页面中,在使用setup语法糖时,我们使用naive-ui的组件不需要进行注册,它会自行注册以及导出:
<template><divclass="pt-[14rem]"><n-resultstatus="500"title="500 服务器错误":description="error.message"><template#footer><n-button@click="handleError">回到首页</n-button></template></n-result></div></template><scriptsetup>import{ NButton, NResult }from"naive-ui";const props =defineProps({error: Object,});consthandleError=()=>clearError({redirect:"/"});</script>
版权归原作者 patricks_star 所有, 如有侵权,请联系我们删除。