Vue 3 组件开发(一):搭建表格编辑系统 - 环境搭建
ccwgpt 2024-10-25 10:53 44 浏览 0 评论
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的地位,且真正做到了服务器随起随用。看来,连尤大神都难逃"真香"理论。
Vite究竟有什么魔力?不妨让我们通过实际搭建一款基于Vue 3 组件的表格编辑系统,亲自体验一把。
环境搭建
使用 Vite 初始化一个 Vue 3 项目
1. 执行代码:
$ npm init vite-app <project-name>
$ cd <project-name> //进入项目目录
$ npm install //安装项目所需依赖
$ npm run dev //启动项目
我们来看下生成的代码, 因为 vite 会尽可能多地镜像 vue-cli 中的默认配置, 所以,这段代码看上去和 vue-cli 生成的代码没有太大区别。
├── index.html
├── package.json
├── public
│ └── favicon.ico
└── src
├── App.vue
├── assets
│ └── logo.png
├── components
│ └── HelloWorld.vue
├── index.css
└── main.js
2. 执行下列命令:
此时如果不通过 npm run dev 来启动项目,而是直接通过浏览器打开 index.html, 会看到下面的报错:
报错的原因:浏览器的 ES module 是通过 http 请求拿到模块的,所以 vite 的一个任务就是启动一个 web server 去代理这些模块,在 vite 里是借用了 koa 来启动的服务。
export function createServer(config: ServerConfig): Server {
// ...
const app = new Koa<State, Context>()
const server = resolveServer(config, app.callback())
// ...
const listen = server.listen.bind(server)
server.listen = (async (...args: any[]) => {
if (optimizeDeps.auto !== false) {
await require('../optimizer').optimizeDeps(config)
}
return listen(...args)
}) as any
return server
}
由于浏览器中的 ESM 是获取不到导入的模块内容的,需要借助Webpack 等工具,如果我们没有引用相对路径的模块,而是引用 node_modules,并直接 import xxx from 'xxx',浏览器便无法得知你项目里有 node_modules,只能通过相对路径或者绝对路径去寻找模块。
这便是vite 的实现核心:拦截浏览器对模块的请求并返回处理后的结果(关于vite 的实现机制,文末会深入讲解)。
3. 生成项目结构:
入口 index.html 和 main.js 代码结构为:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vite App</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>
// main.js
// 只是引用的是最新的 vue3 语法,其余相同
import { createApp } from 'vue'
import App from './App.vue'
import './index.css'
createApp(App).mount('#app')
4. 进入项目目录:cd myVue3
5. 安装相关模块:npm install
6. 下载模块:
7. 启动项目:npm run dev
8. 进入地址,当我们看到这个页面时,说明项目已经成功启动了。
Vite 的实现机制
1. /@module/ 前缀
对比工程下的 main.js 和开发环境下实际加载的 main.js,可以发现代码发生了变化。
工程下的 main.js:
import { createApp } from 'vue'
import App from './App.vue'
import './index.css'
createApp(App).mount('#app')
实际加载的 main.js:
import { createApp } from '/@modules/vue.js'
import App from '/src/App.vue'
import '/src/index.css?import'
createApp(App).mount('#app')
为了解决 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:
<template>
<img alt="Vue logo" src="./assets/logo.png" />
<HelloWorld msg="Hello Vue 3.0 + Vite" />
</template>
<script>
import HelloWorld from './components/HelloWorld.vue';
export default {
name: 'App',
components: {
HelloWorld,
},
};
</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>
实际加载的 App.vue:
import HelloWorld from '/src/components/HelloWorld.vue';
const __script = {
name: 'App',
components: {
HelloWorld,
},
};
import "/src/App.vue?type=style&index=0&t=1592811240845"
import {render as __render} from "/src/App.vue?type=template&t=1592811240845"
__script.render = __render
__script.__hmrId = "/src/App.vue"
__script.__file = "/Users/wang/qdcares/test/vite-demo/src/App.vue"
export default __script
可见,一个 .vue 文件被拆成了三个请求(分别对应 script、style 和template) ,浏览器会先收到包含 script 逻辑的 App.vue 的响应,然后解析到 template 和 style 的路径后,再次发起 HTTP 请求来请求对应的资源,此时 Vite 对其拦截并再次处理后返回相应的内容。
// App.vue?type=style
import { updateStyle } from "/vite/hmr"
const 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"
updateStyle("7ac74a55-0", css)
export default css
// App.vue?type=template
import {createVNode as _createVNode, resolveComponent as _resolveComponent, Fragment as _Fragment, openBlock as _openBlock, createBlock as _createBlock} from "/@modules/vue.js"
const _hoisted_1 = /*#__PURE__*/
_createVNode("img", {
alt: "Vue logo",
src: "/src/assets/logo.png"
}, null, -1 /* HOISTED */
)
export function render(_ctx, _cache) {
const _component_HelloWorld = _resolveComponent("HelloWorld")
return (_openBlock(),
_createBlock(_Fragment, null, [_hoisted_1, _createVNode(_component_HelloWorld, {
msg: "Hello Vue 3.0 + Vite"
})], 64 /* STABLE_FRAGMENT */
))
}
vite对于其他的类型文件的处理几乎都是类似的逻辑,即根据请求的不同文件类型,做出不同的编译处理结果。
欢迎点击下方“了解更多”获取更多技术详情。
相关推荐
- 一个基于.Net Core遵循Clean Architecture原则开源架构
-
今天给大家推荐一个遵循CleanArchitecture原则开源架构。项目简介这是基于Asp.netCore6开发的,遵循CleanArchitecture原则,可以高效、快速地构建基于Ra...
- AI写代码翻车无数次,我发现只要提前做好这3步,bug立减80%
-
写十万行全是bug之后终于找到方法了开发"提示词管理助手"新版本那会儿,我差点被bug整崩溃。刚开始两周,全靠AI改代码架构,结果十万行程序漏洞百出。本来以为AI说没问题就稳了,结果...
- OneCode低代码平台的事件驱动设计:架构解析与实践
-
引言:低代码平台的事件驱动范式在现代软件开发中,事件驱动架构(EDA)已成为构建灵活、松耦合系统的核心范式。OneCode低代码平台通过创新性的注解驱动设计,将事件驱动理念深度融入平台架构,实现了业务...
- 国内大厂AI插件评测:根据UI图生成Vue前端代码
-
在IDEA中安装大厂的AI插件,打开ruoyi增强项目:yudao-ui-admin-vue31.CodeBuddy插件登录腾讯的CodeBuddy后,大模型选择deepseek-v3,输入提示语:...
- AI+低代码技术揭秘(二):核心架构
-
本文档介绍了为VTJ低代码平台提供支持的基本架构组件,包括Engine编排层、Provider服务系统、数据模型和代码生成管道。有关UI组件库和widget系统的信息,请参阅UI...
- GitDiagram用AI把代码库变成可视化架构图
-
这是一个名为gitdiagram的开源工具,可将GitHub仓库实时转换为交互式架构图,帮助开发者快速理解代码结构。核心功能一键可视化:替换GitHubURL中的"hub...
- 30天自制操作系统:第六天:代码架构整理与中断处理
-
1.拆开bootpack.c文件。根据设计模式将对应的功能封装成独立的文件。2.初始化pic:pic(可编程中断控制器):在设计上,cpu单独只能处理一个中断。而pic是将8个中断信号集合成一个中断...
- AI写代码越帮越忙?2025年研究揭露惊人真相
-
近年来,AI工具如雨后春笋般涌现,许多人开始幻想程序员的未来就是“对着AI说几句话”,就能轻松写出完美的代码。然而,2025年的一项最新研究却颠覆了这一期待,揭示了一个令人意外的结果。研究邀请了16位...
- 一键理解开源项目:两个自动生成GitHub代码架构图与说明书工具
-
一、GitDiagram可以一键生成github代码仓库的架构图如果想要可视化github开源项目:https://github.com/luler/reflex_ai_fast,也可以直接把域名替换...
- 5分钟掌握 c# 网络通讯架构及代码示例
-
以下是C#网络通讯架构的核心要点及代码示例,按协议类型分类整理:一、TCP协议(可靠连接)1.同步通信//服务器端usingSystem.Net.Sockets;usingTcpListene...
- 从复杂到优雅:用建造者和责任链重塑代码架构
-
引用设计模式是软件开发中的重要工具,它为解决常见问题提供了标准化的解决方案,提高了代码的可维护性和可扩展性,提升了开发效率,促进了团队协作,提高了软件质量,并帮助开发者更好地适应需求变化。通过学习和应...
- 低代码开发当道,我还需要学习LangChain这些框架吗?| IT杂谈
-
专注LLM深度应用,关注我不迷路前两天有位兄弟问了个问题:当然我很能理解这位朋友的担忧:期望效率最大化,时间用在刀刃上,“不要重新发明轮子”嘛。铺天盖地的AI信息轰炸与概念炒作,很容易让人浮躁与迷茫。...
- 框架设计并不是简单粗暴地写代码,而是要先弄清逻辑
-
3.框架设计3.框架设计本节我们要开发一个UI框架,底层以白鹭引擎为例。框架设计的第一步并不是直接撸代码,而是先想清楚设计思想,抽象。一个一个的UI窗口是独立的吗?不是的,...
- 大佬用 Avalonia 框架开发的 C# 代码 IDE
-
AvalonStudioAvalonStudio是一个开源的跨平台的开发编辑器(IDE),AvalonStudio的目标是成为一个功能齐全,并且可以让开发者快速使用的IDE,提高开发的生产力。A...
- 轻量级框架Lagent 仅需20行代码即可构建自己的智能代理
-
站长之家(ChinaZ.com)8月30日消息:Lagent是一个专注于基于LLM模型的代理开发的轻量级框架。它的设计旨在简化和提高这种模型下代理的开发效率。LLM模型是一种强大的工具,可以...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- 框架图 (58)
- flask框架 (53)
- quartz框架 (51)
- abp框架 (47)
- springmvc框架 (49)
- 分布式事务框架 (65)
- scrapy框架 (56)
- shiro框架 (61)
- 定时任务框架 (56)
- java日志框架 (61)
- mfc框架 (52)
- abb框架断路器 (48)
- beego框架 (52)
- java框架spring (58)
- grpc框架 (65)
- tornado框架 (48)
- 前端框架bootstrap (54)
- orm框架有哪些 (51)
- 知识框架图 (52)
- ppt框架 (55)
- 框架图模板 (59)
- 内联框架 (52)
- cad怎么画框架 (58)
- ssm框架实现登录注册 (49)
- oracle字符串长度 (48)