Vue 3 组件开发:搭建基于SpreadJS的表格编辑系统(环境搭建)

image.png

Vue是一套用于构建用户界面的渐进式框架,与其它大型 JS 框架不同,Vue 被设计为可以自底向上逐层应用,更易上手,还便于与第三方库或既有项目整合,因此,Vue完全能够为复杂的单页应用提供驱动。

2020年09月18日,Vue.js 3.0 正式发布,作者尤雨溪将其描述为:更快、更小、更易于维护。

Vue 3都加入了哪些新功能?

本次发布, Vue框架本身迎来了多项更新,如Vue 此前的反应系统是使用 Object.defineProperty 的 getter 和 setter。 但是,在 Vue 3中,将使用 ES2015 Proxy 作为其观察者机制,这样做的好处是消除了以前存在的警告,使速度加倍,并节省了一半的内存开销。

除了基于 Proxy 的观察者机制,Vue 3的其他新特性还包括:

1. Performance(性能提升)

在Vue 2中,当某个DOM需要更新时,需要遍历整个虚拟DOM树才能判断更新点。而在Vue 3中,无需此项操作,仅需通过静态标记,对比虚拟节点上带有patch flag的节点,即可定位更新位置。

对比Vue 2和Vue 3的性能差异,官方文档中给出了具体数据说明:

· SSR速度提高了2~3倍

· Update性能提高1.3~2倍

2. Composition API(组合API)

Vue 2中有data、methods、mounted等存储数据和方法的对象,我们对此应该不陌生了。比如说要实现一个轮播图的功能,首先需要在data里定义与此功能相关的数据,在methods里定义该功能的方法,在mounted里定义进入页面自动开启轮播的代码…… 有一个显而易见的问题,就是同一个功能的代码却要分散在页面的不同地方,维护起来会相当麻烦。

为了解决上述问题,Vue 3推出了具备清晰的代码结构,并可消除重复逻辑的 Composition API,以及两个全新的函数setup和ref。

Setup 函数可将属性和方法返回到模板,在组件初始化的时候执行,其效果类似于Vue 2中的beforeCreate 和 created。如果想使用setup里的数据,需要将值return出来,没有从setup函数返回的内容在模板中不可用。

Ref函数的作用是创建一个引用值,主要是对String、Number、Boolean的数据响应做引用。

相对于Vue 2,Vue 3的生命周期函数也发生了变更,如下所示:

· beforeCreate -> 请使用 setup()

· created -> 请使用 setup()

· beforeMount -> onBeforeMount

· mounted -> onMounted

· beforeUpdate -> onBeforeUpdate

· updated -> onUpdated

· beforeDestroy -> onBeforeUnmount

· destroyed -> onUnmounted

· errorCaptured -> onErrorCaptured

需要注意的是,Vue 2使用生命周期函数时是直接在页面中写入生命周期函数,而在Vue 3则直接引用即可:

import {reactive, ref, onMounted} from 'vue'

3. Tree shaking support(按需打包模块)

有人将“Tree shaking”  称之为“摇树优化”,其实就是把无用的模块进行“剪枝”,剪去没有用到的API,因此“Tree shaking”之后,打包的体积将大幅度减少。

官方将Vue 2和Vue 3进行了对比,Vue 2若只写了Hello World,且没有用到任何的模块API,打包后的大小约为32kb,而Vue 3 打包后仅有13.5kb。         

4. 全新的脚手架工具:Vite

Vite 是一个由原生 ESM 驱动的 Web 开发构建工具。在开发环境下基于浏览器原生 ES imports 开发,在生产环境下基于 Rollup 打包。

和 Webpack相比,具有以下特点:

· 快速的冷启动,不需要等待打包

· 即时的热模块更新

· 真正的按需编译,不用等待整个项目编译完成

由于完全跳过了打包这个概念,Vite的出现大大的撼动了Webpack的地位,且真正做到了服务器随起随用。看来,连尤大神都难逃“真香”理论。

image.png

Vite究竟有什么魔力?不妨让我们通过实际搭建一款基于Vue 3 组件的表格编辑系统,亲自体验一把。

一、环境搭建

使用 Vite 初始化一个 Vue 3 项目

1. 执行代码:

1$ npm init vite-app <project-name> 2 3$ cd <project-name> //进入项目目录 4 5$ npm install //安装项目所需依赖 6 7$ npm run dev //启动项目 8

我们来看下生成的代码, 因为 vite 会尽可能多地镜像 vue-cli 中的默认配置, 所以,这段代码看上去和 vue-cli 生成的代码没有太大区别。

1├── index.html 2 3├── package.json 4 5├── public 6 7│ └── favicon.ico 8 9└── src 10 11 ├── App.vue 12 13 ├── assets 14 15 │ └── logo.png 16 17 ├── components 18 19 │ └── HelloWorld.vue 20 21 ├── index.css 22 23 └── main.js

2. 执行下列命令:

image.png

此时如果不通过 npm run dev 来启动项目,而是直接通过浏览器打开 index.html, 会看到下面的报错:

image.png

报错的原因:浏览器的 ES module 是通过 http 请求拿到模块的,所以 vite 的一个任务就是启动一个 web server 去代理这些模块,在 vite 里是借用了 koa 来启动的服务。

1export function createServer(config: ServerConfig): Server { 2 // ... 3 const app = new Koa<State, Context>() 4 const server = resolveServer(config, app.callback()) 5 6 // ... 7 const listen = server.listen.bind(server) 8 server.listen = (async (...args: any[]) => { 9 if (optimizeDeps.auto !== false) { 10 await require('../optimizer').optimizeDeps(config) 11 } 12 return listen(...args) 13 }) as any 14 15 return server 16}

由于浏览器中的 ESM 是获取不到导入的模块内容的,需要借助Webpack 等工具,如果我们没有引用相对路径的模块,而是引用 node_modules,并直接 import xxx from 'xxx',浏览器便无法得知你项目里有 node_modules,只能通过相对路径或者绝对路径去寻找模块。

这便是vite 的实现核心:拦截浏览器对模块的请求并返回处理后的结果(关于vite 的实现机制,文末会深入讲解)。

3. 生成项目结构:

image.png

入口 index.html 和 main.js 代码结构为:

1<!DOCTYPE html> 2<html lang="en"> 3<head> 4 <meta charset="UTF-8"> 5 <link rel="icon" href="https://my.oschina.net/favicon.ico" /> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <title>Vite App</title> 8</head> 9<body> 10 <div id="app"></div> 11 <script type="module" src="https://my.oschina.net/src/main.js"></script> 12</body> 13</html> 14 15// main.js 16// 只是引用的是最新的 vue3 语法,其余相同 17import { createApp } from 'vue' 18import App from './App.vue' 19import './index.css' 20 21createApp(App).mount('#app') 22

4. 进入项目目录:cd myVue3 

5. 安装相关模块:npm install

image.png

6. 下载模块:

image.png

7. 启动项目:npm run dev

image.png

8. 进入地址,当我们看到这个页面时,说明项目已经成功启动了。

image.png

Vite 的实现机制

1. /@module/ 前缀

对比工程下的 main.js 和开发环境下实际加载的 main.js,可以发现代码发生了变化。

工程下的 main.js:

1import { createApp } from 'vue' 2import App from './App.vue' 3import './index.css' 4 5createApp(App).mount('#app') 6

实际加载的 main.js:

1import { createApp } from '/@modules/vue.js' 2import App from '/src/App.vue' 3import '/src/index.css?import' 4 5createApp(App).mount('#app') 6

为了解决 import xxx from 'xxx' 报错的问题,vite 对这种资源路径做了统一处理,即添加一个/@module/前缀。

在 src/node/server/serverPluginModuleRewrite.ts 源码的 koa 中间件里可以看到 vite 对 import 做了一层处理,其过程如下:

· 在 koa 中间件里获取请求 body

· 通过 es-module-lexer 解析资源 ast 拿到 import 的内容

· 判断 import 的资源是否是绝对路径,绝对视为 npm 模块

· 返回处理后的资源路径:"vue" => "/@modules/vue"

2. 支持 /@module/

在 /src/node/server/serverPluginModuleResolve.ts 里可以看到大概的处理逻辑:

· 在 koa 中间件里获取请求 body

· 判断路径是否以 /@module/ 开头,如果是取出包名

· 去node_module里找到这个库,基于 package.json 返回对应的内容

3. 文件编译

通过前文,我们知道了 js module 的处理过程,对于vue、css、ts等文件,其又是如何处理的呢?

以 vue 文件为例,在 webpack 里使用 vue-loader 对单文件组件进行编译,在这里 vite 同样拦截了对模块的请求并执行了一个实时编译。

通过工程下的 App.vue 和实际加载的 App.vue,便发现改变。

工程下的 App.vue:

1<template> 2 <img alt="Vue logo" src="https://my.oschina.net//powertoolsteam/blog/4879100/assets/logo.png" /> 3 <HelloWorld msg="Hello Vue 3.0 + Vite" /> 4</template> 5 6<script> 7import HelloWorld from './components/HelloWorld.vue'; 8 9export default { 10 name: 'App', 11 components: { 12 HelloWorld, 13 }, 14}; 15</script> 16<style> 17#app { 18 font-family: Avenir, Helvetica, Arial, sans-serif; 19 -webkit-font-smoothing: antialiased; 20 -moz-osx-font-smoothing: grayscale; 21 text-align: center; 22 color: #2c3e50; 23 margin-top: 60px; 24} 25</style> 26

实际加载的 App.vue:

1import HelloWorld from '/src/components/HelloWorld.vue'; 2 3const __script = { 4 name: 'App', 5 components: { 6 HelloWorld, 7 }, 8}; 9 10import "/src/App.vue?type=style&index=0&t=1592811240845" 11import {render as __render} from "/src/App.vue?type=template&t=1592811240845" 12__script.render = __render 13__script.__hmrId = "/src/App.vue" 14__script.__file = "/Users/wang/qdcares/test/vite-demo/src/App.vue" 15export default __script 16

可见,一个 .vue 文件被拆成了三个请求(分别对应 script、style 和template) ,浏览器会先收到包含 script 逻辑的 App.vue 的响应,然后解析到 template 和 style 的路径后,再次发起 HTTP 请求来请求对应的资源,此时 Vite 对其拦截并再次处理后返回相应的内容。

1// App.vue?type=style 2import { updateStyle } from "/vite/hmr" 3const css = "\n#app {\n font-family: Avenir, Helvetica, Arial, sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n text-align: center;\n color: #2c3e50;\n margin-top: 60px;\n}\n" 4updateStyle("7ac74a55-0", css) 5export default css 6 7// App.vue?type=template 8import {createVNode as _createVNode, resolveComponent as _resolveComponent, Fragment as _Fragment, openBlock as _openBlock, createBlock as _createBlock} from "/@modules/vue.js" 9 10const _hoisted_1 = /*#__PURE__*/ 11_createVNode("img", { 12 alt: "Vue logo", 13 src: "/src/assets/logo.png" 14}, null, -1 /* HOISTED */ 15) 16 17export function render(_ctx, _cache) { 18 const _component_HelloWorld = _resolveComponent("HelloWorld") 19 20 return (_openBlock(), 21 _createBlock(_Fragment, null, [_hoisted_1, _createVNode(_component_HelloWorld, { 22 msg: "Hello Vue 3.0 + Vite" 23 })], 64 /* STABLE_FRAGMENT */ 24 )) 25}

vite对于其他的类型文件的处理几乎都是类似的逻辑,即根据请求的不同文件类型,做出不同的编译处理结果。

扩展阅读

· Vue 3 组件开发实战:搭建基于SpreadJS的表格编辑系统(组件集成篇)

· Vue 3 组件开发实战:搭建基于SpreadJS的表格编辑系统(功能拓展篇)

· SpreadJS Vue 框架支持

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

Opencv中Mat矩阵相乘——点乘、dot、mul运算详解

Opencv中Mat矩阵相乘——点乘、dot、mul运算详解2016年09月02日00:00:36 \牧野(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fme.csdn.net%2Fdcrmg) 阅读数:59593

KVM调整cpu和内存

一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid