赞
踩
最近在做移动端的项目,由于没有找见移动端树形组件,所以封装了一个。包含加载所有数据的功能以及懒加载功能。
以下是目录结构
以下是完成后的ui 点击左侧切换“展开”、“收起” 点击右侧其他操作
然后直接上代码
以下是懒加载的例子,一次性全部加载的就不放了
组件说明:
* 组件说明:树形组件 itemActive:是否需要高亮显示 Boolean data:树形组件的数据 Array类型 props:组件属性 Object {id:'',children:'',name:''} lazy:是否开启懒加载 Boolean @load:懒加载回调方法 Funciton 返回当前点击项的所有数据 @click:点击事件方法 Funciton 返回当前点击项的所有数据 clickableConditions: 可以点击的条件 Object { //所有的列表是否可以点击 all: { enable: true }, //部分的列表可以点击 //以下条件说明【 orgType = 1或orgType = 2时可以点击】 part: { prop: "orgType", value: [1,2] } },
WarningMessage.vue
-
- /*
- * @Autor: Mr Lu
- * @Version: 1.0
- * @Date: 2019-12-03
- * @LastEditors: OBKoro1
- * @LastEditTime: 2019-12-03
- * @Description: 预警信息
- * 组件说明:树形组件
- itemActive:是否需要高亮显示 Boolean
- data:树形组件的数据 Array类型
- props:组件属性 Object {id:'',children:'',name:''}
- lazy:是否开启懒加载 Boolean
- @load:懒加载回调方法 Funciton 返回当前点击项的所有数据
- @click:点击事件方法 Funciton 返回当前点击项的所有数据
- clickableConditions: 可以点击的条件 Object
- {
- //所有的列表是否可以点击
- all: {
- enable: true
- },
-
- //部分的列表可以点击
- //以下条件说明【 orgType = 1或orgType = 2时可以点击】
- part: {
- prop: "orgType",
- value: [1,2]
- }
- },
- */
- <template>
- <div id="WarningMessage" class="p-box">
- <div class="p-return">
- <mu-appbar color="primary" class="lan-header">
- <mu-button icon slot="left" v-close>
- <i class="iconfont angle-left iconangle-left"></i>
- </mu-button>预警信息
- </mu-appbar>
- </div>
- <div class="p-content">
- <wallModule name="预警总计(个)" :total="totalCount" :bgImage="wallBgImage" />
- <div class="t-box">
- <div class="t-title">质量检查</div>
- <div class="t-content">
- <div class="t-header">
- <span class="name">超期未整改</span>
- <span class="total">{{totalCount}}</span>
- </div>
- <div class="t-body">
- <mTree
- v-show="tree.data.length"
- :data="tree.data"
- :props="tree.defaultProps"
- :lazy="true"
- @load="loadData"
- :clickableConditions="tree.clickableConditions"
- @click="skipPage"
- :showTotal="true"
- ></mTree>
- <NoData v-if="!tree.data.length&&!tree.loading" />
- </div>
- </div>
- </div>
- </div>
- </div>
- </template>
-
- <script>
- import WeatherModule from "@/weather/WeatherModule";
- import wallModule from "@/wall/wallModule";
- import mTree from "@/tree/mTree";
- export default {
- name: "WarningMessage",
- components: {
- WeatherModule,
- mTree,
- wallModule
- },
- data() {
- return {
- totalCount: 0,
- overflowDateCount: 0,
- wallBgImage: require("#/assets/img/wall/wall.png"),
- tree: {
- loading: false,
- defaultProps: {
- id: "orgId",
- name: "orgName",
- children: "children"
- },
- clickableConditions: {
- all: {
- //所有的是否可以点击
- enable: false
- },
- part: {
- //部分的可以点击的条件
- prop: "orgType",
- value: [1]
- }
- },
- data: []
- }
- };
- },
- computed: {},
- created() {
- this.initPage();
- },
- mounted() {},
- watch: {},
- methods: {
- skipPage(treeRowData) {},
- initPage() {
- this.getTotal();
- let params = {
- orgId: this.$A.GS("orgInfo")["orgId"],
- type: this.$A.GS("orgInfo")["type"],
- alarmStatus: 2
- };
-
- this.getData(params).then(response => {
- if (response.code == 200) {
- this.tree.data =
- response.body && response.body.length ? response.body : [];
- } else {
- this.tree.data = [];
- }
- });
- },
- getTotal() {
- let params = {
- orgId: this.$A.GS("orgInfo")["orgId"],
- type: this.$A.GS("orgInfo")["type"]
- };
- this.$A.Go("get", "/safety/qualityTotalAlarm/statistic", params).then(
- response => {
- if (response.code == 200) {
- this.totalCount = response.body.totalAlarmCount;
- }
- },
- err => {
- console.log(err);
- }
- );
- },
- loadData(treeRowData) {
- let params = {
- orgId: treeRowData.orgId,
- type: treeRowData.orgType,
- alarmStatus: 2
- };
- this.getData(params).then(response => {
- if (response.code == 200) {
- if (response.body && response.body.length) {
- var newArray = response.body;
- newArray.forEach(element => {
- element.level = treeRowData.level + 1;
- });
- this.$set(treeRowData, "children", newArray);
- this.$set(treeRowData, "expanded", true);
- } else {
- this.$set(treeRowData, "isLeaf", true);
- }
- } else {
- }
- });
- },
- getData(params) {
- this.$openLoading();
- this.tree.loading = true;
- let p = new Promise((resolve, reject) => {
- this.$A.Go("post", "/safety/importantRectLayer/statistic", params).then(
- response => {
- this.$closeLoading();
- this.tree.loading = false;
- resolve(response);
- },
- err => {
- this.$closeLoading();
- this.tree.loading = false;
- console.log(err);
- }
- );
- });
- return p;
- }
- },
- destroyed() {}
- };
- </script>
-
- <style lang="scss">
- #WarningMessage {
- //树形组件样式
- .treeList {
- border-top: 0.01rem solid $borderColor;
-
-
-
- [role="tree-content"] {
- background-color: #fff;
- -webkit-box-sizing: border-box;
- box-sizing: border-box;
- color: inherit;
- height: 0.55rem;
- display: block;
- overflow: hidden;
- position: relative;
- text-decoration: none;
- display: flex;
- align-items: center;
- border-bottom: 0.01rem solid #e0e0e0;
-
-
- [role="title"].active {
- >.tree-content-icon {
- background: $themeColoro;
- }
- }
-
- [role="title"].active {
- >.tree-content-label {
- background: $themeColoro;
- }
- }
-
- [role="title"] {
- height: 100%;
- width: 100%;
- display: flex;
- align-items: center;
-
- .tree-content-icon {
- display: flex;
- align-items: center;
- justify-content: center;
- color: $themeColor;
- height: 100%;
- padding: 0 0.14rem;
- border-right: 0.01rem solid rgba(224, 224, 224, 1);
-
- .iconfont {
- margin-left: 0.03rem;
- font-size: 0.08rem;
- }
- }
-
- .tree-content-icon.disabled {
- color: $themeColoro;
- cursor: not-allowed;
- }
-
- .tree-content-label {
- flex: 1;
- height: 100%;
- display: flex;
- min-width: 0;
- align-items: center;
- justify-content: space-between;
- padding: 0 0.14rem;
-
- .name {
- flex: 1;
- white-space: nowrap;
- text-overflow: hidden;
- text-overflow: ellipsis;
- overflow: hidden;
- }
-
- .icon {
- display: flex;
- height: 100%;
- align-items: center;
- margin-left: 0.05rem;
-
- .iconfont {
- margin-left: 0.15rem;
- color: #dbdbdb;
- }
- }
- }
- }
- }
-
- [role="tree-children"] {
- background: #fff;
- }
-
- [role="tree-children"]::before {
- content: "";
- }
-
- .iconfont.iconhidden {
- visibility: hidden;
- }
-
- .iconfont.iconnone {
- display: none;
- }
- }
-
- }
- </style>

mTree.vue
- <template>
- <div role="tree" class="treeList">
- <treeItem :node="node" v-bind="$attrs" v-on="$listeners" ref="tree" />
- </div>
- </template>
- <script>
- import treeItem from "./tree-item";
- export default {
- name: "mTree",
- components: {
- treeItem
- },
- props: {
- data: {
- type: Array,
- default: []
- }
- },
- data() {
- return {
- node: []
- };
- },
- computed: {},
- created() {},
- mounted() {},
- watch: {
- data: {
- handler(val, oldVal) {
- this.node = this.dealTreeData(val, 1);
- },
- deep: true
- }
- },
- methods: {
- dealTreeData(tree, level) {
- let arr = [];
- tree.length &&
- tree.forEach((item, index) => {
- let obj = {};
- obj = this.deepCopy(item);
- obj.level = level;
- // obj.expanded = true;
- if (item.children && item.children.length) {
- obj.children = this.dealTreeData(item.children, level + 1);
- } else {
- if (!this.$attrs.lazy) {
- obj.isLeaf = true;
- } else {
- obj.isLeaf = false;
- }
- }
- arr.push(obj);
- });
- return arr;
- },
- deepCopy(obj) {
- var result = Array.isArray(obj) ? [] : {};
- for (var key in obj) {
- if (obj.hasOwnProperty(key)) {
- if (typeof obj[key] === "object" && obj[key] !== null) {
- result[key] = this.deepCopy(obj[key]); //递归复制
- } else {
- result[key] = obj[key];
- }
- }
- }
- return result;
- },
- postData(data) {
- // this.$emit("load", data);
- }
- },
- destroyed() {}
- };
- </script>
-
- <style lang="scss">
- </style>

treeItem.vue
- <template>
- <div class>
- <div role="tree-item" class="treeItem" v-for="(item) in node" :key="item[$attrs.props.id]">
- <div role="tree-content">
- <div
- role="title"
- :class="item[$attrs.props.id]==currentId?'active':''"
- :style="{'background':`rgba(${255-colorLevel*(item.level-1)},${255-colorLevel*(item.level-1)},${255-colorLevel*(item.level-1)})`}"
- >
- <!-- 展开或收起 -->
- <!-- :style="{'visibility':item.isLeaf&&!item[$attrs.props.children]?'hidden':'visible'}" -->
- <span
- class="tree-content-icon"
- @click.stop="item.isLeaf&&!item[$attrs.props.children]?'':treeToggleClick(item)"
- :class="item.isLeaf&&!item[$attrs.props.children]?'disabled':''"
- >
- {{item.isLeaf&&!item[$attrs.props.children]?"展开":item['expanded']?'收起':"展开"}}
- <!-- <span
- class="iconfont"
- :class="item['expanded']?'iconangle-down':'iconangle-right'"
- ></span>-->
- </span>
- <!-- 标题 -->
- <!-- !enabledConfigClick?'':clickType == 'all'?treeConfigClick(item):(item[$attrs.clickableConditions.part.prop]==$attrs.clickableConditions.part.value?treeConfigClick(item):false) -->
- <label
- class="tree-content-label"
- @click.stop="!enabledConfigClick?'':clickType == 'all'?treeConfigClick(item):($attrs.clickableConditions.part.value.includes(item[$attrs.clickableConditions.part.prop])?treeConfigClick(item):false)"
- >
- <span class="name">{{ item[$attrs.props.name]}}</span>
- <span class="icon">
- <span v-if="$attrs.showTotal">{{item.projectCount}}</span>
- <i
- class="iconfont iconangle-right"
- v-if="!enabledConfigClick?false:clickType == 'all'?true:($attrs.clickableConditions.part.value.includes(item[$attrs.clickableConditions.part.prop])?true:false)"
- ></i>
- <i
- class="iconfont iconangle-right"
- v-else
- :class="$attrs.showTotal?'iconhidden':'iconnone'"
- ></i>
- </span>
- </label>
- </div>
- </div>
- <VerticalToggle>
- <!-- :style="{ 'padding-left': .14 + 'rem' }" -->
- <div role="tree-children" v-if="item['expanded']">
- <treeItem :node="item[$attrs.props.children]" v-bind="$attrs" v-on="$listeners" />
- </div>
- </VerticalToggle>
- </div>
- </div>
- </template>
- <script>
- import VerticalToggle from "./js/VerticalToggle";
- export default {
- name: "treeItem",
- components: {
- VerticalToggle
- },
- props: {
- node: {}
- },
- data() {
- return {
- tree: null,
- data: [],
- currentId: "",
- enabledConfigClick: false,
- clickType: "all",
- colorLevel: 5
- };
- },
- computed: {},
- created() {
- if (this.$attrs.clickableConditions) {
- if (
- this.$attrs.clickableConditions.all &&
- this.$attrs.clickableConditions.all.enable
- ) {
- this.enabledConfigClick = true;
- this.clickType = "all";
- } else if (this.$attrs.clickableConditions.part) {
- this.enabledConfigClick = true;
- this.clickType = "part";
- } else {
- this.enabledConfigClick = false;
- }
- } else {
- this.enabledConfigClick = false;
- }
- },
- mounted() {},
- watch: {},
- methods: {
- /**点击展开收起的事件 */
- treeToggleClick(item) {
- // this.currentId = item[this.$attrs.props.id];
- if (this.$attrs.lazy) {
- if (item.isLeaf || item[this.$attrs.props.children]) {
- this.$set(item, "expanded", !item.expanded);
- } else {
- if (item.orgType && item.orgType == 1) {
- this.$set(item, "expanded", !item.expanded);
- this.$set(item, "isLeaf", true);
- } else {
- this.$parent.$emit("load", item);
- }
- //this.$parent.$emit("load", item);
- }
- } else {
- this.$set(item, "expanded", !item.expanded);
- }
- },
- /**点击右侧文字的事件 */
- treeConfigClick(item) {
- this.$attrs.itemActive
- ? (this.currentId = item[this.$attrs.props.id])
- : "";
- this.$parent.$emit("click", item);
- },
- postData(item) {
- debugger;
- }
- },
- destroyed() {}
- };
- </script>
-
- <style lang="scss">
- /*树形组件*/
- </style>

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。