From d1448cb0ef10f358bb7bddb4e1ec268515e0b787 Mon Sep 17 00:00:00 2001 From: gaoluyang <2820782392@qq.com> Date: 星期二, 15 七月 2025 11:46:57 +0800 Subject: [PATCH] 项目初始化 --- components/qian-tree/qian-tree.vue | 425 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 425 insertions(+), 0 deletions(-) diff --git a/components/qian-tree/qian-tree.vue b/components/qian-tree/qian-tree.vue new file mode 100644 index 0000000..e4deed7 --- /dev/null +++ b/components/qian-tree/qian-tree.vue @@ -0,0 +1,425 @@ +<template xlang="wxml"> + <view class="tki-tree"> + <view class="tki-tree-mask" :class="{'show':showTree}" @tap="_cancel"></view> + <view class="tki-tree-cnt" :class="{'show':showTree}"> + <view class="tki-tree-bar"> + <view class="tki-tree-bar-cancel" :style="{'color':cancelColor}" hover-class="hover-c" @tap="_cancel">鍙栨秷</view> + <view class="tki-tree-bar-title" :style="{'color':titleColor}">{{title}}</view> + <view class="tki-tree-bar-confirm" :style="{'color':confirmColor}" hover-class="hover-c" @tap="_confirm">纭畾</view> + </view> + <view class="tki-tree-view"> + <scroll-view class="tki-tree-view-sc" :scroll-y="true"> + <block v-for="(item, index) in treeList" :key="index"> + <view class="tki-tree-item" :style="[{ + paddingLeft: item.rank*15 + 'px', + zIndex: item.rank*-1 +50 + }]" + :class="{ + border: border === true, + show: item.show, + last: item.lastRank, + showchild: item.showChild, + open: item.open, + }"> + <view class="tki-tree-label" @tap.stop="_treeItemTap(item, index)"> + <image class="tki-tree-icon" :src="item.lastRank ? lastIcon : item.showChild ? currentIcon : defaultIcon"></image> + {{item.name}} + </view> + <view class="tki-tree-check" @tap.stop="_treeItemSelect(item, index)" v-if="selectParent?true:item.lastRank"> + <view class="tki-tree-check-yes" v-if="item.checked" :class="{'radio':!multiple}" :style="{'border-color':confirmColor}"> + <view class="tki-tree-check-yes-b" :style="{'background-color':confirmColor}"></view> + </view> + <view class="tki-tree-check-no" v-else :class="{'radio':!multiple}" :style="{'border-color':confirmColor}"></view> + </view> + </view> + </block> + </scroll-view> + </view> + </view> + </view> +</template> + +<script> + export default { + name: "tki-tree", + props: { + lazy: { + type: Boolean, + default: false + }, + range: { + type: Array, + default: function() { + return [] + } + }, + idKey: { + type: String, + default: 'id' + }, + rangeKey: { + type: String, + default: 'label' + }, + title: { + type: String, + default: '' + }, + multiple: { // 鏄惁鍙互澶氶�� + type: Boolean, + default: false + // default: true + }, + selectParent: { //鏄惁鍙互閫夌埗绾� + type: Boolean, + default: false + }, + foldAll: { //鎶樺彔鏃跺叧闂墍鏈夊凡缁忔墦寮�鐨勫瓙闆嗭紝鍐嶆鎵撳紑鏃堕渶瑕佷竴绾т竴绾ф墦寮� + type: Boolean, + default: false + }, + confirmColor: { // 纭畾鎸夐挳棰滆壊 + type: String, + default: '' // #07bb07 + }, + cancelColor: { // 鍙栨秷鎸夐挳棰滆壊 + type: String, + default: '' // #757575 + }, + titleColor: { // 鏍囬棰滆壊 + type: String, + default: '' // #757575 + }, + currentIcon: { // 灞曞紑鏃跺�欑殑ic + type: String, + default: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFEAAABRCAYAAACqj0o2AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MEQ0QTM0MzQ1Q0RBMTFFOUE0MjY4NzI1Njc1RjI1ODIiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MEQ0QTM0MzU1Q0RBMTFFOUE0MjY4NzI1Njc1RjI1ODIiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDowRDRBMzQzMjVDREExMUU5QTQyNjg3MjU2NzVGMjU4MiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDowRDRBMzQzMzVDREExMUU5QTQyNjg3MjU2NzVGMjU4MiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PidwepsAAAK0SURBVHja7JxbTsJAFIYHww7ciStgCeoGvGxAiOsgURegoL5720AXYLiIr0aJviq3Zx3PhIEnKG3ndtr+f3KixrSUj/ZjzjClIqUUiFm2gAAQAREQEUAEREAERAQQAREQAREBREAEREBEEqa67h9RFDWllDv0awWYlqlQHmu1WjMRRMoV1QFttA12y3xRtdNczq8EsE4/f8FumX2q77ROvNXk8UGMEKdUz6tYJHljaZAbuyUH+UR1to5BEohTuqwPCeS4pAA/qY6o/kyHOAMCeRK3owJnj+rH1jjxhqpVsstaebCz6TmnHWyXyY+xHjSBWBY/bvSgadtXBj9u9KCN3rnIfkzkQVsTEEX0Y2IP2oKo/HhMICcFAThUcwVZNGU6FdbX/XURzkbVF4+ybGhjPrFdgP66QdXNurGtSdk6Xdb9nAJ8oDo3OQlsQZzkdPw41ONBo6vI5scDefRjZg+6gpg3Pxp50CXEvPjR2IOuIXL3oxUPuobI3Y9WPOgDIlc/WvOgL4iL/vqFCcD7LH0xB4hj7cfQ/fWH9qCT+FhG0tN+DBk1PzjOM0SVllixcsBT1AvYc/kAPhc0hRg/3uvxoCgKRN9+dOrBUBB9+9GpB0NC9OVH5x4MDdG1H714kANEV3705kEOEBf9dcPi/lQnsuvLg1wgSu3Ha0v7Uh4MMgUXeuG71H407a+VBy9CPQkOdw+MtB+nGbd/D+FBbhBNxo9SjwcngJjNj0E9yBFiFj8G9SBXiGn8GNyDnCEm8SMLD3KHGOdHNh7kDjHOj2w8mAeIi/5arX+c6b/fxHz9oADEdGdjR/fXCw/OOB5oVfCOgnepz8IB14PMw03jCmTE+QBx5z0gAmKSqK9OUF+hcAeIhu/QYr4Qie8rjW83hhMBERARQAREQAREBBABERCLnH8BBgA+TQI7U4t53AAAAABJRU5ErkJggg==' + }, + defaultIcon: { // 鎶樺彔鏃跺�欑殑ic + type: String, + default: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFEAAABRCAYAAACqj0o2AAACE0lEQVR4Xu3c200DMRCF4XEltJAOkEugA+ggpUAHoQMqiFMCdEAJUMEiS4mEELlIO7bPOeN9i6K1rG/952myyea1WiCtXmEuYBPR4RBMxInoIOCwhOtJLKVszWyXc/5y2BvNEq6I+/3+kFK6M7OHnPM7jcLKjbZAvD/uaZtzflm5P4rbWyJWgDcze1LPuzVihfxUz7sH4ilJ2bx7Isrm3RtRMu8RiHJ5j0SUyXs0okTeCIj0eSMh0uaNhkiZNyIiXd7IiDR5oyNS5M2ACJ83EyJs3myIkHkzIsLlzYwIkzc7IkTeCojD81ZCHJa3GuKQvBURu+etjNgtb3XELnlHQGyedyTEZnlHQ2ySd0RE97wjI7rlHR3RJe+JeIrbLOecD6ePpZQ6W1kn2epo4MUrPOKyLN8ppYq1+y1VStncOjIdGnFZlo+U0uOtWOeOY2TE12Ouq//pEA7xXL7XfvcufR8K0Svfv6CREN3yDYfYIt9QiK3yjYTYLF95xB75SiP2ylcZsVu+cogj8pVCHJWvEuKwfOkREfKlRkTJlxkRJl86RMR8qRBR82VChM0XHpEhX2hElnyREWnyhUNkzBcKkTVfJETafIcjKuQ7FFEl35GIMvl2R1TMtyuiar49EWXzbY5oZpv/hibXTF2h3+s60FRKeT6+3TjMS3nrA3ZFRD8xrfY3ER1kJ+JEdBBwWGKeRAfEH1wS5WFZSDB/AAAAAElFTkSuQmCC' + }, + lastIcon: { // 娌℃湁瀛愰泦鐨刬c + type: String, + default: '' + }, + border: { // 鏄惁鏈夊垎鍓茬嚎 + type: Boolean, + default: false + }, + }, + data() { + return { + showTree: false, + treeList: [], + selectIndex: -1, + returnedItem: [] ,//瀹氫箟涓�涓┖鏁扮粍 + pids: [], + ancestorsIds: [], + childNums: [], + } + }, + computed: {}, + methods: { + _show() { + this.showTree = true + }, + _hide() { + this.showTree = false + }, + _cancel() { + this._hide() + this.$emit("cancel", ''); + }, + _confirm() { + // 澶勭悊鎵�閫夋暟鎹� + let rt = [], + obj = {}; + this.treeList.forEach((v, i) => { + if (this.treeList[i].checked) { + rt.push(this.treeList[i].id) + } + }) + this._hide() + this.$emit("confirm", rt); + }, + //鎵佸钩鍖栨爲缁撴瀯 + _renderTreeList(list = [], rank = 0, parentId = [], parents = []) { + list.forEach(item => { + this.treeList.push({ + id: item[this.idKey], + name: item[this.rangeKey], + source: item, + parentId, // 鐖剁骇id鏁扮粍 + parents, // 鐖剁骇id鏁扮粍 + rank, // 灞傜骇 + showChild: false, //瀛愮骇鏄惁鏄剧ず + open: false, //鏄惁鎵撳紑 + show: rank === 0, // 鑷韩鏄惁鏄剧ず + hideArr: [], + orChecked: item.checked ? item.checked : false, + checked: item.checked ? item.checked : false, + childNum: 0 + }) + + if (Array.isArray(item.children) && item.children.length > 0) { + // console.log(item) + let parentid = [...parentId], + parentArr = [...parents]; + delete parentArr.children + parentid.push(item[this.idKey]); + parentArr.push({ + [this.idKey]: item[this.idKey], + [this.rangeKey]: item[this.rangeKey] + }) + // lazy + if(!this.lazy) { + this._renderTreeList(item.children, rank + 1, parentid, parentArr) + } + } else { + this.treeList[this.treeList.length - 1].lastRank = true; + } + }) + }, + // 澶勭悊榛樿閫夋嫨 + _defaultSelect() { + this.treeList.forEach((v, i) => { + if (v.checked) { + this.treeList.forEach((v2, i2) => { + if (v.parentId.toString().indexOf(v2.parentId.toString()) >= 0) { + v2.show = true + if (v.parentId.includes(v2.id)) { + v2.showChild = true; + v2.open = true; + } + } + }) + } + }) + }, + getOwn(id, arr){ + //鍒╃敤foreach寰幆閬嶅巻 + arr.forEach((item) => { + //鍒ゆ柇閫掑綊缁撴潫鏉′欢 + if(item[this.idKey] == id) + { + // 瀛樺偍鏁版嵁鍒扮┖鏁扮粍 + this.returnedItem = item + } + else if(item.children != null) //鍒ゆ柇chlidren鏄惁鏈夋暟鎹� + { + //閫掑綊璋冪敤 + this.getOwn(id, item.children); + } + }) + return this.returnedItem + }, + setShow (id, arr, isShow) { + arr.forEach((item, index) => { + if(item.parentId.includes(id)) { + this.treeList[index].showChild = isShow + this.treeList[index].show = isShow + } else if (item.children !== undefined) { + this.setShow(id, item.children, isShow) + } + }) + }, + // 鐐瑰嚮 + _treeItemTap(item, index) { + // console.log(item) + if (item.lastRank === true) { + //鐐瑰嚮鏈�鍚庝竴绾ф椂瑙﹀彂浜嬩欢 + this.treeList[index].checked = !this.treeList[index].checked + this._fixMultiple(index) + return; + } + let id = item.id; + item.showChild = !item.showChild; + // qingqian + if(item.showChild) { + const range = this.range + const parentIdArr = item.parentId + // 鎵惧埌褰撳墠鍏冪礌 + const own = this.getOwn(id, range) + const checkedChildren = own.children + // 瀛愬厓绱犳彃鍏ョ殑绱㈠紩浣嶇疆 + const nextIndex = this.treeList.findIndex(itemT => itemT.id === item.id) + console.log(checkedChildren); + if(checkedChildren === undefined || checkedChildren.length < 1) { + return + } + // 瀛愯妭鐐规暟閲� + this.treeList[index].childNum = checkedChildren.length + const newRank = item.rank + 1 + checkedChildren.forEach(itemC => { + const childObj = { + id: itemC[this.idKey], + name: itemC[this.rangeKey], + source: {}, + parentId: [item.id], // 鐖剁骇id鏁扮粍 + parents: [item], // 鐖剁骇id鏁扮粍 + rank: newRank, // 灞傜骇 + showChild: false, //瀛愮骇鏄惁鏄剧ず + open: false, //鏄惁鎵撳紑 + show: 1, // 鑷韩鏄惁鏄剧ず + hideArr: [], + orChecked: this.treeList[index].checked, + checked: this.treeList[index].checked, + } + if(!this.treeList.some(itemT => itemT.id === itemC[this.idKey])) { + this.treeList.splice(nextIndex+1,0,childObj) + } + }) + } + // 灞曞紑/闅愯棌瀛愮骇/瀛欑骇 + let list = this.treeList + item.open = item.showChild ? true : !item.open; + list.forEach((childItem, i) => { + if (item.showChild === false) { + //闅愯棌鎵�鏈夊瓙绾� + if (!childItem.parentId.includes(id)) { + return; + } + //TODO: 淇敼 + if (!this.foldAll) { + if (childItem.lastRank !== true && !childItem.open) { + childItem.showChild = false; + this.setShow(childItem.id, this.treeList, false) + } + // 涓洪殣钘忕殑鍐呭娣诲姞涓�涓爣璁� + if (childItem.show) { + childItem.hideArr[item.rank] = id + } + } else { + if (childItem.lastRank !== true) { + childItem.showChild = false; + // 缁х画闅愯棌瀛愮骇鐨勭殑瀛愮骇 + this.setShow(childItem.id, this.treeList, false) + } + } + if(childItem.children !== undefined) { + childItem.children.forEach((childItem1, i1) => { + if(!childItem1.parentId.includes(childItem.id)) { + return + } + childItem.children[i1].showChild = false + childItem.children[i1].show = false + }) + } + childItem.show = false; + } else { + // 鎵撳紑瀛愰泦 + if (childItem.parentId[childItem.parentId.length - 1] === id) { + childItem.show = true; + } + // 鎵撳紑琚殣钘忕殑瀛愰泦 + if (childItem.parentId.includes(id) && !this.foldAll) { + // console.log(childItem.hideArr) + if (childItem.hideArr[item.rank] === id) { + childItem.show = true; + if (childItem.open && childItem.showChild) { + childItem.showChild = true + } else { + childItem.showChild = false + } + childItem.hideArr[item.rank] = null + } + } + } + }) + }, + // 閫氳繃鐖秈d澶勭悊瀛愮骇 + syncChecked (trees, pid, checked) { + trees.forEach((item,index) => { + if(item.parentId.includes(pid)) { + this.treeList[index].checked = checked + this.syncChecked(trees, item.id, checked) + } else if(item.children !== undefined) { + this.syncChecked(item.children, pid, checked) + } + }) + }, + // 鑾峰彇鐖剁骇寰�涓婃墍鏈夊眰绾х殑id 骞跺悓姝ョ姸鎬� + setAncestors (pids, checked) { + this.treeList.forEach((item,index) => { + if(pids.includes(item.id)) { + if(checked && this.childNums[item.id] !== undefined && item.childNum === this.childNums[item.id]) { + // 瀛愮骇鍏ㄩ儴閫変腑, 鐖剁骇鎵嶉�変腑 + this.treeList[index].checked = true + } else { + this.treeList[index].checked = false + } + this.setAncestors(item.parentId, checked) + } + }) + }, + _treeItemSelect(item, index) { + this.treeList[index].checked = !this.treeList[index].checked + // 閫夌埗绾�, 瀛愮骇鑷姩鍏ㄩ�� + this.syncChecked(this.treeList, item.id, this.treeList[index].checked) + + if(item.rank > 0) { + item.parentId.forEach((pid, indexP) => { + const parent = this.treeList.filter(i => i.id === pid) + const childNum = parent.length > 0 ? parent[0].childNum : 0 + if(this.childNums[pid] === undefined) { + this.childNums[pid] = 1 + } else if(this.childNums[pid] < childNum) { + this.childNums[pid]++ + } + }) + //瀛愮骇閫夋嫨/閫夋弧/鍙栨秷閫夋嫨, 鐖剁骇寰�涓婂悓姝ョ姸鎬� + this.setAncestors(item.parentId, this.treeList[index].checked) + } + this._fixMultiple(index) + }, + // 澶勭悊鍗曢�夊閫� + _fixMultiple(index) { + if (!this.multiple) { + // 濡傛灉鏄崟閫� + this.treeList.forEach((v, i) => { + if (i != index) { + this.treeList[i].checked = false + } else { + this.treeList[i].checked = true + } + }) + } + }, + // 閲嶇疆鏁版嵁 + _reTreeList() { + this.treeList.forEach((v, i) => { + this.treeList[i].checked = v.orChecked + }) + }, + _initTree(range = this.range){ + this.treeList = []; + this._renderTreeList(range); + this.$nextTick(() => { + this._defaultSelect(range) + }) + } + }, + watch: { + range(list) { + this._initTree(list); + }, + multiple() { + if (this.range.length) { + this._reTreeList(); + } + }, + selectParent() { + if (this.range.length) { + this._reTreeList(); + } + }, + }, + mounted() { + this._initTree(); + } + } +</script> + +<style scoped> + @import "./style.css"; +</style> -- Gitblit v1.9.3