提交 28a54828 编写于 作者: KK's avatar KK

树选择

上级 2e165831
...@@ -156,5 +156,7 @@ export const AppComponents = { ...@@ -156,5 +156,7 @@ export const AppComponents = {
v.component('app-mob-department-personnel',() => import('@/components/app-mob-department-personnel/app-mob-department-personnel.vue')); v.component('app-mob-department-personnel',() => import('@/components/app-mob-department-personnel/app-mob-department-personnel.vue'));
v.component('app-mob-group-picker',() => import('@/components/app-mob-group-picker/app-mob-group-picker.vue')); v.component('app-mob-group-picker',() => import('@/components/app-mob-group-picker/app-mob-group-picker.vue'));
v.component('app-mob-group-select',() => import('@/components/app-mob-group-select/app-mob-group-select.vue')); v.component('app-mob-group-select',() => import('@/components/app-mob-group-select/app-mob-group-select.vue'));
// 树选择
v.component('app-tree',() => import('@/components/app-tree/app-tree.vue'));
}, },
}; };
\ No newline at end of file
.app-tree {
width: 100%;
height: 100%;
.app-mob-treeview {
.treeNav {
padding-left: 14px;
color: #a5a2a2;
font-size: 14px;
margin: 10px 0;
.treeNav-active {
color: #705697;
}
.tree-span {
padding: 0 3px;
color: #ccc;
}
}
.tree-partition {
height: 8px;
background-color: #ededed;
}
.tree-icon {
color: #3880ff;
font-size: 20px;
}
.tree-partition-bigger {
height: 16px;
}
ion-list {
ion-item {
font-size: 15px;
font-family: '微软雅黑';
.node_length{
color: #a5a2a2;
}
}
ion-item:last-child {
--inner-border-width: 0;
}
}
.tree_item_label {
display: flex;
align-items: center;
.tree_item_img {
width: 30px;
height: 30px;
margin-right: 10px;
border-radius: 4px;
}
.tree_item_index_text {
width: 30px;
height: 30px;
margin-right: 10px;
line-height: 30px;
background: #ccc;
text-align: center;
border-radius: 4px;
color: #fff;
}
}
}
}
\ No newline at end of file
<template>
<div class="app-tree">
<div class="app-mob-treeview sysemployee-tree">
<div class="treeNav">
<template v-for="(item, index) in treeNav">
<span :key="item.id" class="sc-ion-label-ios-h sc-ion-label-ios-s ios hydrated" :class="index + 1 < treeNav.length ? 'treeNav-active' : ''" @click="nav_click(item)">{{ item.label }}</span>
<span class="tree-span" :key="item.id + 'span'" v-if="index + 1 < treeNav.length">></span>
</template>
</div>
<div class="tree-partition" v-if="valueNodes.length > 0"></div>
<ion-list>
<template v-for="(item, index) in readerData">
<ion-item :key="index" @click="click_node(item)">
<ion-label>{{ item.label }}<span class="node_length" v-if="item.children && item.children.length > 0"> ({{item.children.length}})</span></ion-label>
<ion-icon class="tree-icon" slot="end" :name="geticon(item.status)" @click.stop="icon_click(item)"></ion-icon>
</ion-item>
</template>
</ion-list>
<div @click="on_ok_click">确认</div>
</div>
</div>
</template>
<script lang="ts">
import { Vue, Component, Prop, Watch, } from "vue-property-decorator";
@Component({
components: {},
})
export default class AppTree extends Vue {
/**
* 选择项
*
* @type {string}
* @memberof AppTree
*/
public selectTreeValue?: string;
@Prop() public _viewparams?: string;
@Watch('_viewparams', { immediate: true })
on__viewparams_change(newVale: any, oldVal: any) {
const data = JSON.parse(newVale);
const _this: any = this;
for (let index = 0; index < Object.keys(data).length; index++) {
const item = Object.keys(data)[index];
_this[item] = data[item];
}
}
@Watch('selectTreeValue', { immediate: true })
on_selectTreeValue_change(newVale: any, oldVal: any) {
this.cacheValue = newVale ? JSON.parse(newVale) : [];
this.curValue = newVale ? JSON.parse(newVale) : [];
}
/**
* 缓存值
*
* @type {any[]}
* @memberof AppTree
*/
public cacheValue: any = [];
/**
* 当前选中值
*
* @type {any[]}
* @memberof AppTree
*/
public curValue: any[] = [];
/**
* 是否多选
*/
public multiple?: boolean;
/**
* 父节点数据
*/
public rootNodes: any = [];
/**
* 子节点数据
*/
public valueNodes: any = [];
/**
* 树导航栏数据
*/
public treeNav: any[] = [{ id: 'main', label: 'main' }];
/**
* 获取图标
*/
public geticon(value: any) {
switch (value) {
case 0:
return 'ellipse-outline'
case 1:
return 'checkmark-circle-outline'
case 2:
return 'remove-circle-outline'
default: 'ellipse-outline'
break;
}
}
/**
* 树数据
*/
public nodesData?: any[];
/**
* nodesData值变化
*/
@Watch("nodesData", { immediate: true, deep: true })
on_nodesData_change(newVale: any, oldVal: any) {
if(!newVale){
return
}
this.parseNodes(newVale, true);
}
/**
* 渲染数据
*/
public readerData: any = [];
/**
* 解析节点数据
*
* @param {*} nodes
* @memberof EmpTreeBase
*/
public parseNodes(nodes: any, isReader: boolean = false) {
if (isReader) {
this.readerData = []
}
for (let index = 0; index < nodes.length; index++) {
const node: any = nodes[index];
if (isReader) {
this.readerData.push(Object.assign({ status: this.getSelectStatus(node) }, node));
}
}
}
/**
* 设置状态属性
* 0未选择
* 1选择
* 部分选择
* @param {*} nodes
* @memberof EmpTreeBase
*/
public getSelectStatus(node: any): number {
if (this.curValue.length <= 0) {
return 0
}
if (node.isLeaf) {
return this.curValue.some((item: any) => { return Object.is(item.id, node.id) }) ? 1 : 0;
} else {
let temp_arr = [];
for (let index = 0; index < node.children.length; index++) {
const node_item = node.children[index];
temp_arr.push(this.getSelectStatus(node_item));
}
if (temp_arr.every((item: any) => { return Object.is(item, 1) })) {
return 1;
}
if (temp_arr.every((item: any) => { return Object.is(item, 0) })) {
return 0;
}
if (temp_arr.some((item: any) => { return Object.is(item, 1) }) || temp_arr.some((item: any) => { return Object.is(item, 2) })) {
return 2;
}
}
return 0;
}
/**
* 导航点击
*/
public nav_click(item: any) {
if (item.id == this.treeNav[this.treeNav.length - 1].id) {
return
}
const count = this.treeNav.findIndex((i: any) => item.id === i.id) + 1;
this.treeNav.splice(count, this.treeNav.length - count);
if (Object.is(item.id, 'main')) {
this.parseNodes(this.nodesData, true)
} else {
this.click_node(item);
this.parseNodes(item, true)
}
}
/**
* 节点点击
*/
public click_node(item: any) {
if (item.isLeaf) {
this.icon_click(item);
return
}
this.treeNav.push(item);
this.parseNodes(item.children, true)
}
/**
* 图标点击
*/
public icon_click(item: any) {
if( this.multiple){
const _this = this;
const node_index = this.curValue.findIndex((_item: any) => { return Object.is(item.id, _item.id) });
let temp_allNode = this.getNodeChild(item);
if(node_index == -1) {
item.status = 1
}
for (let index = 0; index < temp_allNode.length; index++) {
const temp_node = temp_allNode[index];
if(node_index > -1){
const _index = _this.curValue.findIndex((_item: any) => { return Object.is(temp_node.id, _item.id) })
_this.curValue.splice(_index, 1);
}else{
if (this.curValue.findIndex((_item: any) => { return Object.is(_item.id, temp_node.id) }) == -1) {
this.curValue.push(temp_node);
}
}
}
}else{
this.curValue = [item];
}
let currNav = this.treeNav[this.treeNav.length - 1];
this.parseNodes(Object.is(currNav.id, 'main') ? this.nodesData : currNav.children, true);
this.$forceUpdate();
}
/**
* 获取当前节点所有子节点 包括当前节点
*/
public getNodeChild(node: any): any[] {
let allchildren: any[] = [];
allchildren.push(node);
for (let index = 0; index < node.children.length; index++) {
const element = node.children[index];
if (element.children && element.children.length > 0) {
allchildren.push(this.getNodeChild(element));
} else {
allchildren.push(element)
}
}
return allchildren;
}
/**
* on_ok_click
*/
public on_ok_click() {
this.$emit('close',JSON.parse(JSON.stringify(this.curValue)));
}
}
</script>
<style lang = "less">
@import "./app-tree.less";
</style>
\ No newline at end of file
Markdown 格式
0% or
您添加了 0 到此讨论。请谨慎行事。
先完成此消息的编辑!
想要评论请 注册