Vue3.0(一):Vue的引入-options api-模板语法
Vue的引入方式
CDN方式进行引入
- 将以下
script标签引入即可
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title><!-- CDN地址 --><script src="https://unpkg.com/vue@3/dist/vue.global.js"></script></head><body><div id="app"></div><script>//使用Vueconst app = Vue.createApp({template: `<h1>hello</h1>`,});//挂载app.mount("#app");</script></body>
</html>
本地引入
- 可以将CDN中地址中的代码,拷贝到一个 vue.js文件中
- 之后引入该js文件即可
<script src="./vue.js"></script>
命令式编程和声明式编程的区别

- 以上案例是实现了一个计数器的功能
- 左边是Vue实现
- 右边是原生实现
- 原生js实现—命令式编程
- 需要将每一步操作,都转化为代码,告诉计算机要怎么实现
- 相当于每一步操作都告诉计算机执行什么命令
- Vue实现—声明式编程
- 在vue实现中,只需要声明要展示什么数据,展示的具体内容,以及用到的方法
- 而Vue内部会将这些内容进行关联
- 命令式编程:how to do,自己完成整个how的过程
- 声明式编程:what to do,由框架完成 how的过程
MVVM模型
Model-View-ViewMode的简称
- Vue不完全遵循MVVM模型,但是受到了启发

- View相当于html代码,Model是声明变量,方法;ViewModel就是Vue框架
- Vue框架会将数据与View进行绑定,当View发生了点击等事件,会交由Vue处理,找到对应的Model中的方法
options api(部分)
data属性
//使用Vue
const app = Vue.createApp({data(){return{title:"Vue3.0"}}
});
//挂载
app.mount("#app");
- data属性是传入一个函数,并返回一个对象
- data中返回的对象,会被Vue的响应式系统劫持(通过 Proxy方式实现)
methods属性
//使用Vue
const app = Vue.createApp({methods:{myClick(){//可以通过this访问data中声明的变量console.log(123)}}
});
//挂载
app.mount("#app");
- 在 methods中通常是用于声明函数方法的
- 在 声明函数的时候,不能使用箭头函数
- 因为使用了箭头函数,会找到上一层作用域中的this,导致无法访问到data中的变量
computed计算属性
有些数据需要进行处理之后,再将其显示到页面中
- 对于响应式数据的复杂逻辑,都应该使用计算属性
- 在computed中可以使用this访问data中的变量
<div id="app"><div>{{numStr}}</div>
</div>
<script>//使用Vueconst app = Vue.createApp({data() {return {arr: [1, 2, 3],};},computed: {//计算属性的值都是函数numStr() {return this.arr.join("");},},});//挂载app.mount("#app");
</script>
- 计算属性是有缓存的
- 因为计算属性会基于它的依赖关系进行缓存(上面的例子中,numStr计算属性的依赖关系就是arr)
- 当依赖关系不发生变化的时候,计算属性是不需要重新计算的(arr不变,则numStr不重新计算)
- 若 arr发生了变化,则numStr会重新进行计算
watch侦听器
用于侦听数据的变化,当数据发生变化的时候,需要执行特定的逻辑
<div id="app"><div v-for="(item,index) in arr" :key="index">{{item}}</div><button @click="arrChange">change</button>
</div>
<script>//使用Vueconst app = Vue.createApp({data() {return {arr: [1, 2, 3],};},watch: {//监听的变量//传入两个参数,newValue和oldValuearr(newValue, oldValue) {//对于对象的侦听,newValue, oldValue实际上是Proxy对象console.log(newValue, oldValue);//若想获取Proxy的原始数据,可以使用Vue.toRawconsole.log(Vue.toRaw(newValue));},},methods: {arrChange() {this.arr = [1, 2, 3, 4];},},});//挂载app.mount("#app");
侦听器的配置选项
修改对象的某个属性,需要进行特殊的配置,才可以侦听到,需要进行深度侦听
<div id="app"><div v-for="(item,index) in arr" :key="index">{{item}}</div><button @click="arrChange">change</button>
</div>
<script>//使用Vueconst app = Vue.createApp({data() {return {arr: [1, 2, 3],};},//进行监听watch: {arr: {handler(newValue, oldValue) {//此时你会发现,newValue和oldValue是一样的//这是因为内存地址没有发生过变化,所以是一样的console.log(newValue, oldValue);},//开启深度侦听deep: true,},},methods: {arrChange() {this.arr.push(4);},},});//挂载app.mount("#app");
</script>
第一次渲染的时候,默认是不会进行侦听的,可以通过immediate进行配置
<div id="app"><div v-for="(item,index) in arr" :key="index">{{item}}</div><button @click="arrChange">change</button>
</div>
<script>//使用Vueconst app = Vue.createApp({data() {return {arr: [1, 2, 3],};},watch: {arr: {handler(newValue, oldValue) {//此时你会发现,newValue和oldValue是一样的//这是因为内存地址没有发生过变化,所以是一样的console.log(newValue, oldValue);},//开启深度侦听deep: true,//首次加载是否侦听immediate: true,},},methods: {arrChange() {this.arr.push(4);},},});//挂载app.mount("#app");
</script>
v-model双向数据绑定
- v-model指令可以在表单input textarea等元素上创建双向数据绑定
- 它会根据控件类型自动选取正确的方式来更新元素
- v-model本质上就是语法糖,负责监听用户的输入事件来更新数据
<div id="app"><!-- 手动实现 --><input type="text" :value="message" @input="inputChange" /><h2>{{message}}</h2>
</div>
<script>//使用Vueconst app = Vue.createApp({data() {return {message: "123",};},methods: {inputChange(event) {this.message = event.target.value;},},});//挂载app.mount("#app");
</script>
- 通过 v-bind指令绑定message,当用户在输入框中输入内容,会触发 inputChange事件,从而将this.message进行更改
<div id="app"><!-- 通过v-model实现 --><input type="text" v-model="message" /><h2>{{message}}</h2>
</div>
<script>//使用Vueconst app = Vue.createApp({data() {return {message: "123",};},});//挂载app.mount("#app");
</script>
修饰符
- lazy:v-model默认触发的是input事件,而该修饰符是将input事件转成change事件,只有当光标离开才会触发
<input type="text" v-model.lazy="message" />
- number:默认是字符串类型,该修饰符是将内容自动转成数字
<input type="text" v-model.number="num" />
- trim:去除首尾的空格
<input type="text" v-model.trim="message" />
模板语法
Vue中特定的语法
Mustache双括号语法
<div id="app"><!--基本用法:可以使用data属性中返回的变量-->{{title}}<!--表达式-->{{counter * 2}}<!--三元运算符-->{{flag?true:false}}<!--可以调用methods中的函数-->{{myClick()}}
</div>
v-once指令(了解)
只会渲染一次
<div id="app"><div v-once>{{message}}</div>
</div>
- div标签只会渲染一次,即使message被改变了,也不会重新渲染
- 可以用于性能优化
- 同时使用了v-once指令的元素,其子元素也只会渲染一次
v-text指令(了解)
用于更新元素的textContent
<div id="app"><div>{{message}}</div><!--与上面实现的效果一样--><div v-text="message"></div>
</div>
v-html(了解)
用于将html字符串转成相应的样式
<div id="app"><div v-html="message"></div>
</div>message = `<h2>hahaha</h2>`
v-pre(了解)
用于跳过元素和子元素的编译过程,显示原始的Mustache标签

v-bind的绑定属性
可以绑定一个或者多个属性值,或者向另外一个组件传递props值
- 前面的属性主要是将内容插入到元素中
- 而某些元素的属性也希望动态绑定
- 比如图片、连接、动态绑定一些类,样式等
<div id="app">基本使用<img v-bind:src="url">简写<img :src="url">
</div>
绑定class属性
- 动态class通过对象语法绑定
- key:代表类名、
- value:传入一个boolean值
- 可以传入多个
<style>.titleClass {}.textClass {}.abc{}
</style>
<div id="app"><div :class="{titleClass:true,textClass:flag}"></div>//会将普通的class进行合并<div class="abc" :class="{titleClass:true,textClass:flag}"></div>
</div>
- 动态class通过数组语法绑定
<style>.titleClass {}.textClass {}.abc{}
</style>
<div id="app"><div :class="['titleClass','textClass']"></div>
</div>
绑定style属性
- 使用 v-bind绑定style,后面要跟着对象
- 对于 font-size中间带 **-**的属性,需要用引号包起来或者写成驼峰形式
<div id="app">//普通写法<div style="color:red"></div><div :style="{color:textRed,fontSize:'30px'}"></div>
</div>
- 同时也有数组写法
- 通常是多个对象联合使用
<div id="app"><div :style="[colorObject,fontSizeObject]"></div>
</div>
绑定属性名
<div id="app"><div :[className]="[colorObject,fontSizeObject]"></div>
</div>data(){return{className:"style"}
}
直接绑定对象
- 在元素中,直接通过
v-bind = 'obj'即可- 会自动遍历obj中的key,将key添加到元素上面
- 通常用于组件间传值
<div id="app"><div v-bind="infos">hello</div>
</div>

v-on绑定事件
基本使用方法
<div id="app"><!-- 完整写法 --><div v-on:click="divClick">hello</div><!-- 语法糖 --><div @click="divClick">hello2</div><!-- 可以写成表达式 --><div @click="console.log(456)">hello3</div><!-- 绑定其他方法 --><div @mousemove="divClick">hello4</div><!-- 绑定多个事件 --><div @click="divClick" @mousemove="divMove">hello5</div>
</div>
<script>//使用Vueconst app = Vue.createApp({methods: {divClick() {console.log("click");},divMove() {console.log("move");},},});//挂载app.mount("#app");
</script>
参数传递
- 没有传递参数,默认会传递一个 event参数
<div id="app"><button @click="divClick">123</button>
</div>
<script>//使用Vueconst app = Vue.createApp({methods: {divClick(event) {//默认参数eventconsole.log(event);},},});//挂载app.mount("#app");
</script>
- 有明确的参数,会将 默认参数event覆盖
<div id="app"><button @click="divClick('zhangcheng')">123</button>
</div>
<script>//使用Vueconst app = Vue.createApp({methods: {divClick(data) {//默认参数eventconsole.log(data);},},});//挂载app.mount("#app");
</script>
- 自己的参数和默认参数event
- 通过 $event
<div id="app"><button @click="divClick('zhangcheng',$event)">123</button>
</div>
<script>//使用Vueconst app = Vue.createApp({methods: {divClick(data, event) {//默认参数eventconsole.log(data, event);},},});//挂载app.mount("#app");
</script>
修饰符

- 通过
@click.stop="divClick"进行使用
条件渲染
在某些情况下,一些元素需要根据特定的条件进行显示
v-if v-else v-else-if v-show
<div id="app"><div v-if="flag">flag为true显示</div><div v-else>flag为false显示</div>
</div>
<script>//使用Vueconst app = Vue.createApp({data() {return {flag: true,};},});//挂载app.mount("#app");
</script>
- template元素的使用(Vue3提出来的)
- 该元素通常配合v-if使用
- 且该元素可以包含多个子元素
- 该元素不会渲染到DOM树上
<template v-if="flag"><div>flag为true显示</div><div>flag为false显示</div>
</template>
v-if与v-show的区别是v-if条件不成立的时候,DOM不会渲染或者被销毁掉v-show的元素会被渲染,只是通过CSS的display进行控制v-if支持template,但是v-show不能
v-for列表渲染
可以遍历可迭代对象
- 在真实开发中,我们通常从服务器中获取一组数据
- 而要将这一组数据,都展示在页面中,就需要使用
v-for进行遍历
基本使用
<div id="app"><!-- 直接获取内容 --><div v-for="item in arr">{{item}}</div><!-- 获取内容和索引值,顺序不能动 --><div v-for="(item,index) in arr">item:{{item}};index:{{index}}</div>
</div>
<script>//使用Vueconst app = Vue.createApp({data() {return {arr: [1, 2, 3],};},});//挂载app.mount("#app");
</script>
支持的类型
- v-for不仅支持遍历数组
- 同样也支持遍历对象
<div id="app"><!-- 遍历对象,value代表value --><div v-for="value in obj">{{value}}</div><!-- 遍历对象,(value,key,index)代表value,key以及索引 --><div v-for="(value,key,index) in obj">{{value}}-{{key}}-{{index}}</div>
</div>
<script>//使用Vueconst app = Vue.createApp({data() {return {obj: {name: "zhangcheng",age: "18",},};},});//挂载app.mount("#app");
</script>
- 遍历字符串(可迭代对象)
<div id="app"><div v-for="value in str">{{value}}</div>
</div>
<script>//使用Vueconst app = Vue.createApp({data() {return {str:"abcsde"};},});//挂载app.mount("#app");
</script>
- 可以遍历数字
<div id="app"><div v-for="value in 10">{{value}}</div>
</div>
<script>//使用Vueconst app = Vue.createApp({});//挂载app.mount("#app");
</script>
数组更新检测
- Vue中对一些数组的方法进行了包裹,这些方法在对数组进行操作的时候,可以更新视图
- 这些方法对原数组进行了改变

<div id="app"><div v-for="item in arr">{{item}}</div><button @click="arrChange">change</button>
</div>
<script>//使用Vueconst app = Vue.createApp({data() {return {arr: [1, 2, 3],};},methods: {arrChange() {this.arr.push(4);},},});//挂载app.mount("#app");
</script>
- 而针对于不改变原数组,且生成新数组的方法,不可以更新视图
- 需要重新赋值
<div id="app"><div v-for="item in arr">{{item}}</div><button @click="arrChange">change</button>
</div>
<script>//使用Vueconst app = Vue.createApp({data() {return {arr: [1, 2, 3],};},methods: {arrChange() {this.arr = this.arr.map(item=>item+"zc")},},});//挂载app.mount("#app");
</script>
v-for中的key作用是什么
通常在使用v-for的时候,需要搭配key一同使用
- key的要求是唯一的
- key属性主要用在 Vue的虚拟DOM算法,在新旧nodes对比辨识 VNodes
- 有 key存在的时候,对元素进行了改变,会尽可能地复用相同地节点
- 没有 **key存在的时候,**不会对元素进行复用
<div id="app"><div v-for="item in arr" :key="item">{{item}}</div>
</div>
<script>//使用Vueconst app = Vue.createApp({data() {return {arr: [1, 2, 3],};},});//挂载app.mount("#app");
</script>
认识VNode
- VNode是虚拟节点
- 在 Vue中无论是组件还是元素都是VNode(虚拟节点)
- 本质就是一个JS对象


虚拟DOM
方便对代码进行跨平台操作以及diff算法
- 如果我们不仅仅只有一个div,而是复杂的嵌套元素
- 这些会生成一个 VNode Tree
- 即为虚拟 DOM
相关文章:
Vue3.0(一):Vue的引入-options api-模板语法
Vue的引入方式 CDN方式进行引入 将以下 script标签引入即可 <script src"https://unpkg.com/vue3/dist/vue.global.js"></script><!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><met…...
API网关-Apisix多节点搭建(RPM包方式)
文章目录 前言一、介绍1. 端口介绍2. APISIX节点介绍3. apisix单机安装配置教程(选看) 二、准备1. 配置集群免密登录2. 搭建etcd集群 三、安装apisix节点1. 复制脚本2. 增加执行权限3. 分发脚本4. 执行脚本5. 配置apisix的etcd集群地址 四、安装apisix-dashboard1. 复制脚本2. …...
HAL库配置片内FLASH读写
一、FLASH简介 不同型号的 STM32F40xx/41xx,其 FLASH 容量也有所不同,最小的只有 128K 字节,最大 的则达到了 1024K 字节。我们的探索者开发板选择的是 STM32F407ZGT6 的 FLASH 容量为 1024K 字节。 主存储器,存放代码和数据常数&…...
日志记录——单片机可执行文件合并
一:需求场景 现在有一片单片机,执行程序包括自定义boot和应用程序app, 在将打包好的固件给到生产是有以下问题,由于要通过jlink烧录boot,然后上电启动boot,通过boot烧录初始化程序,过程过于复杂࿰…...
2024数模美赛C题F题完整代码结果展示
C:Momentum in Tennis 实在精力有限,完整讲解可以移步去看我的讲解视频啦: 美赛C题每一问代码结果讲解及进度说明 F:Reducing lllegal Wildlife Trade 实在精力有限,完整讲解可以移步去看我的讲解视频啦: …...
H5调用安卓原生相机API案例
1、在activity_main.xml文件里添加webview标签 <WebViewandroid:id="@+id/webview"android:layout_width="match_parent"android:layout_height="match_parent"> </WebView> 2、AndroidManifest.xml(权限和活动声明) 开启访问…...
Java面试——计网篇
一、基础篇 1、 TCP/IP 网络模型 对于同一台设备上的进程间通信,有很多种方式,比如有管道、消息队列、共享内存、信号等方式,而对于不同设备上的进程间通信,就需要网络通信,而设备是多样性的,所以要兼容多…...
函数式接口当参数使用
如果函数式接口作为一个方法的参数,就以为着要方法调用方自己实现业务逻辑,常见的使用场景是一个业务整体逻辑是不相上下的,但是在某一个步骤有不同的逻辑,例如数据处理有不同的策略,如果有大量的if-els,或…...
全面详解Maven的配置文件settings.xml
全面详解Maven的配置文件settings.xml setting文件位置maven多仓库查找依赖的顺序大致如下:基本配置选项localRepository(本地仓库设置)mirrors(镜像设置)servers(服务器)Profiles(配置文件)Active Profiles(激活配置文件Profiles的Profile) Maven是一个用于构建和管…...
【Spring连载】使用Spring Data访问Redis(十四)----Redis Repositories
【Spring连载】使用Spring Data访问Redis(十四)----Redis Repositories 一、Core concepts二、Defining Repository Interfaces三、Creating Repository Instances四、Usage五、Object Mapping Fundamentals六、对象到Hash映射Object-to-Hash Mapping七、…...
小鹏汽车穿越“生死线”
文|刘俊宏编|王一粟 “颠覆与涅槃,颠覆自我与重新涅槃,让企业在变革中更完美的蜕变。” 2024新年伊始,小鹏汽车董事长兼CEO何小鹏对2023年的蜕变显然非常刻骨铭心。无论是在汽车新势力,还是放眼整个中国汽…...
AIPC专题:深耕笔电背光模组领域,AIPC与车载显示拉动公司成长
今天分享的是AIPC系列深度研究报告:《AIPC专题:深耕笔电背光模组领域,AIPC与车载显示拉动公司成长》。 (报告出品方:东兴证券) 报告共计:19页 公司深耕笔电背光模组,主要下游客户为…...
架构(十一)从0到1实现动态定时任务
一、引言 作者的平台项目最近需要实现一个功能,用户可选择这个任务什么时候执行,执行频率是什么? 这其实就是一个定时任务,只不过需要动态的,让用户自由选择。 二、原生实现 要实现这样的功能,可以直接依赖…...
Mybatis 批量插入数据 SQL
温故而知新,这里记录一下 案例1 批量插入时,xxxMapper.java 中方法的参数都必须是 List ,泛型可以是 bean ,也可以是 Map 。配合使用 mybatis 的 foreach 即可。示例如下: public Integer batchInsertDemo(List<D…...
【学员分享-考试心得】国产数据库潜力无限,云贝教育OBCP认证培训帮您解难题
近年来,随着国产化转型的推进,国外数据库的岗位需求逐渐减少,让许多IT从业者倍感压力。在这种情况下,了解国产数据库成为了求职市场上的竞争力。云贝老师们将聚焦于OceanBase、PostgreSQL、TDSQL等IT培训,探讨其对国产…...
【Mysql】事务的隔离级别与 MVCC
事务隔离级别 我们知道 MySQL 是一个 C/S 架构的服务,对于同一个服务器来说,可以有多个客户端与之连接,每个客户端与服务器连接上之后,就是一个会话( Session )。每个客户端都可以在自己的会话中向服务器发…...
MongoDB从入门到实战之MongoDB快速入门
前言 上一章节主要概述了MongoDB的优劣势、应用场景和发展史。这一章节将快速的概述一下MongoDB的基本概念,带领大家快速入门MongoDB这个文档型的NoSQL数据库。 MongoDB从入门到实战的相关教程 MongoDB从入门到实战之MongoDB简介👉 MongoDB从入门到实战…...
Linux服务详解
如有错误或有补充,以及任何改进的意见,请在评论区留下您的高见,同时文中给出大部分命令的示例,即是您暂时无法在Linux中查看,您也可以知道各种操作的功能以及输出 如果觉得本文写的不错,不妨点个赞&#x…...
闲聊电脑(4)硬盘分区
夜深人静,万籁俱寂,老郭趴在电脑桌上打盹,桌子上的小黄鸭和桌子旁的冰箱又开始窃窃私语…… 小黄鸭:冰箱大哥,上次你说的那个“分区”和“格式化”是什么意思? 冰箱:分区么,就是分…...
光耦合器的结构与原理解析
光耦合器是一种重要的电光转换器件,广泛应用于电子设备、通信系统以及工业控制等领域。本文将深入分析光耦合器的结构与原理,旨在为读者提供清晰而全面的了解。 光耦合器作为一种关键的电子元件,扮演着信号隔离和传输的重要角色。它的设计结构…...
【杂谈】-递归进化:人工智能的自我改进与监管挑战
递归进化:人工智能的自我改进与监管挑战 文章目录 递归进化:人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管?3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...
Java 语言特性(面试系列1)
一、面向对象编程 1. 封装(Encapsulation) 定义:将数据(属性)和操作数据的方法绑定在一起,通过访问控制符(private、protected、public)隐藏内部实现细节。示例: public …...
ubuntu搭建nfs服务centos挂载访问
在Ubuntu上设置NFS服务器 在Ubuntu上,你可以使用apt包管理器来安装NFS服务器。打开终端并运行: sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享,例如/shared: sudo mkdir /shared sud…...
FFmpeg 低延迟同屏方案
引言 在实时互动需求激增的当下,无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作,还是游戏直播的画面实时传输,低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架,凭借其灵活的编解码、数据…...
[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...
ElasticSearch搜索引擎之倒排索引及其底层算法
文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...
深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...
什么是Ansible Jinja2
理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具,可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板,允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板,并通…...
GruntJS-前端自动化任务运行器从入门到实战
Grunt 完全指南:从入门到实战 一、Grunt 是什么? Grunt是一个基于 Node.js 的前端自动化任务运行器,主要用于自动化执行项目开发中重复性高的任务,例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...
