Vue Playground 演练场源码解读(一)

184 阅读3分钟

Vue Playground 演练场源码解读(一)

以学习源码来丰富自己,学习其原理,并从源码中学习好的技术实践。Playground 源码

不要着急,本系列文章会一点点把该源码好的技术实践以及其原理慢慢进行拨开讲解。好的代码习惯都是从借鉴别人的代码开始的

本系列预计共四篇,敬请关注

获取vue、ts版本

1.png

咱们先思考下,以咱们前端的维度去考虑如果我们自己实现维护一套版本更新会怎么做:

第一个方案:后端出个API接口(配置文件),有版本更新由后端维护。

第二个方案:前端写死版本,由前端维护(每次vue有版本更新需要重新打包发布) ❌。

其实很明显第一种方案最佳,由前端去维护不是太可行,每次有版本更新重新打包可不行。但是这个Vue Playground 演练场又是一个纯前端的项目,源码中使用的是 jsdelivr 托管维护的。 可以访问 vue全部版本信息 进行具体查看

jsdelivr 是一个免费的、高性能的 CDN(内容分发网络),专门用于托管和分发开源项目和前端库的资源文件。它为开发者提供了一个快速、可靠的方式来加载 JavaScript、CSS、字体等静态资源。

jsDelivrGitHub、npm、Unpkg等平台集成,可以自动托管和更新开源项目中的资源文件。开发者可以直接从这些平台获取资源,而无需手动上传文件。就是说你发布了vue版本,jsdelivr会自动更新。

获取版本使用fetch请求,获取到版本数据。这里有个开关就是判断有没有数据,就是只会加载一次

2.png

动态设置容器的高度

<script setup>
const setVH = () => {
  document.documentElement.style.setProperty('--vh', window.innerHeight + `px`)
}
window.addEventListener('resize', setVH)
setVH()
</script>

<style>
body {
  font-size: 13px;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen,
    Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
  margin: 0;
  --base: #444;
  --nav-height: 50px;
}

.vue-repl {
  height: calc(var(--vh) - var(--nav-height)) !important;
}
</style>

它通过监听窗口的 resize 事件,并根据窗口的高度设置一个名为 --vh 的 CSS 变量。然后,它使用这个变量来设置一个名为 .vue-repl 的容器的高度,以适应窗口的变化。

下载源码

3.png

咱们一起来看看下载项目源码是怎么实现的如下:

4.png

import index from './template/index.html?raw'?raw 是一个特殊的查询参数,用于指示加载资源时的特定行为。具体来说,?raw 的作用是将文件内容以原始字符串的形式导入,而不是按照默认的模块解析方式处理。

?raw 会告诉 Webpack 将文件的内容直接读取为一个字符串。例如,如果 index.html 文件的内容是:

<div>Hello, world!</div>

使用 import index from './template/index.html?raw' 后,index 的值将是一个字符串:

console.log(index); // 输出 "<div>Hello, world!</div>"

jszip 是一个打包成的zip文件的库,它提供了一种方便的方式来创建压缩zip文件。

const { default: JSZip } = await import('jszip')
const zip = new JSZip()

// basic structure
zip.file('index.html', index)

使用folder创建文件夹,然后循环数据添加文件

const files = store.getFiles() // 这里先不用关系,后面咱们再拆解

for (const file in files) {
    if (file !== 'import-map.json' && file !== 'tsconfig.json') {
      src.file(file, files[file])
    } else {
      zip.file(file, files[file])
    }
}

配合file-saver做下载:

import { saveAs } from 'file-saver'

const blob = await zip.generateAsync({ type: 'blob' })
saveAs(blob, 'vue-project.zip')

总结

本篇文章跟大家分享了:

  1. 动态获取版本,并且简单了解了下jsdelivr
  2. 动态设置高度
  3. ?raw 是做什么的,以及jszip配合file-saver的下载项目.