当前位置: 首页 > wzjs >正文

宁夏做网站邯郸市开网店儿网络公司

宁夏做网站,邯郸市开网店儿网络公司,wordpress根据用户显示文章,成都家装设计公司前段时间刚写完毕业论文,现在一上来就是“基于”,哈哈。🤯 这篇文章持续更新,涉及到的技术栈是Koa、Vue和Vite (用React手搓服务端渲染好麻烦)。但是现在能上生产的服务端渲染估计是Next(配合Re…

前段时间刚写完毕业论文,现在一上来就是“基于”,哈哈。🤯 这篇文章持续更新,涉及到的技术栈是Koa、Vue和Vite (用React手搓服务端渲染好麻烦)。但是现在能上生产的服务端渲染估计是Next(配合React)和Nuxt(配合Vue)用的比较多。关于Next框架的学习见煮啵的另一篇文章,也将持续更新。

目录

1️⃣ 最基本的服务端渲染
2️⃣ Koa配合Vue
3️⃣ Koa配合Vue和Vite


最基本的服务端渲染

懒得BB,直接上代码:

// koa-pro/demos/basic_ssr.js
export default async (ctx) => {ctx.type = 'html';ctx.body = `<!DOCTYPE html><html><head><title>Hello</title></head><body><h1>Hello World</h1></body></html>`;
}// koa-pro/index.js
import Koa from 'koa';
import Router from '@koa/router';
import basicSSR from './demos/basic_ssr.js'const koa = new Koa();
const router = new Router();router.get('/basic_ssr', basicSSR)
koa.use(router.routes());
koa.listen(3001, () => console.log('Server is running on port 3001'))

这串代码我们平时根本不屑一顾,但他却实现了最基本的SSR。因为它在Koa服务端处理了一个 HTTP 请求,并返回了一段完整的 HTML 内容。


Koa配合Vue

Koa配合Vue来实现SSR,一开始煮啵是跟着Vue3官方文档的教程走的,但是它提供的Demo上有大坑 (也可能不是坑,是因为煮啵技术不行),煮啵只介绍自己实现的过程。首先我们将创建Vue应用的逻辑封装在自定义的createApp函数中:

// koa-ssr/scripts/vue_ssr/app.js
const isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';
export default async function createApp() {let createSSRApp; // Vue提供的创建SSR应用的APIif (isBrowser) {createSSRApp = (await import("https://unpkg.com/vue@3.5.13/dist/vue.esm-browser.js")).createSSRApp;} else {createSSRApp = (await import('vue')).createSSRApp;}// 创建我们自己的应用return createSSRApp({data: () => ({ count: 1 }),template: `<button @click="count++">{{ count }}</button>`,});
}

createApp这个函数的封装在Vue3官方文档里也有,但最大的区别就是官方文档里是直接用import createSSRApp from ‘vue’,而此处却需要根据当前JS代码所处的运行环境(Node或浏览器)来动态的引入createSSRApp这个玩意。为什么这样做见下文分析。

其次我们需要处理HTML模版,并用Koa的路由来挂载:

// koa-ssr/demos/vue_ssr.js
import { renderToString } from '@vue/server-renderer';
import createApp from '../scripts/vue_ssr/app.js';
export default async (ctx) => {const app = await createApp()const html = await renderToString(app);ctx.type = 'html';ctx.body = `<!DOCTYPE html><html><head><title>Vue SSR</title></head><body><div id="app">${html}</div><script type="module" src="/vue_ssr/client.js"></script></body></html>`
}// koa-ssr/index.js
// ...已有内容省略,见上一处代码块。在已有的基础上添加下面这些代码⬇️:
import vueSSR from './demos/vue_ssr.js'
import koaStatic from 'koa-static';
import path from "path";
import { fileURLToPath } from "url";const filename = fileURLToPath(import.meta.url);
const dirname = path.dirname(filename);router.get('/vue_ssr', vueSSR)
koa.use(koaStatic(path.join(dirname, 'scripts')));

此处,在模版中用script标签来加载脚本文件是必要的,否则SSR只返回了“空壳”,而无法提供任何交互。此外,用script标签来载脚本文件必须对外暴露(此处用的是koa-static)来实现。

为什么必须对外暴露?因为浏览器在拿到Koa返回的HTML后,会请求script的脚本文件,在这个Demo中浏览器发起的资源请求的URL即为:http://localhost:3001/scripts/vue_ssr/client.js。问题来了,如果没有用koa-static对外暴露,Koa便没有处理这个请求的逻辑,会返回404。

最后我们需要实现这个client.js脚本文件,客户端就是靠这个脚本来“接管”服务端返回的HTML。这个文件只在客户端执行

// koa-ssr/scripts/vue_ssr/client.js
import createApp from './app.js';
(async function activate() {const app = await createApp();app.mount('#app');
})()

此处最重要的便是app.mount(“#app”)这句代码,它的作用是在客户端激活Vue。

接着我们回答在封装createApp的时候遗留的问题:为什么需要根据JS代码的运行环境来动态导入createSSRApp因为koa-ssr/scripts/vue_ssr/app.js这个文件是需要执行两次的,一次在客户端,一次在服务端。
在服务端执行的时候(即在koa-router收到http://127.0.0.1:3001/vue_ssr请求的时候),它负责将Vue组件渲染成HTML内容,然后发送到客户端。
在客户端执行的时候,此时浏览器会加载client.js文件,client.jsimpoetcreateApp这个函数。这个文件用于做Hydration(激活)操作,将Vue组件的行为附加到已经渲染的HTML上
但问题是,app.js在客户端执行的时候,如果代码为import { createSSRApp } from “vue”是会报错的,在浏览器中运行时无法解析“vue”模块,因为浏览器并不像Node或Vite开发环境那样有“模块解析系统”,它无法直接识别“vue”是个什么路径。


Koa配合Vue和Vite

既然用到Vite,也算是半只脚踏入“工程化”的大门了。但是Vite大多数情况下我们会用来开发一个SPA应用,此处可以抛出一个困扰了煮啵很久的一个问题:考虑到如果使用了SSR服务端渲染,那么每次切换浏览器的导航,是否都需要服务端都需要根据请求来生成HTML页面并返回给客户端?那是否可以认为用Vite构建的SSR应用是无法实现SPA应用的?或者说这两者一定是对立的?

答案当然是否定的。SSR和SPA并不是完全对立的,两者常常结合使用,可以大致分为以下两个步骤:

  1. 服务端渲染:在第一次访问时,Vite会生成HTML并返回给浏览器。这些 HTML 包括了从服务器渲染的数据。
  2. 客户端接管 (Hydration):一旦页面加载完成,Vue、React或其他前端框架会在客户端 “接管” 这个页面,即把页面变成一个SPA。浏览器加载应用的脚本代码,绑定事件,并且使得页面可以进行客户端路由和状态管理。

总的来说,SPA和SSR的结合我们可以认为是先SSR,然后由客户端接管为SPA的过程。且煮啵始终认为,再复杂的应用,只要是SPA应用,服务端渲染便往往只发生在首页渲染的时候(这个“首页”可以是SPA应用中的任意一个页面)。借助Vite官网提供的教程,我们可以快速搭建一个基于Vite的Vue&SSR应用:

// pro/src/entry-client.js
// 客户端入口文件,浏览器靠这个文件在客户端激活Vue,接管服务端返回的HTML
import { createApp } from './main'
const { app } = createApp()
app.mount('#app')// pro/src/entry-serve.js
// 服务端入口文件,返回的stream用于构建HTML文件
import { renderToWebStream } from 'vue/server-renderer'
import { createApp } from './main'
export function render() {const { app } = createApp()const ctx = {}const stream = renderToWebStream(app, ctx)return { stream }
}// pro/src/main.js
// 创建应用实例。此文件在客户端和服务端各执行一次,具体原因见《Koa配合Vue》中的分析。
import { createSSRApp } from 'vue'
import App from './App.vue'
import router from './router/index'
export function createApp() {const app = createSSRApp(App)app.use(router)return { app }
}// pro/src/App.vue
<template><div>Hello World!</div><li><router-link to="/home">首页</router-link></li><li><router-link to="/user">个人中心</router-link></li><div><router-view></router-view></div>
</template>// pro/src/router/index.js
// 路由文件
import { createRouter, createMemoryHistory, createWebHistory } from 'vue-router'
import Home from '../views/home.vue'
import User from '../views/user.vue'
const isSSR = typeof window === 'undefined'
const routes = [{path: '/home',component: Home,name: 'home',meta: { ssr: true }},{path: '/user',component: User,name: 'user',meta: { ssr: true }},
]
const router = createRouter({// 此处必须判断当前所处环境时服务端还是客户端。// 因为createWebHistory的实现依赖于浏览器全局对象window// 而在服务端渲染的时候是没有window的history: isSSR ? createMemoryHistory() : createWebHistory(),routes,
})
export default router

主要的文件就是上面这几个了。之后每次进入前端应用的时候,浏览器发送GET请求得到的HTML文件中的内容都不再是只有一个id为app的div那么简单,而是会将App.vue中静态的内容渲染出来。但是有一个问题:在SSR的时候能不能获取数据库中的数据来填充HTML文件中的内容,然后再返回给客户端?

如果是客户端渲染,我们通常会在onmount这个生命周期中做响应操作,但是onmount中的副作用永远属于客户端行为,它只有在客户端接管HTML后才能发生作用。
但是,这种需求在Next中实现起来很简单:实现getServerSideProps即可。且在Nuxt中估计也是类似的。框架永远有一个好处就是帮我们封装了很多很繁琐的东西,再向上暴露有限的接口。
但是如果硬要用Vite来操作,煮啵现在并没找到很好的方法🤯。唯一能想到的就是从pro/src/entry-server.js或者pro/server.js这两个文件中切入来实现,后续找到方法再来分享。

还有一个问题:既然配合了vue-router使用,那能不能在首次进入页面的时候,让SSR返回的HTML内容中包含当前路径映射到的组件,而不仅仅是一个App.vue的内容?
在Vite最基础的框架上煮啵也没找到方法🤯,尝试过在定义路由表的时候给每个路由选项都添加meta: { ssr: true }这样的配置,但没有生效,之后再找方法吧。但是话又说回来了🤓在Next中这样的功能是内置的,框架已经帮你搞定了。


文章转载自:

http://chTOvxdN.kfmLf.cn
http://0XULQHMA.kfmLf.cn
http://h5lVDUNT.kfmLf.cn
http://IWSjZA9F.kfmLf.cn
http://Jp5wXFFf.kfmLf.cn
http://Hw3OSBt0.kfmLf.cn
http://Wzb6oVsn.kfmLf.cn
http://rYJLPopD.kfmLf.cn
http://eOBnX6kp.kfmLf.cn
http://6OGQffZr.kfmLf.cn
http://8oTzF1Yu.kfmLf.cn
http://KqRxYLq9.kfmLf.cn
http://jn5OfDeE.kfmLf.cn
http://MtaZNxdw.kfmLf.cn
http://5gefz6KH.kfmLf.cn
http://uCxwiJWv.kfmLf.cn
http://GmF11DkQ.kfmLf.cn
http://ufAWlbRv.kfmLf.cn
http://hh6Hksmr.kfmLf.cn
http://F7ahsSzp.kfmLf.cn
http://OucSd5sB.kfmLf.cn
http://wmksiguP.kfmLf.cn
http://5oAK3oQK.kfmLf.cn
http://e4WFT2Ar.kfmLf.cn
http://SVIiBo3H.kfmLf.cn
http://zewGH5PD.kfmLf.cn
http://ZQGDl3Qz.kfmLf.cn
http://WmWnp3RX.kfmLf.cn
http://XqulOwW5.kfmLf.cn
http://deTbsYHf.kfmLf.cn
http://www.dtcms.com/wzjs/719286.html

相关文章:

  • 买房子上哪个网站最好led网站建设
  • 东平县住房和城乡建设局网站利用虚拟主机建设企业网站
  • 对网站建设展望wordpress 4.9.5 漏洞
  • 厚街镇网站仿做建立网站加强家园沟通和联系的利弊
  • 阿里云1m 宽带做网站服务器教育网站 php
  • 建站什么程序好口碑营销方案
  • 网站的总规划书宿迁网络推广
  • 广州网站建设公司网络安全优化网站建设加数据库
  • 外贸网站建设入门营销型网站的建设方案
  • 做农产品的网站名称网站建设具体需求
  • 叮当快药网站谁做的wordpress php 採集
  • 无锡做网站专业的公司重庆黄埔建设集团网站
  • 做网站采集郑州市建设网站
  • 台州网站专业制作wordpress右侧悬浮搜索菜单
  • 花都建网站公司用模板做网站会被盗吗
  • 国外 网站有做验证码吗WordPress注册不提示
  • 手机网站单页面大同网站建设公司
  • wordpress单页淘宝客seo的优化方向
  • 网站开发的技术会计培训班的费用是多少
  • 能够做冶金工程毕业设计的网站html代码做的网站
  • 苏州建站公司精选苏州聚尚网络建站之星怎么免费做网站
  • 如何做推广赚钱天津网站seo设计
  • 网站外链的优化方法狮岭做包包的网站
  • 手机建立网站多少钱zzcms网站开发
  • 学电商比较好的网站有哪些wordpress 首页设置幻灯片
  • 怎么做网站聊天视频直播南昌哪里做网站好
  • 微站是什么会泽住房和城乡建设局网站
  • 下载免费软件哪个网站好网站升级建设
  • 北京外包做网站如何报价公司主页的网站格式
  • 陕西省建设银行分行互联网互联网站360建筑网密码忘了