当前位置: 首页 > news >正文

uniapp使用uview UI,自定义级联选择组件

一、需求:

1.省市区级联选择,可多选
2.可以一键选择某个区域下的所有数据
3.点击省展开市,点击市展开区,以此类推(可返回上一层或多层)
4.只获取选择的人

效果视频

二、注意事项以及源码

1.需要安装uView UI组件库,安装地址uView UI官网

2.源码,复制即用

<template><view class="container"><!-- 层级导航 --><view class="breadcrumb"><text class="breadcrumb-item" v-for="(item, index) in breadcrumbList" :key="index" @click="goBackToLevel(index)":class="{ 'breadcrumb-item-active': index === breadcrumbList.length - 1 }">{{ item }}<text v-if="index !== breadcrumbList.length - 1" class="breadcrumb-separator"> ></text></text></view><!-- 层级内容 --><view class="level-content"><view class="level-item" v-for="(item, index) in currentLevelData" :key="item.id"><!-- 将点击事件移到内部元素,避免与复选框冲突 --><view class="level-item-left" @click="handleLevelItemClick(item)"><view class="level-icon" :style="{ backgroundColor: getLevelColor(item) }"><text class="level-icon-text">{{ getLevelCode(item) }}</text></view><view class="level-info"><text class="level-title">{{ item.name }}</text><text class="level-desc">{{ item.leaf ? item.emergencyPersonnel.phone : `${getAllLeafCount(item)} 个人员` }}</text></view></view><view class="select-checkbox"><u-checkbox :checked="isNodeSelected(item)" :indeterminate="isNodeIndeterminate(item)"@change="(value) => handleNodeSelect(item, value)" shape="circle" active-color="#4F46E5"></u-checkbox></view></view></view><!-- 底部操作栏 --><view class="footer-bar"><view class="selected-info"><u-icon name="account-fill" size="30" color="#4F46E5"></u-icon><text class="selected-count">已选择 {{ selectedPersons.length }}</text></view><u-button type="primary" @click="toFormPage" :disabled="selectedPersons.length === 0"class="next-button">下一步</u-button></view></view>
</template><script>
export default {data() {return {// 人员数据结构(修改后:新增省份、简化字段、常见姓名)personnelData: [{"id": "510000","name": "四川省","children": [{"id": "511400","name": "眉山市","children": [{"id": "市管理员","name": "市管理员","children": [{"id": "10","name": "赵六","children": [],"emergencyPersonnel": {"unitName": "市管理员","unitAddress": "眉山市政务服务中心","personName": "赵六","phone": "19162984018","provinceName": "四川省","cityName": "眉山市","countyName": ""},"leaf": true},{"id": "11","name": "孙七","children": [],"emergencyPersonnel": {"unitName": "市管理员","unitAddress": "眉山市政务服务中心","personName": "孙七","phone": "18180809001","provinceName": "四川省","cityName": "眉山市","countyName": ""},"leaf": true}],"emergencyPersonnel": null,"leaf": false}],"emergencyPersonnel": null,"leaf": false}],"emergencyPersonnel": null,"leaf": false},{"id": "440000","name": "广东省","children": [{"id": "440100","name": "广州市","children": [{"id": "天河区管理员","name": "天河区管理员","children": [{"id": "12","name": "周八","children": [],"emergencyPersonnel": {"unitName": "天河区管理员","unitAddress": "广州市天河区政务中心","personName": "周八","phone": "18228880309","provinceName": "广东省","cityName": "广州市","countyName": "天河区"},"leaf": true},{"id": "13","name": "吴九","children": [],"emergencyPersonnel": {"unitName": "天河区管理员","unitAddress": "广州市天河区政务中心","personName": "吴九","phone": "18990370720","provinceName": "广东省","cityName": "广州市","countyName": "天河区"},"leaf": true}],"emergencyPersonnel": null,"leaf": false},{"id": "海珠区管理员","name": "海珠区管理员","children": [{"id": "14","name": "郑十","children": [],"emergencyPersonnel": {"unitName": "海珠区管理员","unitAddress": "广州市海珠区政务中心","personName": "郑十","phone": "15508337779","provinceName": "广东省","cityName": "广州市","countyName": "海珠区"},"leaf": true}],"emergencyPersonnel": null,"leaf": false}],"emergencyPersonnel": null,"leaf": false},{"id": "440300","name": "深圳市","children": [{"id": "南山区管理员","name": "南山区管理员","children": [{"id": "15","name": "钱十一","children": [],"emergencyPersonnel": {"unitName": "南山区管理员","unitAddress": "深圳市南山区政务中心","personName": "钱十一","phone": "15983336111","provinceName": "广东省","cityName": "深圳市","countyName": "南山区"},"leaf": true}],"emergencyPersonnel": null,"leaf": false}],"emergencyPersonnel": null,"leaf": false}],"emergencyPersonnel": null,"leaf": false},{"id": "330000","name": "浙江省","children": [{"id": "330100","name": "杭州市","children": [{"id": "西湖区管理员","name": "西湖区管理员","children": [{"id": "16","name": "冯十二","children": [],"emergencyPersonnel": {"unitName": "西湖区管理员","unitAddress": "杭州市西湖区政务中心","personName": "冯十二","phone": "18783398823","provinceName": "浙江省","cityName": "杭州市","countyName": "西湖区"},"leaf": true},{"id": "17","name": "陈十三","children": [],"emergencyPersonnel": {"unitName": "西湖区管理员","unitAddress": "杭州市西湖区政务中心","personName": "陈十三","phone": "13547674447","provinceName": "浙江省","cityName": "杭州市","countyName": "西湖区"},"leaf": true}],"emergencyPersonnel": null,"leaf": false},{"id": "余杭区管理员","name": "余杭区管理员","children": [{"id": "18","name": "褚十四","children": [],"emergencyPersonnel": {"unitName": "余杭区管理员","unitAddress": "杭州市余杭区政务中心","personName": "褚十四","phone": "18160172259","provinceName": "浙江省","cityName": "杭州市","countyName": "余杭区"},"leaf": true}],"emergencyPersonnel": null,"leaf": false}],"emergencyPersonnel": null,"leaf": false}],"emergencyPersonnel": null,"leaf": false}],// 当前层级数据currentLevelData: [],// 层级导航路径breadcrumbList: [],// 已选择的人员selectedPersons: [],// 层级历史记录,用于返回levelHistory: []};},onLoad() {// 初始化层级数据(因personnelData改为数组,此处调整为加载所有省份)this.currentLevelData = this.personnelData;this.breadcrumbList = ["全国"];this.levelHistory = [this.currentLevelData];},methods: {// 获取层级颜色getLevelColor(item) {if (item.leaf) {return '#E0E7FF';}const colors = ['#E0F2FE', '#DBEAFE', '#EFF6FF', '#F0FDF4', '#FEF3C7'];let hash = 0;for (let i = 0; i < item.name.length; i++) {hash = item.name.charCodeAt(i) + ((hash << 5) - hash);}return colors[Math.abs(hash) % colors.length];},// 获取层级代码getLevelCode(item) {if (item.leaf) {return item.name.charAt(0);}return item.name.substring(0, 2);},// 递归获取某个节点下的所有叶子节点getAllLeafNodes(node) {let leafNodes = [];if (node.leaf) {leafNodes.push(node);} else if (node.children && node.children.length > 0) {node.children.forEach(child => {leafNodes = leafNodes.concat(this.getAllLeafNodes(child));});}return leafNodes;},// 计算某个节点下的叶子节点总数getAllLeafCount(node) {return this.getAllLeafNodes(node).length;},// 判断某个节点的选中状态isNodeSelected(node) {const leafNodes = this.getAllLeafNodes(node);if (node.leaf) {return this.selectedPersons.some(p => p.id === node.id);}return leafNodes.every(leaf =>this.selectedPersons.some(p => p.id === leaf.id));},// 判断某个非叶子节点是否半选isNodeIndeterminate(node) {if (node.leaf) return false;const leafNodes = this.getAllLeafNodes(node);const selectedLeafCount = leafNodes.filter(leaf =>this.selectedPersons.some(p => p.id === leaf.id)).length;return selectedLeafCount > 0 && selectedLeafCount < leafNodes.length;},// 将叶子节点转换为selectedPersons格式convertLeafToSelected(leafNode) {return {id: leafNode.id,name: leafNode.name,phone: leafNode.emergencyPersonnel.phone,unitName: leafNode.emergencyPersonnel.unitName,unitAddress: leafNode.emergencyPersonnel.unitAddress,provinceName: leafNode.emergencyPersonnel.provinceName,cityName: leafNode.emergencyPersonnel.cityName,countyName: leafNode.emergencyPersonnel.countyName};},// 处理节点选择 - 修正事件参数问题handleNodeSelect(node, checked) {const leafNodes = this.getAllLeafNodes(node);if (checked) {// 选中操作:添加所有未选中的叶子节点leafNodes.forEach(leaf => {const isExist = this.selectedPersons.some(p => p.id === leaf.id);if (!isExist) {this.selectedPersons.push(this.convertLeafToSelected(leaf));}});} else {// 取消选中:移除所有相关叶子节点this.selectedPersons = this.selectedPersons.filter(p =>!leafNodes.some(leaf => leaf.id === p.id));}},// 处理层级项点击handleLevelItemClick(item) {if (!item.leaf && item.children && item.children.length > 0) {// 判断当前层级是否是最外层(全国层级)const isRootLevel = this.breadcrumbList.length === 1 && this.breadcrumbList[0] === "全国";if (!isRootLevel) {this.breadcrumbList.push(item.name);} else {// 从全国进入省份时,更新导航路径this.breadcrumbList = ["全国", item.name];}this.currentLevelData = item.children;this.levelHistory.push(this.currentLevelData);}},// 返回上一级goBackToLevel(index) {if (index >= this.breadcrumbList.length - 1) return;// 调整导航路径this.breadcrumbList = this.breadcrumbList.slice(0, index + 1);// 调整层级历史this.levelHistory = this.levelHistory.slice(0, index + 1);// 更新当前层级数据this.currentLevelData = this.levelHistory[index];},// 前往表单页面toFormPage() {console.log(this.selectedPersons);if (this.selectedPersons.length === 0) {this.$u.toast('请至少选择一个人员');return;}}}
};
</script><style scoped>
/* 样式保持不变 */
.container {background-color: #F8F8F8;min-height: 100vh;padding-bottom: 60px;
}.breadcrumb {padding: 12px 15px;background-color: white;display: flex;align-items: center;font-size: 14px;overflow-x: auto;white-space: nowrap;
}.breadcrumb-item {color: #6B7280;padding: 0 2px;
}.breadcrumb-item-active {color: #4F46E5;font-weight: 500;
}.breadcrumb-separator {margin: 0 4px;color: #D1D5DB;
}.level-content {background-color: white;padding-top: 10px;
}.level-item {display: flex;align-items: center;justify-content: space-between;padding: 12px 15px;border-bottom: 1px solid #F3F4F6;
}.level-item-left {display: flex;align-items: center;width: 80%;
}.level-icon {width: 36px;height: 36px;border-radius: 50%;display: flex;align-items: center;justify-content: center;
}.level-icon-text {font-size: 14px;font-weight: 500;color: #4F46E5;
}.level-info {margin-left: 12px;
}.level-title {font-size: 16px;color: #1F2937;
}.level-desc {font-size: 12px;color: #6B7280;margin-top: 2px;display: block;
}.select-checkbox {width: 20px;height: 20px;display: flex;align-items: center;justify-content: center;
}.footer-bar {position: fixed;bottom: 0;left: 0;right: 0;background-color: white;display: flex;align-items: center;justify-content: space-between;padding: 10px 15px;border-top: 1px solid #F3F4F6;}.selected-info {display: flex;align-items: center;color: #1F2937;font-size: 14px;
}.selected-count {margin-left: 5px;
}.next-button {width: 120px;border-radius: 20px;
}
</style>
http://www.xdnf.cn/news/1422631.html

相关文章:

  • 六、练习3:Gitee平台操作
  • RSA的CTF题目环境和做题复现第1集
  • shell——函数与数组
  • 华东制造企业推荐的SD-WAN服务商排名
  • java中常见的几种排序算法
  • 毕业设计:丹麦电力电价预测预测未来24小时的电价pytorch+lstm+历史特征和价格+时间序列 电价预测模型资源 完整代码数据可直接运行
  • js脚本和ts脚本相互调用
  • 虚拟机一插SD卡就蓝屏,导致整个电脑系统蓝屏怎么办
  • 一、SVN与svnbucket.com常见问题解答
  • PTP高精度时间同步的核心:E2E与P2P延迟补偿机制
  • FPGA|Quartus II 中pll IP核的具体使用方法
  • 优化正则表达式性能:预编译与模式匹配的最佳实践
  • Coolutils Total PDF Converter中文版:多功能PDF文件转换器
  • 奇偶破题:当反函数撞上奇函数
  • 【前端:Html】--4.进阶:媒体
  • 【论文阅读】Sparse4D v3:Advancing End-to-End 3D Detection and Tracking
  • 订单后台管理系统-day07菜品模块
  • MIT 6.5840 (Spring, 2024) 通关指南——Lab 2: Key/Value Server
  • openssh 安装部署
  • 【Day 41】Shell脚本-循环
  • 802.11 和 802.1X
  • 谷歌-PCR-CA-联合训练并行小码本引入语义特征
  • wpf之WrapPanel
  • RAG-文本到SQL
  • 国别域名的SEO优势:是否更利于在当地搜索引擎排名?
  • Linux -- 进程间通信【System V共享内存】
  • 软考中级习题与解答——第二章_程序语言与语言处理程序(1)
  • vue社区网格化管理系统(代码+数据库+LW)
  • PRACH物理层详解
  • Flutter Container 阴影设置指南 2025版