使用脚手架创建项目
平时我们在创建Vue项目的时候通常是使用 Vue 提供的官方脚手架工具 Vite 或 Vue CLI 来快速搭建项目,具体使用方法如下👇
Vite
npm create vue@latest
Vue CLI
npm install -g @vue/cli
vue create my-project
但是这样通过脚手架创建的项目往往存在一些致命的问题🤯
- 不利于SEO:由于SPA的内容是通过 JavaScript 动态生成,搜索引擎在抓取和索引页面时可能无法正确理解和识别页面内容。
- 不能做多页面,只能单页面:Vue CLI 默认生成的项目是单页面应用,这意味着整个应用只有一个 HTML 文件和懒加载的 JavaScript 文件。这对于构建一些简单的应用是非常方便的,但对于需要多页面的项目来说可能不够灵活。
- title、描述、关键字只有一套:由于SPA只有一个主要的 HTML 文件,因此 title、描述和关键字等 meta 标签通常是动态生成的。
- 渲染完成后才能拿到数据:SPA中的数据通常是通过异步请求获取的,并在页面加载完成后进行渲染。这可能会导致一些展示性内容在页面加载的初始阶段不可见。
为了解决这些问题,我们可以使用预渲染或者服务端渲染(SSR)😋
预渲染
预渲染路由
预渲染是一种优化单页面应用(SPA)的技术,它可以在构建时(而不是在运行时)生成特定路由页面的静态 HTML 文件。
预渲染解决了 SPA 在首次加载时需要等待 JavaScript 完全下载和执行的问题。通过在构建过程中预先生成静态 HTML 文件,预渲染可以提供更快的首次加载速度,同时也有利于搜索引擎的爬虫进行抓取和索引。
可以使用插件来实现预渲染的功能,例如 prerender-spa-plugin
。下面是使用该插件实现预渲染的基本步骤:
- 安装插件:在项目根目录下运行以下命令来安装
prerender-spa-plugin
:
npm install -D prerender-spa-plugin
- 添加预渲染配置:在项目根目录下的
vue.config.js
(如果不存在则手动创建)中,添加以下配置:
const PrerenderSPAPlugin = require('prerender-spa-plugin');
const path = require('path');
module.exports = {
// ...其他配置项
configureWebpack: {
plugins: [
new PrerenderSPAPlugin({
staticDir: path.join(__dirname, 'dist'), // 编译生成的静态文件目录
routes: ['/', '/about', '/contact'] // 需要预渲染的路由列表
})
]
}
};
在上面的配置中,我们指定了需要预渲染的路由列表,可以根据自己的实际需求添加需要预渲染的路由。
修改title描述关键词
vue-meta-info
是一个 Vue.js 插件,用于在 Vue 组件中动态设置页面头部信息,例如 title、meta、link 等。
可以帮助你在每个组件中定义和管理页面头部的内容,使你能够根据组件的不同情况动态修改页面头部信息,以便更好地进行 SEO、社交分享和页面定制等。
以下是使用 vue-meta-info
的基本步骤:
- 安装
vue-meta-info
:在项目根目录下运行以下命令来安装vue-meta-info
插件:
npm install vue-meta-info
- 在 Vue 项目中使用
vue-meta-info
:在main.js
文件或根组件中添加以下代码:
import Vue from 'vue';
import VueMeta from 'vue-meta-info';
Vue.use(VueMeta);
- 在组件中使用
vue-meta-info
:在需要设置页面头部信息的组件中,可以通过metaInfo
属性对象来定义页面头部标签的内容。例如:
export default {
name: 'MyComponent',
metaInfo: {
title: 'Page Title', // 设置页面标题
meta: [
{
name: 'description',
content: 'Page Description' // 设置页面描述
},
{
property: 'og:title',
content: 'Open Graph Title' // 设置 Open Graph 标题
}
],
link: [
{ rel: 'canonical', href: 'https://example.com/page' } // 设置页面的 canonical 链接
]
},
// 组件的其余代码...
};
通过在组件中设置 metaInfo
属性对象,可以根据组件的需要动态地设置页面头部信息。这些信息将在组件渲染时自动更新和应用到页面中。
问题
解决了:
-
预渲染可以解决每个页面单独生成 title 描述关键词的需求。通过预渲染,每个页面可以根据自己的需求定义不同的 title、meta 和其他标签。
-
预渲染生成的静态 HTML 页面可以在构建过程中获取并插入接口数据,这样爬虫可以抓取到页面的内容。这对于 SEO 是非常有益的
存在问题:
- 对于动态路由的配置,预渲染无法直接支持,因为预渲染是在构建过程中生成静态文件,需要提前知道所有可能的路由
- 如果title描述关键词来自于接口的数据,配置到meta-info也是不行的😱
使用场景:
对于适合使用预渲染的项目类型,一般来说适合那些需要 SEO 优化的项目,特别是那些有少量需要做 SEO 的页面的项目。例如,如果您有一个单页面应用程序(SPA),但只有某几个页面需要被搜索引擎索引和优化,可以考虑使用预渲染来针对这些页面进行 SEO 优化。
服务端渲染 SSR
服务端渲染(Server-Side Rendering,简称 SSR)是一种将网页内容在服务器端生成的技术
在传统的客户端渲染中,页面的内容和数据都是通过 JavaScript 在客户端浏览器中动态生成的。这意味着搜索引擎爬虫或不支持 JavaScript 的浏览器无法获取到完整的页面内容,从而影响 SEO 和用户体验😫
优势
服务端渲染通过在服务器端生成完整的页面内容并返回给客户端浏览器,解决了客户端渲染的一些问题。服务端渲染的优势包括:
- SEO 优化:由于服务器返回的是已经生成好的完整页面内容,搜索引擎可以直接读取到页面内容,从而能够更好地索引和排名网站。
- 首次加载性能:服务端渲染可以在服务器端生成完整的 HTML 页面,减少了客户端的渲染时间。这样,用户在首次加载页面时可以更快地获取到内容,提高了用户体验。
- 更好的渐进增强和无障碍支持:由于服务端渲染提供了完整的页面内容,无需依赖 JavaScript,在不支持 JavaScript 的浏览器中也可以正常显示网页内容。
原理
用一张图片清晰的认识到SSR的原理👇
Nuxt 在其中就充当了一个桥梁的作用
- 客户端发起请求:客户端浏览器向服务器发送请求,请求获取特定页面的内容。
- 服务器处理请求:服务器接收到客户端的请求后,根据请求的 URL、参数等信息,确定需要渲染的页面。
- 数据获取和预处理:服务器端通过接口或数据库等方式获取页面所需的数据。这些数据可以是静态的,也可以是动态的。
- 页面模板与数据合并:在服务器端,将获取到的数据与页面的模板进行合并和渲染,生成完整的 HTML 页面。
- 完整 HTML 页面返回客户端:服务器将生成的完整 HTML 页面作为响应返回给客户端浏览器。
Nuxt
安装
npx nuxi@latest init <project-name>
cd <project-name>
yarn install
yarn dev --open
生命周期
服务端生命周期
-
nuxtServerInit(context)
: 在应用程序初始化之前被调用,在服务端渲染期间被调用,可以在这里进行全局数据的初始化或请求。一般用来读取、设置store里的数据 -
middleware({ app, route, redirect })
: 在每次路由切换之前被调用,可以用于定义路由中间件,进行身份验证或重定向等操作。 -
validate({ params, query })
: 跳转页面的时候判断url携带的参数是否合法,失败的话跳转到404页面 -
asyncData({ store, params })
: 可以用于在组件渲染之前异步获取数据并将其合并到组件的数据中。 -
fetch({ app,store, params })
:会在组件每次加载之前被调用。在该方法中,可以使用异步请求方法获取数据,并在组件的数据中进行赋值。
服务端和客户端共有的生命周期
beforeCreated
:在组件实例被创建之前被调用created
:在组件实例被创建后立即调用
路由
基础路由
假设 pages
的目录结构如下:
pages/
--| user/
-----| index.vue
-----| one.vue
--| index.vue
那么,Nuxt.js 自动生成的路由配置如下:
router: {
routes: [
{
name: 'index',
path: '/',
component: 'pages/index.vue'
},
{
name: 'user',
path: '/user',
component: 'pages/user/index.vue'
},
{
name: 'user-one',
path: '/user/one',
component: 'pages/user/one.vue'
}
]
}
动态路由
在 Nuxt.js 里面定义带参数的动态路由,需要创建对应的以下划线作为前缀的 Vue 文件 或 目录。
以下目录结构:
pages/
--| _slug/
-----| comments.vue
-----| index.vue
--| users/
-----| _id.vue
--| index.vue
Nuxt.js 生成对应的路由配置表为:
router: {
routes: [
{
name: 'index',
path: '/',
component: 'pages/index.vue'
},
{
name: 'users-id',
path: '/users/:id?',
component: 'pages/users/_id.vue'
},
{
name: 'slug',
path: '/:slug',
component: 'pages/_slug/index.vue'
},
{
name: 'slug-comments',
path: '/:slug/comments',
component: 'pages/_slug/comments.vue'
}
]
}
你会发现名称为 users-id
的路由路径带有 :id?
参数,表示该路由是可选的。如果你想将它设置为必选的路由,需要在 users/_id
目录内创建一个 index.vue
文件。
持久化存储
在 Nuxt.js 中,由于其采用了服务器端渲染(SSR)的方式,直接使用浏览器端的 document.cookie
方法来设置和读取 cookie 是不可行的。这是因为在服务器端渲染过程中,代码是在服务器上执行的,而不是在客户端浏览器中执行。
如果需要在 Nuxt.js 中使用 cookie,可以通过使用插件来解决这个问题。
npm install cookie-universal-nuxt
在 nuxt.config.js
中配置
modules:['cookie-universal-nuxt']
现在,可以在 Nuxt.js 项目中的页面、组件或其他地方使用 $cookies
对象来设置和读取 cookie。
export default {
created() {
this.$cookies.set('username', 'John Doe')
},
methods: {
getUsername() {
return this.$cookies.get('username')
}
}
}
跨域
-
在
nuxt.config.js
配置文件。 -
在该配置文件中新增一个名为
proxy
的属性,并指定要代理的接口地址及相关配置。例如:
export default {
// 其他配置...
modules:['@nuxt/proxy']
proxy: {
'/api': {
target: 'http://api.example.com',
pathRewrite: { '^/api': '/' }
}
}
}
- 在上面的示例中,我们将以
/api
开头的请求代理到http://api.example.com
。同时,我们使用pathRewrite
来重写请求路径,将/api
去掉。 - 在代码中使用相对路径(以
/api
开头)来发起请求。Nuxt.js 会自动将这些请求代理到目标地址,解决跨域问题。
结尾
预渲染和服务端渲染都是常用的渲染方式,它们在不同的场景和需求下有各自的优缺点。在选择使用预渲染还是服务端渲染时,需要结合实际情况进行权衡。
最终的选择应该综合考虑项目需求、技术能力和用户体验等因素。预渲染适用于内容稳定、不需要频繁更新的页面,服务端渲染适用于需要动态数据获取或频繁更新的页面。通过权衡优缺点并结合实际情况,可以选择最合适的渲染方式来搭建高效、优化的 Nuxt.js 应用程序。
原文链接:https://juejin.cn/post/7332409645007077428 作者:Tooy8