[项目亮点(待结合自行设计的组件)]Vue中自定义设计——扩展性原则并以开源的vuedraggable为例

article/2025/6/14 15:24:05

在 Vue 中设计具有良好扩展性的自定义组件,需要遵循一系列设计原则,以确保组件在不同场景下的适应性和可维护性。以下是关键原则及一个示例,帮助您理解如何实现这一目标。


🧭 Vue 组件扩展性设计原则

  1. 开闭原则(Open/Closed Principle)
    组件应对扩展开放,对修改封闭。通过提供灵活的 props、插槽(slots)和事件机制,使组件在不修改内部代码的情况下,能够适应新的需求。

  2. 插槽机制(Slots)
    利用插槽允许父组件向子组件传递内容,实现内容的自定义和扩展,增强组件的灵活性。

  3. 属性驱动(Props)
    通过定义清晰的 props 接口,使组件的行为和样式可配置,便于在不同上下文中复用。

  4. 事件通信(Emits)
    使用 $emit 机制向父组件传递事件,保持组件的独立性和可组合性。

  5. 组合式 API(Composition API)
    在 Vue 3 中,使用组合式 API(如 setup 函数)将逻辑抽离为可复用的函数,提升组件的可扩展性和可维护性。

  6. 插件化架构
    对于大型项目,可采用插件化架构,将功能模块化,按需引入,提升系统的灵活性和可扩展性。


📦 示例:可扩展的通知组件 AlertBox.vue

以下是一个具有良好扩展性的通知组件示例,展示了如何应用上述原则:

<!-- AlertBox.vue -->
<template><div :class="['alert-box', typeClass]" role="alert"><slot name="icon"><!-- 默认图标 --><span class="default-icon">⚠️</span></slot><div class="alert-content"><slot>{{ message }}</slot></div><button v-if="closable" class="close-btn" @click="$emit('close')">×</button></div>
</template><script>
export default {name: 'AlertBox',props: {type: {type: String,default: 'info', // 可选值:'success', 'warning', 'error'},message: {type: String,default: '',},closable: {type: Boolean,default: false,},},computed: {typeClass() {return `alert-${this.type}`;},},
};
</script><style scoped>
.alert-box {padding: 1em;border-radius: 4px;position: relative;display: flex;align-items: center;
}
.alert-info {background-color: #e6f7ff;color: #1890ff;
}
.alert-success {background-color: #f6ffed;color: #52c41a;
}
.alert-warning {background-color: #fffbe6;color: #faad14;
}
.alert-error {background-color: #fff1f0;color: #f5222d;
}
.default-icon {margin-right: 0.5em;
}
.alert-content {flex: 1;
}
.close-btn {background: none;border: none;font-size: 1.2em;cursor: pointer;
}
</style>

使用示例:

<template><AlertBox type="success" message="操作成功!" closable @close="handleClose"><template #icon><CustomSuccessIcon /></template><template #default><strong>成功!</strong> 您的操作已完成。</template></AlertBox>
</template><script>
import AlertBox from './AlertBox.vue';
import CustomSuccessIcon from './CustomSuccessIcon.vue';export default {components: {AlertBox,CustomSuccessIcon,},methods: {handleClose() {// 处理关闭事件},},
};
</script>

特点说明:

  • 开闭原则:通过 props 和插槽提供扩展点,满足不同需求而无需修改组件内部。
  • 插槽机制:允许自定义图标和内容,增强灵活性。
  • 属性驱动:通过 type 控制样式,通过 message 设置默认内容。
  • 事件通信:通过 $emit('close') 通知父组件关闭事件。(博客园)

📚 进一步阅读

  • Vue 官方文档:组件基础
  • Vue.js 组件复用和扩展之道
  • Vue 3 插件化架构设计

通过遵循上述设计原则,并结合实际需求,您可以创建出具有良好扩展性的 Vue 组件,提升应用的灵活性和可维护性。


以下是基于 Vue.Draggable 的组件设计与实现详解,结合核心特性、扩展性设计和生命周期钩子应用,帮助你构建高灵活性的拖拽组件:


一、Vue.Draggable 核心特性

  1. 数据驱动

    • 通过 v-model 绑定数组,拖拽操作自动同步数据顺序。
    • 示例:
      <draggable v-model="items"><div v-for="item in items" :key="item.id">{{ item.name }}</div>
      </draggable>
      
  2. 跨列表拖拽

    • 使用 group 属性实现分组,同名组间可相互拖拽:
      <draggable group="shared" :list="listA"></draggable>
      <draggable group="shared" :list="listB"></draggable>
      
  3. 精细控制

    • 手柄拖拽handle=".drag-handle" 限制仅特定区域触发拖拽。
    • 禁止元素filter=".locked" 屏蔽指定元素拖拽。
    • 动画效果animation="300" 添加过渡动画。
  4. 事件钩子

    事件触发时机参数说明
    @start拖拽开始时包含被拖拽元素信息 { item, index }
    @end拖拽结束时包含目标位置信息
    @add元素添加到新列表时{ element, newIndex }
    @update列表内顺序变化时{ oldIndex, newIndex }

二、高扩展性组件设计

1. 动态插槽支持
  • 允许外部自定义拖拽项样式,提升复用性:
    <draggable v-model="items"><template #item="{ element }"><slot name="item" :item="element"><!-- 默认样式 --><div>{{ element.name }}</div></slot></template>
    </draggable>
    
2. 多UI库兼容
  • 通过 tagcomponentData 集成第三方组件(如 Element UI、Vuetify):
    <draggable tag="el-collapse" :component-data="{props: { accordion: true },on: { change: handleCollapseChange }}"
    ><el-collapse-item v-for="item in items" :key="item.id" />
    </draggable>
    
3. 条件控制扩展
  • 动态启用/禁用拖拽::options="{ disabled: !isEditable }"
  • 自定义拖拽验证逻辑::move="checkMove",通过返回值控制是否允许拖拽:
    checkMove(evt) {return evt.draggedContext.element.type !== 'locked';
    }
    

三、生命周期钩子深度整合

  1. 内置事件钩子

    • 拖拽开始/结束@start@end 用于记录操作日志或备份数据。
    • 数据变更时@update 同步到后端或触发业务逻辑。
  2. 自定义扩展钩子
    设计 beforeDragStartafterDragEnd 等自定义事件,增强灵活性:

    <template><draggable @start="handleStart"@end="handleEnd"/>
    </template>
    <script>
    export default {methods: {handleStart(evt) {this.$emit('before-drag-start', evt.item);},handleEnd(evt) {this.$emit('after-drag-end', evt.newIndex);}}
    }
    </script>
    

四、边界处理与性能优化

  1. 空列表处理

    • 添加 min-height 避免空容器无法拖入:
      .drag-container { min-height: 100px; }
      
  2. 大列表优化

    • 启用原生滚动::options="{ scroll: true, scrollSensitivity: 50 }"
    • 虚拟滚动:结合 vue-virtual-scroller 仅渲染可视区域项。
  3. 跨框架兼容

    • 在 Nuxt 等 SSR 框架中,需通过 Client-only 插件注册:
      // plugins/draggable.js
      import Vue from 'vue';
      import draggable from 'vuedraggable';
      Vue.component('draggable', draggable);
      

五、设计原则总结

  1. 分层设计

    • 基础层:封装 Vue.Draggable 的核心拖拽逻辑。
    • 业务层:通过插槽和 Props 注入业务组件。
    • 控制层:暴露事件钩子供外部干预流程。
  2. 配置优先
    将 Sortable.js 的配置项(如 groupanimation)设计为 Props 传递,而非硬编码。

  3. TypeScript 支持
    为 Props 和事件定义类型接口,提升组件可靠性:

    interface DraggableProps {list: any[];group?: string;animation?: number;
    }
    

最佳实践场景:看板系统、表单构建器、仪表盘布局编辑。通过组合式 API 封装拖拽逻辑,可在不同场景复用核心代码,仅替换视图层组件。


附录:关键配置速查表

属性说明示例值
v-model/list绑定数据数组:list="items"
group跨列表分组名group="kanban"
handle拖动手柄选择器handle=".drag-handle"
ghost-class拖拽占位符样式类ghost-class="ghost"
force-fallback强制使用 HTML5 拖拽:force-fallback="true"

通过上述设计,可实现从简单列表排序到企业级可视化搭建系统的灵活扩展,完整代码参考 Vue.Draggable 官方文档。
在这里插入图片描述


http://www.hkcw.cn/article/PDIcOmwObj.shtml

相关文章

【AcWing】899. 编辑距离

文章目录 一、题目1、原题链接2、题目描述 二、解题报告1、思路分析2、时间复杂度3、代码详解 一、题目 1、原题链接 902. 最短编辑距离 2、题目描述 二、解题报告 1、思路分析 思路参考来源y总 dp[i][j]表示将a[1~i]变为b[1~j]中所有方案的操作次数最少的一个&#xff1b;按…

Linux基本指令/下

目录 1.echo、cat与printf 2. > 操作符 与 >> 操作符 3. < 操作符 4.消息传送 linux文件深入 5.文件类型 6.mv命令 7.时间相关指令 8.查找命令 9.grep命令 10.zip/unzip/tar命令 11.scp命令 12.bc命令 13.uname 指令 14.快捷键大全 15.关机/重启/睡…

从gitee仓库中恢复IDEA项目某一版本

神奇的功能&#xff01;&#xff01;&#xff01;代码改乱了&#xff0c;但是还有救&#xff01; 打开终端&#xff0c;输入git log 复制想要恢复版本的提交哈希值&#xff0c;打开终端输入git reset --hard <哈希值> &#xff0c;就能修复到那时的提交版本了

排污许可证原始数据(1989-2025.5)

1156 排污许可证原始数据&#xff08;1989-2025.5&#xff09; “污染”年度发文数及主题分布 数据来源 本数据来源于全国排污许可证管理信息平台&#xff0c;由数据皮皮侠团队人工整理&#xff0c;全部内容真实有效。 时间跨度 1989-2025.5 数据范围 省、地级市企业 数…

华为云Flexus+DeepSeek征文|华为云 Flexus X 加速 Dify 平台落地:高性能、低成本、强可靠性的云上选择

目录 前言 1 一键部署 Dify 平台的完整步骤 1.1 选择模板 1.2 参数配置 1.3 资源栈设置 1.4 配置确认与部署 2 Flexus X 服务器的技术优势 2.1 柔性算力随心配 2.2 一直加速一直快 2.3 越用越省降本多 2.4 安全可靠更放心 3 Flexus X 在 Dify 解决方案中的性能体验…

【题解-洛谷】P9422 [蓝桥杯 2023 国 B] 合并数列

题目&#xff1a;P9422 [蓝桥杯 2023 国 B] 合并数列 题目描述 小明发现有很多方案可以把一个很大的正整数拆成若干正整数的和。他采取了其中两种方案&#xff0c;分别将他们列为两个数组 { a 1 , a 2 , ⋯ a n } \{a_1, a_2, \cdots a_n\} {a1​,a2​,⋯an​} 和 { b 1 , …

在Windows本地部署Dify详细操作

Dify官网文档&#xff1a;产品简介 - Dify Docs 1.硬件要求 2.部署方式选择 本次我选择Docker Compose 部署&#xff0c;接下来我将根据官方文档指引&#xff0c;在windows电脑上完成dify本地部署 3.DockerCompose本地部署Dify 3.1 安装WSL2 官方安装WSL2的操作说明入口&…

《彩云追月》音乐会尽展民乐柔美 传统与现代交融

5月30日晚,北京演艺集团旗下北京民族乐团在北京艺术中心上演了民族音乐会《彩云追月》。作为北京演艺集团第十一届“五月演出季”的收官项目,本场音乐会在著名指挥家张冰冰的执棒下,为观众呈现了一场融合传统与现代、柔美与激情的民乐之旅。音乐会以北京民族乐团原创作品《长…

深入理解交叉熵损失函数——全面推演各种形式

带你从不一样的视角综合认识交叉熵损失&#xff0c;阅读这篇文章&#xff0c;帮你建立其分类问题&#xff0c;对比学习&#xff0c;行人重识别&#xff0c;人脸识别等问题的联系&#xff0c;阅读这篇文章相信对你阅读各种底层深度学习论文有帮助。 引言 1. 重新理解全连接层&…

Java 异常

文章目录 异常异常和错误 异常的处理JVM处理异常和自己处理异常finally面试题异常的处理流程 自定义异常类 异常 异常&#xff1a;将程序执行过程中发生的不正常行为&#xff0c;异常也是一个类程序出现异常后将不会继续执行异常的分类&#xff1a;算术异常&#xff0c;空指针…

Postman 发送 SOAP 请求步骤 归档

0.来源 https://apifox.com/apiskills/sending-soap-requests-with-postman/?utm_sourceopr&utm_mediuma2bobzhang&utm_contentpostman 再加上自己一点实践经验 1. 创建一个新的POST请求 postman 创建一个post请求, 请求url 怎么来的可以看第三步 2. post请求设…

matlab/simulink TLC语法基础练习实例

一、基本语法测试方法 1.新建一个脚本&#xff0c;保存扩展名为tlc,本例中是tst.tlc&#xff0c;设置当前工作路径为保存的tlc文件路径&#xff0c;在tlc文件里面输入下面的代码&#xff0c;然后保存&#xff1a; %warning test 2.在MATLAB的命令窗口输入&#xff1a; tlc …

关联子串 - 华为OD统一考试(JavaScript题解)

华为OD机试题库《C》限时优惠 9.9 华为OD机试题库《Python》限时优惠 9.9 华为OD机试题库《JavaScript》限时优惠 9.9 针对刷题难&#xff0c;效率慢&#xff0c;我们提供一对一算法辅导&#xff0c; 针对个人情况定制化的提高计划&#xff08;全称1V1效率更高&#xff09;。 看…

[yolov11改进系列]基于yolov11引入重参数化模块DiverseBranchBlock的python源码+训练源码

【DiverseBranchBlock介绍】 摘要&#xff1a;我们提出一种通用的卷积网络构造块用来在不增加任何推理时间的前提下提升卷积网络的性能。我们将这个块命名为分离分支块&#xff08;Diverse Branch Block&#xff09;。通过结合不同尺寸和复杂度的分离分支&#xff08;包括串联…

Qt SQL模块基础

Qt SQL模块基础 一、Qt SQL模块支持的数据库 官方帮助文档中的Qt支持的数据库驱动如下图&#xff1a; Qt SQL 模块中提供了一些常见的数据库驱动&#xff0c;包括网络型数据库&#xff0c;如Qracle、MS SQL Server、MySQL等&#xff0c;也包括简单的单机型数据库。 Qt SQL支…

鸿蒙仓颉语言开发实战教程:实现商品分类页

今天继续为大家带来仓颉语言开发商城应用的实战教程&#xff0c;今天的内容是实现商品分类页。 分类页面要在基本布局的基础上增加一些动态效果&#xff0c;比如点击状态的切换和两个列表容器的联动。下面为大家详细介绍。 分类列表 先来看左侧的分类列表&#xff0c;很明显是…

笔试模拟 day15

观前提醒&#xff1a; 笔试所有系列文章均是记录本人的笔试题思路与代码&#xff0c;从中得到的启发和从别人题解的学习到的地方&#xff0c;所以关于题目的解答&#xff0c;只是以本人能读懂为目标&#xff0c;如果大家觉得看不懂&#xff0c;那是正常的。如果对本文的某些知…

Linux防止误关机

Linux防止误关机 安装reboot-guard结果验证关机 安装reboot-guard 兼容python2和python3 https://github.com/stephanritscher/reboot-guard # 下载 wget -cP /usr/sbin/ https://raw.githubusercontent.com/stephanritscher/reboot-guard/refs/heads/master/rguard# 赋予可…

tomcat安装二进制版本

1.安装部署tomcat 下载安装包 ​ wget https://repo.huaweicloud.com/java/jdk/7u80-b15/jdk-7u80-linux-x64.tar.gzwget https://archive.apache.org/dist/tomcat/tomcat-8/v8.0.1/bin/apache-tomcat-8.0.1.tar.gz​ 解压安装包&#xff1a; tar -axf jdk-7u80-linux-x64.t…

SAP学习笔记 - 开发15 - 前端Fiori开发 Boostrap,Controls,MVC(Model,View,Controller),Modules

上一章讲了Fiori开发的准备&#xff0c;以及宇宙至简之HelloWorld。 SAP学习笔记 - 开发14 - 前端Fiori开发 HelloWorld-CSDN博客 本章继续学习 Fiori 开发的知识&#xff1a; Bootstrap&#xff0c;Controls&#xff0c;MVC(Model&#xff0c;View&#xff0c;Controller&a…