VueSSR详解 VueServerRenderer Nutx

SSR

Vue中的SSR(Server-Side Rendering,服务器端渲染)是一种将页面的渲染工作从客户端转移到服务器端的技术。以下是对Vue中SSR的详细解释:

一、SSR的工作原理

在传统的客户端渲染(CSR)中,页面的渲染是在浏览器中进行的。浏览器通过请求获取页面的HTML和JavaScript代码,然后在客户端进行页面的渲染和交互。而在SSR中,服务器接收到请求后,会执行Vue应用的服务器端代码,启动Vue实例,并利用vue-server-renderer模块将Vue组件及其依赖关系转化为HTML字符串。这个过程通常伴随着数据预取,即在服务器端调用API获取视图所需的数据,并将其注入到组件的上下文中,确保首次渲染时就有完整的内容。然后,服务器将这个完整的HTML页面发送给浏览器,浏览器无需再执行额外的JavaScript,即可直接展示出页面内容。

二、SSR的优势

  1. 更快的首屏加载:由于服务器在响应请求时已经生成了完整的HTML页面,所以用户打开页面时可以立即看到内容,无需等待JavaScript下载和执行。这一点在慢网速或者运行缓慢的设备上尤为重要。
  2. 更好的SEO:搜索引擎爬虫能够抓取到完整的HTML页面,并且页面内容可直接被搜索引擎索引,从而提升了页面在搜索引擎中的排名。
  3. 统一的心智模型:开发者可以使用相同的语言以及相同的声明式、面向组件的心智模型来开发整个应用,而不需要在后端模板系统和前端框架之间来回切换。

三、SSR的限制和挑战

  1. 服务器负载:在Node.js中渲染一个完整的应用要比仅仅托管静态文件更加占用CPU资源。因此,如果预期有高流量,需要为相应的服务器负载做好准备,并采用合理的缓存策略。
  2. 构建和部署的复杂性:SSR应用需要一个能让Node.js服务器运行的环境,不像完全静态的SPA那样可以部署在任意的静态文件服务器上。此外,还需要处理服务器与客户端之间的数据同步、路由等问题。
  3. 浏览器端特定的代码限制:一些外部库可能需要特殊处理才能在服务端渲染的应用中运行。浏览器端特定的代码只能在某些生命周期钩子中使用。

四、Vue中SSR的实现

在Vue中实现SSR需要使用Vue官方提供的服务器端渲染框架(Vue Server Renderer),并配置好服务器环境。以下是一个简单的实现流程:

  1. 安装依赖:确保项目中已经安装了Vue、VueRouter、Vue Server Renderer等依赖。
  2. 创建服务器入口文件:通常命名为server.js或类似名称。在该文件中引入必要的模块,包括Vue、Vue Server Renderer、Express(或其他后端框架)等。
  3. 配置路由和数据:创建一个Vue实例,并配置路由、数据等相关内容。
  4. 渲染逻辑:使用Vue Server Renderer的createRenderer方法创建一个renderer实例。在路由处理器中调用renderer实例的renderToString方法来将Vue实例渲染为字符串。
  5. 处理静态资源:使用Webpack进行服务器端渲染的配置,以处理静态资源的导出和加载。
  6. 客户端激活:在服务器端渲染后,需要在客户端激活Vue实例,以便能够响应交互事件和更新页面。可以通过在HTML中插入一个JavaScript脚本,并在脚本中使用createApp方法来创建客户端应用程序实例。

五、使用Nuxt框架简化SSR开发

Nuxt是一个基于Vue的SSR框架,它提供了许多内置的功能和配置,使得开发SSR应用变得更加简单和高效。使用Nuxt框架,开发者可以更快地构建和部署SSR应用,而无需从头开始配置和编写大量的服务器端代码。

综上所述,Vue中的SSR技术通过结合前后端的能力,既保证了初始加载时的性能体验和SEO优化,又保留了Vue.js在客户端高效更新和交互的特性。然而,它也有一些限制和挑战,需要开发者在设计和实现时进行权衡和考虑。

Vue Server Renderer

服务器端渲染(SSR, Server-Side Rendering)是一种在服务器上生成完整的 HTML 页面,然后将其发送到客户端的技术。Vue.js 提供了一个官方工具 Vue Server Renderer 来实现这一点。以下是一个简单的 Vue SSR 示例。

1. 设置项目

首先,我们需要初始化一个新的 Node.js 项目并安装必要的依赖。

mkdir vue-ssr-example 
cd vue-ssr-example 
npm init -y 
npm install vue vue-server-renderer express

2. 创建 Vue 组件

在 src 文件夹中创建一个 App.vue 文件,这是我们的根组件。

mkdir src

src/App.vue:

<template> 
<div id="app"> 
<h1>Hello, Server-Side Rendering with Vue!</h1> 
</div> 
</template> <script> 
export default { 
name: 'App' 
} 
</script> <style> 
#app { 
font-family: Avenir, Helvetica, Arial, sans-serif; 
-webkit-font-smoothing: antialiased; 
-moz-osx-font-smoothing: grayscale; 
text-align: center; 
color: #2c3e50; 
margin-top: 60px; 
} 
</style>

3. 创建服务器

在项目根目录中创建一个 server.js 文件,用于设置 Express 服务器和 Vue SSR

server.js:

const express = require('express'); 
const { createBundleRenderer } = require('vue-server-renderer'); 
const fs = require('fs'); 
const path = require('path'); 
const resolve = file => path.resolve(__dirname, file); const server = express(); // 创建服务器渲染器 
const template = fs.readFileSync(resolve('./index.template.html'), 'utf-8'); 
const serverBundle = require('./dist/vue-ssr-server-bundle.json'); 
const clientManifest = require('./dist/vue-ssr-client-manifest.json'); const renderer = createBundleRenderer(serverBundle, { 
runInNewContext: false, 
template, 
clientManifest 
}); server.use(express.static(path.join(__dirname, 'dist'))); server.get('*', (req, res) => { 
const context = { url: req.url }; 
renderer.renderToString(context, (err, html) => { 
if (err) { 
if (err.code === 404) { 
res.status(404).send('Page not found'); 
} else { 
res.status(500).send('Internal Server Error'); 
} 
} else { 
res.send(html); 
} 
}); 
}); const PORT = process.env.PORT || 8080; 
server.listen(PORT, () => { 
console.log(`Server is running at http://localhost:${PORT}`); 
});

4. 创建 HTML 模板

在项目根目录中创建一个 index.template.html 文件,这是用于渲染 Vue 应用的模板。

index.template.html:

<!DOCTYPE html> 
<html lang="en"> 
<head> 
<meta charset="UTF-8"> 
<meta name="viewport" content="width=device-width, initial-scale=1.0"> 
<title>Vue SSR Example</title> 
<!-- 用于插入客户端脚本 --> 
<!-- vue-ssr-client-manifest will be auto injected --> 
</head> 
<body> 
<!-- 这是应用挂载点 --> 
<div id="app"><!-- server-rendered HTML will be injected here --></div> 
<!-- built files will be auto injected --> 
</body> 
</html>

5. 配置 Webpack

在项目根目录中创建一个 webpack.config.js 文件,用于配置 Webpack 打包。

webpack.config.js:

const path = require('path'); 
const VueSSRServerPlugin = require('vue-server-renderer/server-plugin'); 
const VueSSRClientPlugin = require('vue-server-renderer/client-plugin'); module.exports = { 
entry: './src/entry-server.js', 
target: 'node', 
output: { 
libraryTarget: 'commonjs2', 
path: path.resolve(__dirname, 'dist'), 
filename: 'vue-ssr-server-bundle.json' 
}, 
resolve: { 
alias: { 
'vue$': 'vue/dist/vue.esm.js' 
}, 
extensions: ['.js', '.vue', '.json'] 
}, 
module: { 
rules: [ 
{ 
test: /\.vue$/, 
loader: 'vue-loader' 
}, 
{ 
test: /\.js$/, 
loader: 'babel-loader', 
exclude: /node_modules/ 
} 
] 
}, 
plugins: [ 
new VueSSRServerPlugin() 
] 
}; // 需要另外配置一个 webpack 配置用于生成客户端文件 
const clientConfig = { 
entry: './src/entry-client.js', 
target: 'web', 
output: { 
path: path.resolve(__dirname, 'dist'), 
filename: 'bundle.js' 
}, 
resolve: { 
alias: { 
'vue$': 'vue/dist/vue.esm.js' 
}, 
extensions: ['.js', '.vue', '.json'] 
}, 
module: { 
rules: [ 
{ 
test: /\.vue$/, 
loader: 'vue-loader' 
}, 
{ 
test: /\.js$/, 
loader: 'babel-loader', 
exclude: /node_modules/ 
}, 
{ 
test: /\.(png|jpe?g|gif|svg)$/, 
loader: 'file-loader', 
options: { 
name: '[name].[hash].[ext]?[hash]' 
} 
} 
] 
}, 
plugins: [ 
new VueSSRClientPlugin() 
] 
}; module.exports = [clientConfig, module.exports]; // 返回两个配置

6. 创建入口文件

在 src 文件夹中创建两个入口文件:entry-server.js 和 entry-client.js

src/entry-server.js:

import { createApp } from './app'; export default context => { 
return new Promise((resolve, reject) => { 
const { app, router } = createApp(); router.push(context.url); router.onReady(() => { 
const matchedComponents = router.getMatchedComponents(); 
if (!matchedComponents.length) { 
return reject({ code: 404 }); 
} resolve(app); 
}, reject); 
}); 
};

src/entry-client.js:

import { createApp } from './app'; const { app, router } = createApp(); router.onReady(() => { 
app.$mount('#app'); 
});

src/app.js:

import Vue from 'vue'; 
import App from './App.vue'; 
import router from './router'; export function createApp() { 
const app = new Vue({ 
router, 
render: h => h(App) 
}); return { app, router }; 
}

src/router/index.js:

import Vue from 'vue'; 
import Router from 'vue-router'; Vue.use(Router); export default new Router({ 
routes: [ 
{ 
path: '/', 
name: 'Home', 
component: () => import('../App.vue') 
} 
] 
})

7. 构建项目

在项目根目录中运行以下命令来构建项目:

npm install webpack webpack-cli webpack-node-externals babel-loader @babel/core @babel/preset-env vue-loader vue-template-compiler file-loader --save-dev 
npx webpack --config webpack.config.js

注意:Webpack 5 用户可能需要调整配置,使用 webpack-cli 而不是全局 webpack 命令。

8. 启动服务器

在项目根目录中运行以下命令来启动服务器:

node server.js

现在,你可以打开浏览器访问 http://localhost:8080,你应该会看到服务器端渲染的 Vue 应用。

这个示例展示了如何使用 Vue 和 Express 实现简单的服务器端渲染。根据实际需求,你可以进一步扩展和优化这个示例。

Nutx

以下是一个关于Nuxt框架的使用案例,涵盖了从包安装到入门使用的整个过程:

一、Nuxt框架安装

  1. 确保环境准备

    • 安装Node.js和npm(Node包管理器)。
    • 可以通过命令行运行node -vnpm -v来检查它们的版本。
  2. 全局安装Vue CLI(如果尚未安装):

    npm install -g vue-cli

  3. 创建Nuxt项目

    • 使用Vue CLI(或npx)创建一个新的Nuxt项目。
      npx create-nuxt-app my-nuxt-app
    • 按照提示完成项目设置,如项目名称、编程语言、包管理器、UI框架等。
  4. 进入项目目录并安装依赖

    cd my-nuxt-app 
    npm install

二、Nuxt项目入门使用

  1. 项目目录结构
    • pages/:页面组件目录,每个.vue文件都会生成对应的路由。
    • components/:Vue组件目录,用于存放可复用的Vue组件。
    • static/:静态资源目录,用于存放静态文件如图片、字体等。
    • store/:Vuex状态管理目录,用于管理应用的全局状态。
    • nuxt.config.js:Nuxt全局配置文件,用于覆盖默认配置。
  2. 创建页面组件
    <template>  <div>  <h1>欢迎来到我的Nuxt应用</h1>  </div>  
    </template>  <script>  
    export default {  // 页面组件的逻辑代码  
    }  
    </script>

  3. 运行开发服务器
    • 访问http://localhost:3000即可在浏览器中查看Nuxt应用。
  4. 使用asyncData在服务器端获取数据
    • 在页面组件中,可以使用asyncData方法在服务器端获取数据,并将数据注入到组件中。
      <template> 
      <div> 
      <h1>文章列表</h1> 
      <ul> 
      <li v-for="article in articles" :key="article.id">{{ article.title }}</li> 
      </ul> 
      </div> 
      </template> <script> 
      export default { 
      async asyncData({ params }) { 
      const articles = await fetch('https://api.example.com/articles') 
      .then(res => res.json()); 
      return { articles }; 
      } 
      } 
      </script>

      配置路由和导航守卫

      • Nuxt会自动根据pages/目录下的.vue文件生成路由。
      • 可以在nuxt.config.js中配置路由的扩展属性,如中间件、别名等。
      • 可以在页面组件中使用middleware属性或全局中间件来定义导航守卫。

  5. 使用Vuex进行状态管理
    • store/目录下创建Vuex模块,如index.js
    • 在Vuex模块中定义状态、mutations、actions等。
    • 在页面组件中通过this.$store.statethis.$store.getters访问状态,通过this.$store.committhis.$store.dispatch修改状态。
  6. 构建和部署
    • 使用npm run build命令构建生产环境的Nuxt应用。
    • 将构建后的文件部署到服务器上,如使用Nginx或Apache等Web服务器。

三、总结

通过上述步骤,我们成功安装并入门使用了Nuxt框架。Nuxt框架提供了许多内置的功能和配置,使得开发Vue SSR应用变得更加简单和高效。同时,Nuxt还支持丰富的插件和模块生态系统,可以根据项目需求进行扩展和定制。希望这个使用案例能够帮助你快速上手Nuxt框架的开发。

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

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

相关文章

指针(c语言)

一.指针的定义 1.内存被划分为一个一个内存单元&#xff0c;对内存单元进行编号&#xff0c;这些编号称为内存单元的地址&#xff0c; 其中指针就是存放地址的容器 2.平常说的指针&#xff0c;其实就是指针变量 注意&#xff1a; 1个内存单元的大小是1个字节&#xff0c;如果是…

一篇文章了解TCP/IP模型

TCP/IP模型&#xff0c;即传输控制协议/互联网协议模型&#xff08;Transmission Control Protocol/Internet Protocol Model&#xff09;&#xff0c;是互联网及许多其他网络上使用的分层通信模型。以下是对TCP/IP模型的详细介绍&#xff1a; 一、定义与组成TCP/IP模型是一个四…

AI开发-三方库-torchvision

1 需求 2 torchvision.datasets CLASS torchvision.datasets.MNIST(root: Union[str, Path], train: bool True, transform: Optional[Callable] None, target_transform: Optional[Callable] None, download: bool False) roottraintransformdownload MNIST — Torchv…

动手学深度学习67 自注意力

1. 自注意力 k 窗口的大小 每个kernel窗口都可以并行计算&#xff0c;GPU计算 最长路径&#xff1a;信息是怎么传递的 filed–视野 自注意力适合处理比较长的文本&#xff0c;无视距离&#xff0c;可以看比较长的文本&#xff0c;但是计算复杂度高【代价】 位置信息加到输入数…

【Docker故障处理篇】运行容器报错“all predefined address pools have been fully subnetted”解决方法

【Docker故障处理篇】运行容器报错“all predefined address pools have been fully subnetted”解决方法 一、Docker环境介绍2.1 本次环境介绍2.2 本次实践介绍二、故障现象三、故障分析3.1 报错分析3.2 查询当前Docker网络数量四、解决方法4.1 方法一4.2 方法二4.3 方法三五、…

Hadoop-004-Big Data Tools插件的使用

一、Big Data Tools插件配置流程 1、安装Big Data Tools插件 以IntelliJ IDEA 2024.2.3为例打开setting, 搜索安装Big Data Tools插件后重启IDEA 2、Windows系统基础配置 Windows系统需要做一些基础设置&#xff0c;配合插件使用,将之前下载的hadoop-3.2.4.tar.gz 解压到D…

【VS+QT】联合开发踩坑记录

最新更新日期&#xff1a;2024/11/05 0. 写在前面 因为目前在做自动化产线集成软件开发相关的工作&#xff0c;需要用到QT&#xff0c;所以选择了VS联合开发&#xff0c;方便调试。学习QT的过程中也踩了很多坑&#xff0c;在此记录一下&#xff0c;提供给各位参考。 1. 环境配…

Git常用高频命令学习

gitBash命令行&#xff1a; cd d git clone gitserver192.168.1.78:/gitrepo/Aries gitk git branch develop 创建本地分支 git branch -d develop 删除本地分支 git branch -a 查看所有本地和远程分支 git status 状态 提交分支 git add . 加入到提交队列 git commit -m …

前端面筋(持续更新)

海康威视一面(结果未出) 开头&#xff1a;自我介绍和面试官聊聊天 后面&#xff1a;开始拷打 为什么Vue组件中data属性是一个函数&#xff1f; vue中的key的作用或者原理是什么&#xff1f;说一下你对它的理解 在Vue的生命周期里面&#xff0c;beforeCreate函数里面干了什…

JS渗透(安全)

JS逆向 基本了解 作用域&#xff1a; 相关数据值 调用堆栈&#xff1a; 由下到上就是代码的执行顺序 常见分析调试流程&#xff1a; 1、代码全局搜索 2、文件流程断点 3、代码标签断点 4、XHR提交断点 某通js逆向结合burp插件jsEncrypter 申通快递会员中心-登录 查看登录包…

OJ03:删除有序数组中的重复项

目录 题目思路分析代码展示&#xff1a; 题目 —给你一个 非严格递增排列 的数组 nums &#xff0c;请你 原地 删除重复出现的元素&#xff0c;使每个元素 只出现一次 &#xff0c;返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。…

DistilQwen2:通义千问大模型的知识蒸馏实践

作者&#xff1a;岳元浩&#xff08;顾城&#xff09;、汪诚愚&#xff08;熊兮&#xff09;、严俊冰&#xff08;玖烛&#xff09;、黄俊&#xff08;临在&#xff09; 背景 在人工智能快速发展的今天&#xff0c;大语言模型已经成为了人工智能的研究热点。其中&#xff0c;…

程序员也要认识下“信创产业”

兄弟姐妹们&#xff0c;大家初入社会会觉得技术是第一位&#xff0c;我呸&#xff0c;其实你在那个领域敲代码的选择才是最重要的&#xff0c;选对了领域绝对比你背上100个面试题目强&#xff0c;今天带大家了解下信创产业。 信创产业&#xff0c;即信息技术应用创新产业&#…

Rust 力扣 - 1423. 可获得的最大点数

文章目录 题目描述题解思路题解代码题目链接 题目描述 题解思路 题目所求结果存在下述等式 可获得的最大点数 所有卡牌的点数之和 - 长度为&#xff08;卡牌数量 - k&#xff09;的窗口的点数之和的最小值 我们遍历长度为&#xff08;卡牌数量 - k&#xff09;的窗口&#…

前端实现json动画(附带示例)

前端实现json动画&#xff08;附带示例&#xff09; 使用lottie制作动画。1.json动画2.实现效果3.git仓库4.运行5.json动画天堂6.代码7. 经常使用的方法 使用lottie制作动画。 1.json动画 废话不多说&#xff0c;直接看效果图2.实现效果 3.git仓库 https://gitee.com/chaiach…

[ vulnhub靶机通关篇 ] 渗透测试综合靶场 DarkHole:1 通关详解 (附靶机搭建教程)

&#x1f36c; 博主介绍 &#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 _PowerShell &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 &#x1f389;点赞➕评论➕收藏 养成习…

成都睿明智科技有限公司共赴抖音电商蓝海

在这个短视频风起云涌的时代&#xff0c;抖音作为现象级的社交媒体平台&#xff0c;不仅改变了人们的娱乐方式&#xff0c;更悄然间重塑了电商行业的格局。在这片充满机遇与挑战的蓝海中&#xff0c;成都睿明智科技有限公司凭借其敏锐的市场洞察力和专业的服务能力&#xff0c;…

Centos 网络接口打vlan标签

Centos 网络接口打vlan标签 本次使用给bond打vlan标签&#xff0c;其实其他普通接口也一样 Centos创建bond前需要关闭NetworkManager [root192 network-scripts]# systemctl disable NetworkManager --now Removed symlink /etc/systemd/system/multi-user.target.wants/Netwo…

github - ssh 配置 key、下载repo

1、设置位置 https://github.com/settings/keys 2、生成 Key ssh-keygen -t rsa -b 4096 -C "xx@x.com" 成功后,查看 cat ~/.ssh/id_rsa.pub 得到数据类似: ssh-rsa AAAAB3NzaC1yc2EA...4thQm4FKtB/c= xx3、下载代码 下载方式,选择 ssh,但使用 git clone 下…

ElMessageBox 内容自定义

1. ElmessageBox弹出框显示内容设置字体颜色&#xff1a; 代码内容&#xff1a; const saveToGroup (row: Customers) > {ElMessageBox.confirm(h("i",{ style: "color: #409EFF" },"未建档客户公司无法创建线索/商机/礼品申请。"),"…