首页 > 分享 > Uniapp微信开发树形选择组件

Uniapp微信开发树形选择组件

1.本组件依据ba-tree-picker树形层级选择器(支持单选、多选、父级选择、映射) - DCloud 插件市场
原组件进行修改,修复了样式,新增了默认展开全部树形和数据回显的功能,详细功能可能需要改造原组件
2.组件代码

<!-- 树形层级选择器-->

<!-- 1、支持单选、多选 -->

<template>

<view class="tree-dialog show">

<view class="tree-view">

<scroll-view class="tree-list" :scroll-y="true">

<block v-for="(item, index) in treeList" :key="index">

<view

class="tree-item"

:style="[

{

paddingLeft: item.level * 30 + 'rpx',

},

]"

:class="{

itemBorder: border === true,

show: item.isShow,

}"

>

<view class="item-label">

<view

class="item-icon uni-inline-item"

@tap.stop="_onItemSwitch(item, index)"

>

<view

v-if="!item.isLastLevel && item.isShowChild"

class="switch-on"

:style="{ 'border-left-color': switchColor }"

>

</view>

<view

v-else-if="!item.isLastLevel && !item.isShowChild"

class="switch-off"

:style="{ 'border-top-color': switchColor }"

>

</view>

<view

v-else

class="item-last-dot"

:style="{ 'border-top-color': switchColor }"

>

</view>

</view>

<view

class="uni-flex-item uni-inline-item"

@tap.stop="_onItemSelect(item, index)"

>

<view class="item-name">

<div class="name">

{{

item.name +

(item.childCount ? "(" + item.childCount + ")" : "")

}}

</div>

<div class="name" v-if="item.childCount == 0">

{{ item.phone }}

</div>

</view>

<view

class="item-check"

v-if="selectParent ? true : item.isLastLevel"

>

<view

class="item-check-yes"

v-if="item.checkStatus == 1"

:class="{ radio: !multiple }"

:style="{ 'border-color': confirmColor }"

>

<view

class="item-check-yes-part"

:style="{ 'background-color': confirmColor }"

>

</view>

</view>

<view

class="item-check-yes"

v-else-if="item.checkStatus == 2"

:class="{ radio: !multiple }"

:style="{ 'border-color': confirmColor }"

>

<view

class="item-check-yes-all"

:style="{ 'background-color': confirmColor }"

>

</view>

</view>

<view

class="item-check-no"

v-else

:class="{ radio: !multiple }"

:style="{ 'border-color': confirmColor }"

></view>

</view>

</view>

</view>

</view>

</block>

</scroll-view>

</view>

<view class="tree-bar">

<view

class="tree-bar-cancel"

:style="{ color: cancelColor }"

hover-class="hover-c"

@tap="_cancel"

>重置

</view>

<view

class="tree-bar-confirm"

:style="{ color: confirmColor }"

hover-class="hover-c"

@tap="_confirm"

>

确定

</view>

</view>

</view>

</template>

<script>

export default {

emits: ["select-change"],

name: "ba-tree-picker",

props: {

valueKey: {

type: String,

default: "id",

},

textKey: {

type: String,

default: "name",

},

childrenKey: {

type: String,

default: "children",

},

localdata: {

type: Array,

default: function () {

return [];

},

},

localTreeList: {

type: Array,

default: function () {

return [];

},

},

selectedData: {

type: Array,

default: function () {

return [];

},

},

title: {

type: String,

default: "",

},

multiple: {

type: Boolean,

default: true,

},

selectParent: {

type: Boolean,

default: true,

},

confirmColor: {

type: String,

default: "",

},

cancelColor: {

type: String,

default: "",

},

titleColor: {

type: String,

default: "",

},

switchColor: {

type: String,

default: "",

},

border: {

type: Boolean,

default: false,

},

Users: {

type: Array,

default: () => [],

},

},

data() {

return {

showDialog: true,

treeList: [],

};

},

computed: {},

methods: {

_show() {

this.showDialog = true;

},

_hide() {

this.showDialog = false;

},

_cancel() {

this._hide();

this.$emit("cancel", "");

},

_confirm() {

let selectedList = [];

let selectedNames;

let currentLevel = -1;

this.treeList.forEach((item, index) => {

if (currentLevel >= 0 && item.level > currentLevel) {

console.log("itemid", item.id);

selectedList.push(item.id);

} else {

if (item.checkStatus === 2) {

if (item.level == 1) {

selectedList.push(item.id);

}

currentLevel = item.level;

selectedNames = selectedNames

? selectedNames + " / " + item.name

: item.name;

} else {

currentLevel = -1;

}

}

});

this._hide();

this.$emit("select-change", selectedList, selectedNames);

},

_formatTreeData(list = [], level = 0, parentItem, isShowChild = true) {

let nextIndex = 0;

let parentId = -1;

let initCheckStatus = 0;

if (parentItem) {

nextIndex =

this.treeList.findIndex((item) => item.id === parentItem.id) + 1;

parentId = parentItem.id;

if (!this.multiple) {

initCheckStatus = 0;

} else initCheckStatus = parentItem.checkStatus == 2 ? 2 : 0;

}

list.forEach((item) => {

let isLastLevel = true;

if (item && item[this.childrenKey]) {

let children = item[this.childrenKey];

if (Array.isArray(children) && children.length > 0) {

isLastLevel = false;

}

}

let itemT = {

id: item[this.valueKey],

name: item[this.textKey],

phone: item.phone,

type: item.type,

level,

isLastLevel,

isShow: isShowChild,

isShowChild: false,

checkStatus: initCheckStatus,

orCheckStatus: 0,

parentId,

children: item[this.childrenKey],

childCount: item[this.childrenKey]

? item[this.childrenKey].length

: 0,

childCheckCount: 0,

childCheckPCount: 0,

};

if (this.selectedData.indexOf(itemT.id) >= 0) {

itemT.checkStatus = 2;

itemT.orCheckStatus = 2;

itemT.childCheckCount = itemT.children ? itemT.children.length : 0;

this._onItemParentSelect(itemT, nextIndex);

}

this.treeList.splice(nextIndex, 0, itemT);

nextIndex++;

});

},

_onItemSwitch(item, index) {

if (item.isLastLevel === true) {

return;

}

item.isShowChild = !item.isShowChild;

if (item.children) {

this._formatTreeData(item.children, item.level + 1, item);

item.children = undefined;

} else {

this._onItemChildSwitch(item, index);

}

console.log("thissssssssss", this.treeList);

},

showAll() {

console.log("333", this.treeList);

let Tree = JSON.parse(JSON.stringify(this.treeList));

Tree.forEach((item, index) => {

console.log("item.children", item.children);

if (item.children) {

this._formatTreeData(item.children, item.level + 1, item);

} else {

this._onItemChildSwitch(item, index);

}

});

console.log("Tree", Tree);

let YuanList = this.treeList;

console.log("YuanList", YuanList);

YuanList.forEach((item, index) => {

let find = this.Users.find((user) => {

return user == item.id;

});

if (find) {

console.log("find", item, index);

this._onItemSelect(item, index + 1);

}

});

},

_onItemChildSwitch(item, index) {

const firstChildIndex = index + 1;

if (firstChildIndex > 0)

for (var i = firstChildIndex; i < this.treeList.length; i++) {

let itemChild = this.treeList[i];

if (itemChild.level > item.level) {

if (item.isShowChild) {

if (itemChild.parentId === item.id) {

itemChild.isShow = item.isShowChild;

if (!itemChild.isShow) {

itemChild.isShowChild = false;

}

}

} else {

itemChild.isShow = item.isShowChild;

itemChild.isShowChild = false;

}

} else {

return;

}

}

},

_onItemSelect(item, index) {

console.log("_onItemSelect", item, index);

if (!this.multiple) {

item.checkStatus = item.checkStatus == 0 ? 2 : 0;

this.treeList.forEach((v, i) => {

if (i != index) {

this.treeList[i].checkStatus = 0;

} else {

this.treeList[i].checkStatus = 2;

}

});

let selectedList = [];

let selectedNames;

selectedList.push(item.id);

selectedNames = item.name;

this._hide();

this.$emit("select-change", selectedList, selectedNames);

return;

}

let oldCheckStatus = item.checkStatus;

switch (oldCheckStatus) {

case 0:

item.checkStatus = 2;

item.childCheckCount = item.childCount;

item.childCheckPCount = 0;

break;

case 1:

case 2:

item.checkStatus = 0;

item.childCheckCount = 0;

item.childCheckPCount = 0;

break;

default:

break;

}

this._onItemChildSelect(item, index);

this._onItemParentSelect(item, index, oldCheckStatus);

},

_onItemChildSelect(item, index) {

let allChildCount = 0;

if (item.childCount && item.childCount > 0) {

index++;

while (

index < this.treeList.length &&

this.treeList[index].level > item.level

) {

let itemChild = this.treeList[index];

itemChild.checkStatus = item.checkStatus;

if (itemChild.checkStatus == 2) {

itemChild.childCheckCount = itemChild.childCount;

itemChild.childCheckPCount = 0;

} else if (itemChild.checkStatus == 0) {

itemChild.childCheckCount = 0;

itemChild.childCheckPCount = 0;

}

index++;

}

}

},

_onItemParentSelect(item, index, oldCheckStatus) {

const parentIndex = this.treeList.findIndex(

(itemP) => itemP.id == item.parentId

);

if (parentIndex >= 0) {

let itemParent = this.treeList[parentIndex];

let count = itemParent.childCheckCount;

let oldCheckStatusParent = itemParent.checkStatus;

if (oldCheckStatus == 1) {

itemParent.childCheckPCount -= 1;

} else if (oldCheckStatus == 2) {

itemParent.childCheckCount -= 1;

}

if (item.checkStatus == 1) {

itemParent.childCheckPCount += 1;

} else if (item.checkStatus == 2) {

itemParent.childCheckCount += 1;

}

if (

itemParent.childCheckCount <= 0 &&

itemParent.childCheckPCount <= 0

) {

itemParent.childCheckCount = 0;

itemParent.childCheckPCount = 0;

itemParent.checkStatus = 0;

} else if (itemParent.childCheckCount >= itemParent.childCount) {

itemParent.childCheckCount = itemParent.childCount;

itemParent.childCheckPCount = 0;

itemParent.checkStatus = 2;

} else {

itemParent.checkStatus = 1;

}

this._onItemParentSelect(itemParent, parentIndex, oldCheckStatusParent);

}

},

_reTreeList() {

this.treeList.forEach((v, i) => {

this.treeList[i].checkStatus = v.orCheckStatus;

});

},

_initTree() {

this.treeList = [];

this._formatTreeData(this.localdata);

},

},

watch: {

localdata() {

this._initTree();

},

localTreeList() {

this.treeList = this.localTreeList;

},

},

mounted() {

this._initTree();

setTimeout(() => {

this.showAll();

}, 300);

console.log("treeList", this.treeList);

},

};

</script>

<style scoped lang="scss">

.tree-dialog {

height: 100%;

background-color: #fff;

border-top-left-radius: 10px;

border-top-right-radius: 10px;

display: flex;

flex-direction: column;

z-index: 102;

font-size: 28upx;

top: 20%;

transition: all 0.3s ease;

transform: translateY(100%);

}

.tree-dialog.show {

transform: translateY(0);

}

.tree-bar {

position: fixed;

bottom: 0;

left: 0;

right: 0;

height: 90rpx;

padding-left: 25rpx;

padding-right: 25rpx;

display: flex;

justify-content: space-between;

align-items: center;

box-sizing: border-box;

border-bottom-width: 1rpx !important;

border-bottom-style: solid;

border-bottom-color: #f5f5f5;

font-size: 32rpx;

color: #757575;

line-height: 1;

}

.tree-bar-confirm {

display: flex;

align-items: center;

justify-content: center;

color: #0055ff;

background-color: $cc-theme-color;

color: #fff;

height: 80upx;

border-radius: 40upx;

line-height: 80upx;

flex: 1;

flex-shrink: 0;

}

.tree-bar-cancel {

display: flex;

align-items: center;

justify-content: center;

flex: 1;

flex-shrink: 0;

margin-right: 20upx;

color: $cc-theme-color;

border: 1px solid $cc-theme-color;

height: 80upx;

border-radius: 40upx;

line-height: 80upx;

}

.tree-view {

flex: 1;

padding: 20rpx;

display: flex;

flex-direction: column;

overflow: hidden;

height: 100%;

margin-bottom: 100upx;

}

.tree-list {

flex: 1;

height: 100%;

overflow: hidden;

}

.tree-item {

display: flex;

justify-content: space-between;

align-items: center;

line-height: 1;

height: 0;

opacity: 0;

transition: 0.2s;

overflow: hidden;

}

.tree-item.show {

height: 90rpx;

opacity: 1;

}

.tree-item.showchild:before {

transform: rotate(90deg);

}

.tree-item.last:before {

opacity: 0;

}

.switch-on {

width: 0;

height: 0;

border-left: 10rpx solid transparent;

border-right: 10rpx solid transparent;

border-top: 15rpx solid #666;

}

.switch-off {

width: 0;

height: 0;

border-bottom: 10rpx solid transparent;

border-top: 10rpx solid transparent;

border-left: 15rpx solid #666;

}

.item-last-dot {

position: absolute;

width: 10rpx;

height: 10rpx;

border-radius: 100%;

background: #666;

}

.item-icon {

width: 26rpx;

height: 26rpx;

padding-left: 20rpx;

}

.item-label {

flex: 1;

display: flex;

align-items: center;

height: 100%;

}

.uni-flex-item {

width: 100%;

display: flex;

align-items: center;

justify-content: space-between;

}

.item-name {

display: flex;

align-items: center;

justify-content: space-between;

flex: 1;

overflow: hidden;

text-overflow: ellipsis;

white-space: nowrap;

}

.item-check {

width: 40px;

height: 40px;

display: flex;

justify-content: center;

align-items: center;

}

.item-check-yes,

.item-check-no {

width: 20px;

height: 20px;

border-top-left-radius: 20%;

border-top-right-radius: 20%;

border-bottom-right-radius: 20%;

border-bottom-left-radius: 20%;

border-top-width: 1rpx;

border-left-width: 1rpx;

border-bottom-width: 1rpx;

border-right-width: 1rpx;

border-style: solid;

border-color: #0055ff;

display: flex;

justify-content: center;

align-items: center;

box-sizing: border-box;

}

.item-check-yes-part {

width: 12px;

height: 12px;

border-top-left-radius: 20%;

border-top-right-radius: 20%;

border-bottom-right-radius: 20%;

border-bottom-left-radius: 20%;

background-color: #0055ff;

}

.item-check-yes-all {

margin-bottom: 5px;

border: 2px solid #007aff;

border-left: 0;

border-top: 0;

height: 12px;

width: 6px;

transform-origin: center;

transition: all 0.3s;

transform: rotate(45deg);

}

.item-check .radio {

border-top-left-radius: 50%;

border-top-right-radius: 50%;

border-bottom-right-radius: 50%;

border-bottom-left-radius: 50%;

}

.item-check .radio .item-check-yes-b {

border-top-left-radius: 50%;

border-top-right-radius: 50%;

border-bottom-right-radius: 50%;

border-bottom-left-radius: 50%;

}

.hover-c {

opacity: 0.6;

}

.itemBorder {

border-bottom: 1px solid #e5e5e5;

}

</style>

javascript

运行

2.使用代码

<baTreePicker

ref="treePicker"

:multiple="true"

@select-change="selectChange"

:localdata="listData"

:Users="Users"

valueKey="id"

textKey="name"

childrenKey="children"

/>

javascript

运行

3.结构

相关知识

基于uniapp微信小程序的摄影街拍圈子交流平台
分享课程——uniapp+vue3+云开发全栈开发同城配送鲜花小程序任意商城项目
uniapp中引入公共组件
APP开发,原生APP开发,vue前端APP开发,uniapp混合APP开发,物料APP,电商APP,视频APP,直播APP,社区团购APP,社交电商APP
【开题报告】基于uniapp的鲜花预定APP的设计与实现
web前端开发项目案例
微信小程序插件
鲜花商城购物系统开发实战:打造浪漫网上花店体验
Element UI树形选择:TreeSelect层级选择方案
微信小程序后端开发

网址: Uniapp微信开发树形选择组件 https://m.huajiangbk.com/newsview2489522.html

所属分类:花卉
上一篇: select tree 简单实用
下一篇: 挑选银柳有讲究!别让你的无心之选