Cocos creator实现飞机大战空中大战《战击长空》小游戏资源及代码
Cocos creator实现飞机大战空中大战《战击长空》小游戏资源及代码
最近在学习Cocos Creator,作为新手,刚刚开始学习Cocos Creator,刚刚入门,这里记录一下飞机大战小游戏实现。
https://wxaurl.cn/VEgRy2eTMyi
一 安装CocosDashBoard
这里就不介绍如何安装了
二 新建2D项目FlyWar
2.1、管理项目目录
在资源管理器中新建文件夹
anim 动画
preb 预制体
res 图片、语音资源
scene 场景
scripts 脚本资源
将资源文件拖到res目录下
三、关键步骤
3.1 实现背景的移动代码
背景的星空会有移动的效果
import GameConstant from "./GameConstant";const {ccclass, property} = cc._decorator;@ccclass
export default class MoveBackground extends cc.Component { bgs : cc.Node[];@propertyspeed : number = 50;canvasWidth: number;canvasHeight: number;onLoad () {let canvas = cc.find('Canvas');this.canvasWidth = canvas.width;this.canvasHeight = canvas.height;// 注册特定事件cc.director.on(GameConstant.kUpdateGameStatus, this.listenGameStatus, this);}listenGameStatus() {}start () {this.node.width= this.canvasWidth;this.node.height = this.canvasHeight;this.bgs = this.node.children;for (let index = 0; index < this.bgs.length; index++) {let element = this.bgs[index];element.width = this.canvasWidth;element.height = this.canvasHeight;}// 设置默认if (this.bgs.length >= 2) {this.bgs[1].y = this.bgs[0].y + this.bgs[0].height; }}update (dt) {this.bgs[0].y -= this.speed * dt;this.bgs[1].y -= this.speed * dt;if (this.bgs[0].y < -this.canvasHeight) {this.bgs[0].y = this.bgs[1].y + this.bgs[1].height;}if (this.bgs[1].y < -this.canvasHeight) {this.bgs[1].y = this.bgs[0].y + this.bgs[0].height;}}
}
3.2 实现自己飞机的绑定击碰撞检测
首先将load方法中开启碰撞检测
// 碰撞检测
cc.director.getCollisionManager().enabled = true;
将手指移动飞机
start() {// touch inputthis.node.on(cc.Node.EventType.TOUCH_START, this.onTouchBegan, this);this.node.on(cc.Node.EventType.TOUCH_END, this.onTouchEnded, this);this.node.on(cc.Node.EventType.TOUCH_CANCEL, this.onTouchEnded, this);this.node.on(cc.Node.EventType.TOUCH_MOVE, this.onTouchMove, this);}// touch事件onTouchBegan(event) {if (this.isSelected == true) {return;}let position = event.getLocation();this.isSelected = true;this.touchStartX = position.x;this.touchStartY = position.y;}onTouchEnded() {this.isSelected = false;}onTouchMove(e: cc.Event.EventTouch) {let gameStatus = GameStateManager.instance().getGameStatus();if (this.isSelected && (GameConstant.GameStatus.BOSSBOOMFINISH != gameStatus)) {let position = e.getLocation();let moveX = position.x;let moveY = position.y;let disX = (moveX - this.touchStartX);let disY = (moveY - this.touchStartY);this.updateNodeX(disX, disY);this.touchStartX = position.x;this.touchStartY = position.y;}}// 更新位置updateNodeX(distanceX, distanceY) {this.playerRoot.x += distanceX;if (this.playerRoot.x < -this.canvasWidth / 2) {this.playerRoot.x = -this.canvasWidth / 2;}if (this.playerRoot.x > this.canvasWidth / 2) {this.playerRoot.x = this.canvasWidth / 2;}this.playerRoot.y += distanceY;if (this.playerRoot.y < -this.canvasHeight / 2) {this.playerRoot.y = -this.canvasHeight / 2;}if (this.playerRoot.y > this.canvasHeight / 2) {this.playerRoot.y = this.canvasHeight / 2;}this.playerBulletRoot.x = this.playerRoot.x;this.playerBulletRoot.y = this.playerRoot.y + 50;}
玩家飞机的碰撞,当碰撞到不同的敌机就会出现血量减少的
onCollisionEnter(other, self) {if (this.isDead == true) {return;}let deltax = 0;if (other.tag == 999) {// 撞击到敌机BOSS// dead,游戏结束,跳转到结果页面this.isDead = true;this.showPlaneBoom();return;}if (other.tag == 888) {// 获得金币,每个金币50分this.updateScore();}if (other.tag == 911) {// 获得血量this.updateBlood();}if (other.tag == 100 || other.tag == 914) {// 默认子弹 -1// 减去血量this.bloodNumber -= 1;deltax = 1;} else if (other.tag == 101 || other.tag == 102) {// boss大炮弹 -5this.bloodNumber -= 5;deltax = 5;} else if ((other.tag == 90 || other.tag == 91)) {// 敌机 -2this.bloodNumber -= 2;deltax = 2;}if (this.bloodNumber <= 0) {// dead,游戏结束,跳转到结果页面this.isDead = true;this.showPlaneBoom();}if (this.bloodNumber < 0) {this.bloodNumber = 0;}this.updateBloodUI(deltax);}
// 血量控制参考
https://blog.csdn.net/gloryFlow/article/details/130898462
3.2 实现当前飞机发射子弹的效果
当前子弹发射会有角度设置,代码如下
import EnemyPlane from "./EnemyPlane";const {ccclass, property} = cc._decorator;// 直线的Bullet类型
@ccclass
export default class BulletLiner extends cc.Component {// 角度,默认90@property(Number)rotation: number = 90;// 速度@property(Number)speed: number = 1000;// 时间@property(Number)time: number = 0.0;// 时间点lifeTime: number = 2.5;// LIFE-CYCLE CALLBACKS:// 初始位置originPos: any;canvasWidth: number;canvasHeight: number;isDead: boolean = false;onLoad() {let canvas = cc.find('Canvas');this.canvasWidth = canvas.width;this.canvasHeight = canvas.height;}start () {this.originPos = this.node.position;}update (dt) {this.onMove(dt);}// 移动onMove(dt) {let distance = dt * this.speed;let radian = this.rotation * Math.PI / 180;let v2 = this.node.position; let delta = cc.v2(distance * Math.cos(radian), distance * Math.sin(radian));v2.x += delta.x;v2.y += delta.y;this.node.position = v2;if (v2.y > this.canvasHeight) {this.node.removeFromParent();this.node.destroy();}}onCollisionEnter(other, self) {if ((other.tag != 110 && other.tag != 1111 && other.tag != 9911 && other.tag != 911 && other.tag != 888) && !this.isDead) {this.die();}}die() {this.isDead = true;this.node.removeFromParent();this.destroy();}
}
3.4 敌机的移动击及碰撞检测
import GameStateManager from "./GameStateManager";const { ccclass, property } = cc._decorator;// 敌人飞机
@ccclass
export default class EnemyPlane extends cc.Component {// 角度,默认90@property(Number)rotation: number = 90;// 速度@property(Number)speed: number = 1000;// 时间@property(Number)time: number = 0.0;// 时间点lifeTime: number = 2.5;// LIFE-CYCLE CALLBACKS:// 初始位置originPos: any;canvasWidth: number;canvasHeight: number;@property(cc.Prefab)enemyBoom: cc.Prefab = null;@property(cc.Prefab)enemyBullet: cc.Prefab = null;@property([cc.Prefab])coinPrebs: cc.Prefab[] = [];// 音效资源@property(cc.AudioClip)boomAudio: cc.AudioClip = null;isDead: boolean = false;isBoomAnimating: boolean = false;onLoad() {let canvas = cc.find('Canvas');this.canvasWidth = canvas.width;this.canvasHeight = canvas.height;}start() {this.originPos = this.node.position;this.enemyBulletSchedule();}update(dt) {this.onMove(dt);}// 移动onMove(dt) {// this.time += dt;// if (this.time >= this.lifeTime) {// this.node.position = this.originPos;// this.time = 0;// }let distance = dt * this.speed;let radian = this.rotation * Math.PI / 180;let v2 = this.node.position;let delta = cc.v2(distance * Math.cos(radian), distance * Math.sin(radian));v2.x -= delta.x;v2.y -= delta.y;this.node.position = v2;if (v2.y < -this.canvasHeight) {this.node.removeFromParent();this.node.destroy();}}// 动效效果showPlaneBoom() {if (this.isBoomAnimating) {return;}// 调用声音引擎播放声音cc.audioEngine.playEffect(this.boomAudio, false);this.isBoomAnimating = true;// 播放动画let boom;let callFunc = cc.callFunc(function () {this.createCoin();boom = cc.instantiate(this.enemyBoom);this.node.parent.addChild(boom);boom.setPosition(this.node.position);this.node.removeFromParent();let anim = boom.getComponent(cc.Animation);anim.play('enemy_boom');}, this);let aTime = cc.delayTime(0.1);let finish = cc.callFunc(function () {boom.removeFromParent();boom.destroy();this.isBoomAnimating = false;this.removeFromParent();this.destroy();}, this);// 创建一个缓动var tween = cc.tween()// 按顺序执行动作.sequence(callFunc, aTime, finish);cc.tween(this.node).then(tween).start();}onCollisionEnter(other, self) {if ((other.tag == 110 || other.tag == 1111) && !this.isDead) {this.die();}}die() {this.isDead = true;this.showPlaneBoom();this.updateScore();}// 更新得分updateScore() {// 每个敌机得分为10GameStateManager.instance().updateScore(10);}// 创建金币 每个金币10分createCoin() {let delta = 50;for (let index = 0; index < this.coinPrebs.length; index++) {let coin = cc.instantiate(this.coinPrebs[index]);this.node.parent.addChild(coin);coin.setPosition(this.node.position);coin.x = this.node.x + Math.random() * delta;coin.y = this.node.y;}}// 倒计时enemyBulletSchedule() {this.schedule(this.onCreateEnemyBullet, 1.5);}onCreateEnemyBullet() {let bullet = cc.instantiate(this.enemyBullet);this.node.parent.addChild(bullet);bullet.setPosition(this.node.position);bullet.x = this.node.x;bullet.y = this.node.y;}stopSchedule() {this.unschedule(this.onCreateEnemyBullet);}protected onDestroy(): void {this.stopSchedule();}
}
3.5 敌机BOSS
敌机BOSS有血量
当前敌机BOSS只要血量为0时候就是击败了该BOSS
// Learn TypeScript:
// - https://docs.cocos.com/creator/2.4/manual/en/scripting/typescript.html
// Learn Attribute:
// - https://docs.cocos.com/creator/2.4/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
// - https://docs.cocos.com/creator/2.4/manual/en/scripting/life-cycle-callbacks.htmlimport EnemyBossBoom from "./EnemyBossBoom";
import GameConstant from "./GameConstant";
import GameStateManager from "./GameStateManager";const {ccclass, property} = cc._decorator;@ccclass
export default class EnemyBossPlane extends cc.Component {@property(cc.Prefab)bloodBarPreb: cc.Prefab = null;// boss爆炸效果@property(cc.Prefab)bossBoomPreb: cc.Prefab = null;// 血量@property(Number)bloodCount: number = 100;@property(Number)bloodNumber: number = 100;// LIFE-CYCLE CALLBACKS:bloodBar: cc.ProgressBar = null;isDead: boolean = false;onLoad () {// 不同等级boss的血量不同// this.bloodNumber = 100;// this.bloodCount = 100;let blood = cc.instantiate(this.bloodBarPreb);blood.y = 100;blood.x = 0;this.node.addChild(blood);this.bloodBar = blood.getComponent(cc.ProgressBar);this.bloodBar.progress = 1.0;this.bloodBar.getComponentInChildren(cc.Label).string = ""+this.bloodNumber;}start () {this.bloodBar.getComponentInChildren(cc.Label).string = ""+this.bloodNumber;}update (dt) {}// 更新血量updateBloodCount(aBloodCount) {this.bloodNumber = aBloodCount;this.bloodCount = aBloodCount;}onCollisionEnter(other, self) {if (this.isDead == true) {return;}let deltax = 0;if (other.tag == 110) {// 默认子弹 -1// 减去血量this.bloodNumber -= 1;deltax = 1;} if (this.bloodNumber <= 0) {// dead,游戏结束,跳转到结果页面this.isDead = true;this.startBossBoom();}if (this.bloodNumber < 0) {this.bloodNumber = 0;}this.bloodBar.getComponentInChildren(cc.Label).string = ""+this.bloodNumber;let progress = this.bloodNumber/this.bloodCount;let totalLength = this.bloodBar.totalLength;this.bloodBar.getComponentInChildren(cc.Label).node.x -= deltax*(totalLength/this.bloodCount);this.bloodBar.progress = progress;}// boss爆炸了startBossBoom() {GameStateManager.instance().updateGameStatus(GameConstant.GameStatus.BOSSDISMISSING);let bossBoom = cc.instantiate(this.bossBoomPreb);bossBoom.y = 0;bossBoom.x = 0;this.node.addChild(bossBoom);bossBoom.getComponent(EnemyBossBoom).setBossBoomFinished(()=>{this.updateScore();this.bossBoomFinish();});bossBoom.getComponent(EnemyBossBoom).startPlayAnimation();}// 爆炸效果结束了bossBoomFinish() {this.node.removeAllChildren();this.node.removeFromParent();this.node.destroy();// 通知移除全部子弹、敌机飞机、暂停玩家飞机发射子弹后,GameStateManager.instance().updateIsWin(true);// 玩家飞机向上飞行后提示通关,继续创下一关GameStateManager.instance().updateGameStatus(GameConstant.GameStatus.BOSSBOOMFINISH);}// 更新得分updateScore() {// 每个BOSS得分为血量GameStateManager.instance().updateScore(this.bloodCount);}
}
3.6 敌机BOSS来回移动并且发射导弹
// 左右移动moveLeftRight() {// 让节点左右来回移动并一直重复var seq = cc.repeatForever(cc.sequence(cc.moveTo(5, cc.v2(-this.canvasWidth / 2, this.node.y)),cc.moveTo(5, cc.v2(this.canvasWidth / 2, this.node.y))));this.node.runAction(seq);}
// 每次创建一波Boss子弹startCreateBossBullet() {var time = 0.5;this.schedule(this.onCreateBossBullet, time);}onCreateBossBullet() {var bullet = cc.instantiate(this.getBossBullet());this.node.parent.addChild(bullet);var x = this.node.x;var y = this.node.y - this.node.height + bullet.height;bullet.setPosition(cc.v2(x, y));}stopSchedule() {this.unschedule(this.onCreateDBullet);this.unschedule(this.onCreateBossBullet);}onDestroy() {this.stopSchedule();}
四、最后可以扫码看下效果。
搜索微信小游戏:战击长空
五、下载地址
https://gitee.com/baibaime/plane-war.git
相关文章:

Cocos creator实现飞机大战空中大战《战击长空》小游戏资源及代码
Cocos creator实现飞机大战空中大战《战击长空》小游戏资源及代码 最近在学习Cocos Creator,作为新手,刚刚开始学习Cocos Creator,刚刚入门,这里记录一下飞机大战小游戏实现。 https://wxaurl.cn/VEgRy2eTMyi 一 安装CocosDashBo…...

2.4 逻辑代数的基本定理
学习目标: 如果我要学习逻辑代数的基本定理,我会采取以下步骤: 1. 学习基本概念:首先,我会花时间了解逻辑代数的基本概念,如逻辑运算符(合取、析取、否定等)、真值表、逻辑等价性等…...

适用于 Linux 的 Windows 子系统wsl文档
参考链接:https://learn.microsoft.com/zh-cn/windows/wsl/ 鸟哥的Linux私房菜:http://cn.linux.vbird.org/ http://cn.linux.vbird.org/linux_basic/linux_basic.php http://cn.linux.vbird.org/linux_server/ 目录 安装列出可用的 Linux 发行版列出已…...

C++特殊类的设计与类型转换
特殊类的设计与类型转换 特殊类的设计请设计一个类,只能在堆上创建对象请设计一个类,只能在栈上创建对象请设计一个类,只能创建一个对象(单例模式) C的类型转换 特殊类的设计 请设计一个类,只能在堆上创建对象 通过new创建的类就…...
如何通过关键词搜索API接口
如果你是一位电商运营者或者是想要进行1688平台产品调研的人员,你可能需要借助API接口来获取你所需要的信息。在这篇文章中,我们将会讨论如何通过关键词搜索API接口获取1688的商品详情。 第一步:获取API接口的授权信息 在使用API接口前&…...
智驾域控新战争打响,谁在抢跑?
智能驾驶域控制器赛道,已经成为了时下最为火热的市场焦点之一。 最近,头部Tier1均胜电子公布了全球首批基于高通Snapdragon Ride第二代芯片平台的智能驾驶域控制器产品nDriveH,在这一赛道中显得格外引人注意。 就在不久之前,均胜…...
Android 13无源码应用去掉无资源ID的按钮
Android Wifionly项目,客户要求去掉谷歌联系人里的 手机联系人按钮 需求分析 无应用源码,只能通过系统侧去修改 首先通过 Android Studio 工具 uiautomatorviewer 获取父控件资源ID chip_group ,然后通过遍历获取子控件去掉目标按钮 --- a/frameworks/base/core/java/andr…...
【SCI征稿】中科院2区(TOP),正刊,SCIEEI双检,进化计算、模糊集和人工神经网络在数据不平衡中应用
【期刊简介】IF:8.0-9.0,JCR1区,中科院2区(TOP) 【检索情况】SCIE&EI 双检,正刊 【数据库收录年份】2004年 【国人占比】22.78%(期刊国际化程度高) 【征稿领域】进化计算、模…...
Android Audio开发——AAudio基础(十五)
AAudio 是一个自 Android O 引入的新的 Android C API。它主要是为需要低延迟的高性能音频应用设计的。应用程序通过直接从流中读取或向流中写入数据来与 AAudio 通信,但它只包含基本的音频输入输出能力。 一、AAudio概述 AAudio 在应用程序和 Android 设备上的音频输入输出之…...

SDK接口远程调试【内网穿透】
文章目录 1.测试环境2.本地配置3. 内网穿透3.1 下载安装cpolar内网穿透3.2 创建隧道 4. 测试公网访问5. 配置固定二级子域名5.1 保留一个二级子域名5.2 配置二级子域名 6. 使用固定二级子域名进行访问 转发自cpolar内网穿透的文章:Java支付宝沙箱环境支付࿰…...

Mybatis学习笔记二
目录 一、MyBatis的各种查询功能1.1 查询一个实体类对象1.2 查询一个List集合1.3 查询单个数据1.4 查询一条数据为map集合1.5 查询多条数据为map集合1.5.1 方法一:1.5.2 方法二: 二、特殊SQL的执行2.1 模糊查询2.2 批量删除2.3 动态设置表名2.4 添加功能…...

大屏数据可视化开源项目
一、DataGear —— 数据可视化项目 官网:DataGear - 开源免费的数据可视化分析平台 DataGear 是一款开源免费的数据可视化分析平台,数据可视化看板。 功能特性: 1、多种数据源,支持运行时接入任意提供 JDBC 驱动的数据库&#…...
面试经典150题:数组/字符串合集
新专栏,预计两个月写完吧,每天下班回来抽空做几道题。会把做题计划顺序记录下来,如果你有缘,刷到这个开篇序列,那就跟着文章去练题吧。初学者可以慢慢来 88. 合并两个有序数组 void merge(vector<int>& nums…...
Java源文件的执行过程
目录 1.JVM 2.字节码 3.Java源文件执行的过程 4.JIT(Just In Time Compilation) 5.AOT(Ahead Of Time Compilation) 6.AOT破坏Java动态性 7.编译型语言与解释型语言 8.Java-编译与解释并存的语言 9.Java和C的相同点与不同…...

10个ai算法常用库java版
今年ChatGPT 火了半年多,热度丝毫没有降下来。深度学习和 NLP 也重新回到了大家的视线中。有一些小伙伴问我,作为一名 Java 开发人员,如何入门人工智能,是时候拿出压箱底的私藏的学习AI的 Java 库来介绍给大家。 这些库和框架为机器学习、深度学习、自然语言处理等提供了广…...
怎么看服务器带宽大小 103.219.179.X
第一种,可以使用网站测速,这种方式比较便捷,但是由于网站测速是测试服务器发送数据包到他网站节点的一个速度情况,有时候节点问题或者服务器做了封包限制可能导致测试不准确的情况。 第二种,可以在IIS上架设一个大一点…...

图形编辑器开发:最基础但却复杂的选择工具
大家好,我是前端西瓜哥。 对于一个图形设计软件,它最基础的工具是什么?选择工具。 但这个选择工具,却是相当的复杂。这次我来和各位,细说细说选择工具的一些弯弯道道。 我正在开发的图形设计工具的: http…...
apk签名-signapk.jar
如果做平台app开发,需要签platform签名,除了通过adroid.bp或者android.mk的方式使用AOSP整个大工程中签名外,还可以直接通过signapk.jar的方式进行签名,效率更高更快捷简便。 首先我们来回顾下AOSP平台签名的办法。 Android.mk 使…...

【100个高大尚求职简历】简历模板+修改教程+行业分类简历模板 (涵盖各种行业) (简历模板+编辑指导+修改教程)
文章目录 1 简历预览2 简历下载 很多人说自己明明投了很多公司的简历,但是都没有得到面试邀请的机会。自己工作履历挺好的,但是为什么投自己感兴趣公司的简历,都没有面试邀请的机会。反而是那些自己没有投递的公司,经常给自己打电…...
Nginx平滑升级版本或添加模块
文章目录 一、Nginx 平滑升级二、升级失败 回滚操作三、遇到问题 一、Nginx 平滑升级 一般有两种情况下需要升级 nginx,一种是确实要升级 nginx 的版本,另一种是要为 nginx 添加新的模块。 Nginx平滑升级其原理简单概括: (1&am…...
conda相比python好处
Conda 作为 Python 的环境和包管理工具,相比原生 Python 生态(如 pip 虚拟环境)有许多独特优势,尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处: 一、一站式环境管理:…...

Opencv中的addweighted函数
一.addweighted函数作用 addweighted()是OpenCV库中用于图像处理的函数,主要功能是将两个输入图像(尺寸和类型相同)按照指定的权重进行加权叠加(图像融合),并添加一个标量值&#x…...
Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器
第一章 引言:语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域,文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量,支撑着搜索引擎、推荐系统、…...
【JavaSE】绘图与事件入门学习笔记
-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角,以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向,距离坐标原点x个像素;第二个是y坐标,表示当前位置为垂直方向,距离坐标原点y个像素。 坐标体系-像素 …...
Element Plus 表单(el-form)中关于正整数输入的校验规则
目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入(联动)2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...

Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
智能AI电话机器人系统的识别能力现状与发展水平
一、引言 随着人工智能技术的飞速发展,AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术,在客户服务、营销推广、信息查询等领域发挥着越来越重要…...

解析奥地利 XARION激光超声检测系统:无膜光学麦克风 + 无耦合剂的技术协同优势及多元应用
在工业制造领域,无损检测(NDT)的精度与效率直接影响产品质量与生产安全。奥地利 XARION开发的激光超声精密检测系统,以非接触式光学麦克风技术为核心,打破传统检测瓶颈,为半导体、航空航天、汽车制造等行业提供了高灵敏…...
git: early EOF
macOS报错: Initialized empty Git repository in /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/.git/ remote: Enumerating objects: 2691797, done. remote: Counting objects: 100% (1760/1760), done. remote: Compressing objects: 100% (636/636…...

Vue3 PC端 UI组件库我更推荐Naive UI
一、Vue3生态现状与UI库选择的重要性 随着Vue3的稳定发布和Composition API的广泛采用,前端开发者面临着UI组件库的重新选择。一个好的UI库不仅能提升开发效率,还能确保项目的长期可维护性。本文将对比三大主流Vue3 UI库(Naive UI、Element …...