|
@@ -0,0 +1,588 @@
|
|
|
|
+<template>
|
|
|
|
+ <view>
|
|
|
|
+ <template v-if="showLoading">
|
|
|
|
+ <view class="ly-loader ly-flex-center">
|
|
|
|
+ <view class="ly-loader-inner">加载中...</view>
|
|
|
|
+ </view>
|
|
|
|
+ </template>
|
|
|
|
+ <template v-else>
|
|
|
|
+ <view v-if="isEmpty || !visible" class="ly-empty">{{emptyText}}</view>
|
|
|
|
+ <view class="ly-tree" :class="{'is-empty': isEmpty || !visible}" role="tree" name="LyTreeExpand">
|
|
|
|
+ <ly-tree-node v-for="nodeId in childNodesId"
|
|
|
|
+ :nodeId="nodeId"
|
|
|
|
+ :render-after-expand="renderAfterExpand"
|
|
|
|
+ :show-checkbox="showCheckbox"
|
|
|
|
+ :show-radio="showRadio"
|
|
|
|
+ :check-only-leaf="checkOnlyLeaf"
|
|
|
|
+ :key="getNodeKey(nodeId)"
|
|
|
|
+ :indent="indent"
|
|
|
|
+ :icon-class="iconClass">
|
|
|
|
+ </ly-tree-node>
|
|
|
|
+ </view>
|
|
|
|
+ </template>
|
|
|
|
+ </view>
|
|
|
|
+</template>
|
|
|
|
+
|
|
|
|
+<script>
|
|
|
|
+ import Vue from 'vue'
|
|
|
|
+ import TreeStore from './model/tree-store.js';
|
|
|
|
+ import {getNodeKey} from './tool/util.js';
|
|
|
|
+ import LyTreeNode from './ly-tree-node.vue';
|
|
|
|
+
|
|
|
|
+ export default {
|
|
|
|
+ name: 'LyTree',
|
|
|
|
+
|
|
|
|
+ componentName: 'LyTree',
|
|
|
|
+
|
|
|
|
+ components: {
|
|
|
|
+ LyTreeNode
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ data() {
|
|
|
|
+ return {
|
|
|
|
+ elId: `ly_${Math.ceil(Math.random() * 10e5).toString(36)}`,
|
|
|
|
+ visible: true,
|
|
|
|
+ store: {
|
|
|
|
+ ready: false
|
|
|
|
+ },
|
|
|
|
+ currentNode: null,
|
|
|
|
+ childNodesId: []
|
|
|
|
+ };
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ provide() {
|
|
|
|
+ return {
|
|
|
|
+ tree: this
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ props: {
|
|
|
|
+ // 展示数据
|
|
|
|
+ treeData: Array,
|
|
|
|
+
|
|
|
|
+ // 自主控制loading加载,避免数据还没获取到的空档出现“暂无数据”字样
|
|
|
|
+ ready: {
|
|
|
|
+ type: Boolean,
|
|
|
|
+ default: true
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ // 内容为空的时候展示的文本
|
|
|
|
+ emptyText: {
|
|
|
|
+ type: String,
|
|
|
|
+ default: '暂无数据'
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ // 是否在第一次展开某个树节点后才渲染其子节点
|
|
|
|
+ renderAfterExpand: {
|
|
|
|
+ type: Boolean,
|
|
|
|
+ default: true
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ // 每个树节点用来作为唯一标识的属性,整棵树应该是唯一的
|
|
|
|
+ nodeKey: String,
|
|
|
|
+
|
|
|
|
+ // 在显示复选框的情况下,是否严格的遵循父子不互相关联的做法,默认为 false
|
|
|
|
+ checkStrictly: Boolean,
|
|
|
|
+
|
|
|
|
+ // 是否默认展开所有节点
|
|
|
|
+ defaultExpandAll: Boolean,
|
|
|
|
+
|
|
|
|
+ // 切换全部展开、全部折叠
|
|
|
|
+ toggleExpendAll: Boolean,
|
|
|
|
+
|
|
|
|
+ // 是否在点击节点的时候展开或者收缩节点, 默认值为 true,如果为 false,则只有点箭头图标的时候才会展开或者收缩节点
|
|
|
|
+ expandOnClickNode: {
|
|
|
|
+ type: Boolean,
|
|
|
|
+ default: true
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ // 选中的时候展开节点
|
|
|
|
+ expandOnCheckNode: {
|
|
|
|
+ type: Boolean,
|
|
|
|
+ default: true
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ // 是否在点击节点的时候选中节点,默认值为 false,即只有在点击复选框时才会选中节点
|
|
|
|
+ checkOnClickNode: Boolean,
|
|
|
|
+ checkDescendants: {
|
|
|
|
+ type: Boolean,
|
|
|
|
+ default: false
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ // 展开子节点的时候是否自动展开父节点
|
|
|
|
+ autoExpandParent: {
|
|
|
|
+ type: Boolean,
|
|
|
|
+ default: true
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ // 默认勾选的节点的 key 的数组
|
|
|
|
+ defaultCheckedKeys: Array,
|
|
|
|
+
|
|
|
|
+ // 默认展开的节点的 key 的数组
|
|
|
|
+ defaultExpandedKeys: Array,
|
|
|
|
+
|
|
|
|
+ // 是否展开当前节点的父节点
|
|
|
|
+ expandCurrentNodeParent: Boolean,
|
|
|
|
+
|
|
|
|
+ // 当前选中的节点
|
|
|
|
+ currentNodeKey: [String, Number],
|
|
|
|
+
|
|
|
|
+ // 是否最后一层叶子节点才显示单选/多选框
|
|
|
|
+ checkOnlyLeaf: {
|
|
|
|
+ type: Boolean,
|
|
|
|
+ default: false
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ // 节点是否可被选择
|
|
|
|
+ showCheckbox: {
|
|
|
|
+ type: Boolean,
|
|
|
|
+ default: false
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ // 节点单选
|
|
|
|
+ showRadio: {
|
|
|
|
+ type: Boolean,
|
|
|
|
+ default: false
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ // 配置选项
|
|
|
|
+ props: {
|
|
|
|
+ type: [Object, Function],
|
|
|
|
+ default () {
|
|
|
|
+ return {
|
|
|
|
+ children: 'children', // 指定子树为节点对象的某个属性值
|
|
|
|
+ label: 'label', // 指定节点标签为节点对象的某个属性值
|
|
|
|
+ disabled: 'disabled' // 指定节点选择框是否禁用为节点对象的某个属性值
|
|
|
|
+ };
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ // 是否懒加载子节点,需与 load 方法结合使用
|
|
|
|
+ lazy: {
|
|
|
|
+ type: Boolean,
|
|
|
|
+ default: false
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ // 是否高亮当前选中节点,默认值是 false
|
|
|
|
+ highlightCurrent: Boolean,
|
|
|
|
+
|
|
|
|
+ // 加载子树数据的方法,仅当 lazy 属性为true 时生效
|
|
|
|
+ load: Function,
|
|
|
|
+
|
|
|
|
+ // 对树节点进行筛选时执行的方法,返回 true 表示这个节点可以显示,返回 false 则表示这个节点会被隐藏
|
|
|
|
+ filterNodeMethod: Function,
|
|
|
|
+
|
|
|
|
+ // 搜索时是否展示匹配项的所有子节点
|
|
|
|
+ childVisibleForFilterNode: {
|
|
|
|
+ type: Boolean,
|
|
|
|
+ default: false
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ // 是否每次只打开一个同级树节点展开
|
|
|
|
+ accordion: Boolean,
|
|
|
|
+
|
|
|
|
+ // 相邻级节点间的水平缩进,单位为像素
|
|
|
|
+ indent: {
|
|
|
|
+ type: Number,
|
|
|
|
+ default: 18
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ // 自定义树节点的展开图标
|
|
|
|
+ iconClass: String,
|
|
|
|
+
|
|
|
|
+ // 是否显示节点图标,如果配置为true,需要配置props中对应的图标属性名称
|
|
|
|
+ showNodeIcon: {
|
|
|
|
+ type: Boolean,
|
|
|
|
+ default: false
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ // 如果数据量较大,建议不要在node节点中添加parent属性,会造成性能损耗
|
|
|
|
+ isInjectParentInNode: {
|
|
|
|
+ type: Boolean,
|
|
|
|
+ default: false
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ computed: {
|
|
|
|
+ isEmpty() {
|
|
|
|
+ if (this.store.root) {
|
|
|
|
+ const childNodes = this.store.root.getChildNodes(this.childNodesId);
|
|
|
|
+
|
|
|
|
+ return !childNodes || childNodes.length === 0 || childNodes.every(({visible}) => !visible);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return true;
|
|
|
|
+ },
|
|
|
|
+ showLoading() {
|
|
|
|
+ return !(this.store.ready && this.ready);
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ watch: {
|
|
|
|
+ toggleExpendAll(newVal) {
|
|
|
|
+ this.store.toggleExpendAll(newVal);
|
|
|
|
+ },
|
|
|
|
+ defaultCheckedKeys(newVal) {
|
|
|
|
+ this.store.setDefaultCheckedKey(newVal);
|
|
|
|
+ },
|
|
|
|
+ defaultExpandedKeys(newVal) {
|
|
|
|
+ this.store.defaultExpandedKeys = newVal;
|
|
|
|
+ this.store.setDefaultExpandedKeys(newVal);
|
|
|
|
+ },
|
|
|
|
+ treeData(newVal) {
|
|
|
|
+ this.store.setData(newVal);
|
|
|
|
+ },
|
|
|
|
+ checkStrictly(newVal) {
|
|
|
|
+ this.store.checkStrictly = newVal || this.checkOnlyLeaf;
|
|
|
|
+ },
|
|
|
|
+ 'store.root.childNodesId'(newVal) {
|
|
|
|
+ this.childNodesId = newVal;
|
|
|
|
+ },
|
|
|
|
+ 'store.root.visible'(newVal) {
|
|
|
|
+ this.visible = newVal;
|
|
|
|
+ },
|
|
|
|
+ childNodesId(){
|
|
|
|
+ this.$nextTick(() => {
|
|
|
|
+ this.$emit('ly-tree-render-completed');
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ methods: {
|
|
|
|
+ /*
|
|
|
|
+ * @description 对树节点进行筛选操作
|
|
|
|
+ * @method filter
|
|
|
|
+ * @param {all} value 在 filter-node-method 中作为第一个参数
|
|
|
|
+ * @param {Object} data 搜索指定节点的节点数据,不传代表搜索所有节点,假如要搜索A节点下面的数据,那么nodeData代表treeData中A节点的数据
|
|
|
|
+ */
|
|
|
|
+ filter(value, data) {
|
|
|
|
+ if (!this.filterNodeMethod) throw new Error('[Tree] filterNodeMethod is required when filter');
|
|
|
|
+ this.store.filter(value, data);
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * @description 获取节点的唯一标识符
|
|
|
|
+ * @method getNodeKey
|
|
|
|
+ * @param {String, Number} nodeId
|
|
|
|
+ * @return {String, Number} 匹配到的数据中的某一项数据
|
|
|
|
+ */
|
|
|
|
+ getNodeKey(nodeId) {
|
|
|
|
+ let node = this.store.root.getChildNodes([nodeId])[0];
|
|
|
|
+ return getNodeKey(this.nodeKey, node.data);
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * @description 获取节点路径
|
|
|
|
+ * @method getNodePath
|
|
|
|
+ * @param {Object} data 节点数据
|
|
|
|
+ * @return {Array} 路径数组
|
|
|
|
+ */
|
|
|
|
+ getNodePath(data) {
|
|
|
|
+ return this.store.getNodePath(data);
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * @description 若节点可被选择(即 show-checkbox 为 true),则返回目前被选中的节点所组成的数组
|
|
|
|
+ * @method getCheckedNodes
|
|
|
|
+ * @param {Boolean} leafOnly 是否只是叶子节点,默认false
|
|
|
|
+ * @param {Boolean} includeHalfChecked 是否包含半选节点,默认false
|
|
|
|
+ * @return {Array} 目前被选中的节点所组成的数组
|
|
|
|
+ */
|
|
|
|
+ getCheckedNodes(leafOnly, includeHalfChecked) {
|
|
|
|
+ return this.store.getCheckedNodes(leafOnly, includeHalfChecked);
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * @description 若节点可被选择(即 show-checkbox 为 true),则返回目前被选中的节点的 key 所组成的数组
|
|
|
|
+ * @method getCheckedKeys
|
|
|
|
+ * @param {Boolean} leafOnly 是否只是叶子节点,默认false,若为 true 则仅返回被选中的叶子节点的 keys
|
|
|
|
+ * @param {Boolean} includeHalfChecked 是否返回indeterminate为true的节点,默认false
|
|
|
|
+ * @return {Array} 目前被选中的节点所组成的数组
|
|
|
|
+ */
|
|
|
|
+ getCheckedKeys(leafOnly, includeHalfChecked) {
|
|
|
|
+ return this.store.getCheckedKeys(leafOnly, includeHalfChecked);
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * @description 获取当前被选中节点的 data,若没有节点被选中则返回 null
|
|
|
|
+ * @method getCurrentNode
|
|
|
|
+ * @return {Object} 当前被选中节点的 data,若没有节点被选中则返回 null
|
|
|
|
+ */
|
|
|
|
+ getCurrentNode() {
|
|
|
|
+ const currentNode = this.store.getCurrentNode();
|
|
|
|
+ return currentNode ? currentNode.data : null;
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * @description 获取当前被选中节点的 key,若没有节点被选中则返回 null
|
|
|
|
+ * @method getCurrentKey
|
|
|
|
+ * @return {all} 当前被选中节点的 key, 若没有节点被选中则返回 null
|
|
|
|
+ */
|
|
|
|
+ getCurrentKey() {
|
|
|
|
+ const currentNode = this.getCurrentNode();
|
|
|
|
+ return currentNode ? currentNode[this.nodeKey] : null;
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * @description 设置全选/取消全选
|
|
|
|
+ * @method setCheckAll
|
|
|
|
+ * @param {Boolean} isCheckAll 选中状态,默认为true
|
|
|
|
+ */
|
|
|
|
+ setCheckAll(isCheckAll = true) {
|
|
|
|
+ if (this.showRadio) throw new Error('You set the "show-radio" property, so you cannot select all nodes');
|
|
|
|
+
|
|
|
|
+ if (!this.showCheckbox) console.warn('You have not set the property "show-checkbox". Please check your settings');
|
|
|
|
+
|
|
|
|
+ this.store.setCheckAll(isCheckAll);
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * @description 设置目前勾选的节点
|
|
|
|
+ * @method setCheckedNodes
|
|
|
|
+ * @param {Array} nodes 接收勾选节点数据的数组
|
|
|
|
+ * @param {Boolean} leafOnly 是否只是叶子节点, 若为 true 则仅设置叶子节点的选中状态,默认值为 false
|
|
|
|
+ */
|
|
|
|
+ setCheckedNodes(nodes, leafOnly) {
|
|
|
|
+ this.store.setCheckedNodes(nodes, leafOnly);
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * @description 通过 keys 设置目前勾选的节点
|
|
|
|
+ * @method setCheckedKeys
|
|
|
|
+ * @param {Array} keys 勾选节点的 key 的数组
|
|
|
|
+ * @param {Boolean} leafOnly 是否只是叶子节点, 若为 true 则仅设置叶子节点的选中状态,默认值为 false
|
|
|
|
+ */
|
|
|
|
+ setCheckedKeys(keys, leafOnly) {
|
|
|
|
+ if (!this.nodeKey) throw new Error('[Tree] nodeKey is required in setCheckedKeys');
|
|
|
|
+ this.store.setCheckedKeys(keys, leafOnly);
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * @description 通过 key / data 设置某个节点的勾选状态
|
|
|
|
+ * @method setChecked
|
|
|
|
+ * @param {all} data 勾选节点的 key 或者 data
|
|
|
|
+ * @param {Boolean} checked 节点是否选中
|
|
|
|
+ * @param {Boolean} deep 是否设置子节点 ,默认为 false
|
|
|
|
+ */
|
|
|
|
+ setChecked(data, checked, deep) {
|
|
|
|
+ this.store.setChecked(data, checked, deep);
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * @description 若节点可被选择(即 show-checkbox 为 true),则返回目前半选中的节点所组成的数组
|
|
|
|
+ * @method getHalfCheckedNodes
|
|
|
|
+ * @return {Array} 目前半选中的节点所组成的数组
|
|
|
|
+ */
|
|
|
|
+ getHalfCheckedNodes() {
|
|
|
|
+ return this.store.getHalfCheckedNodes();
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * @description 若节点可被选择(即 show-checkbox 为 true),则返回目前半选中的节点的 key 所组成的数组
|
|
|
|
+ * @method getHalfCheckedKeys
|
|
|
|
+ * @return {Array} 目前半选中的节点的 key 所组成的数组
|
|
|
|
+ */
|
|
|
|
+ getHalfCheckedKeys() {
|
|
|
|
+ return this.store.getHalfCheckedKeys();
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * @description 通过 node 设置某个节点的当前选中状态
|
|
|
|
+ * @method setCurrentNode
|
|
|
|
+ * @param {Object} node 待被选节点的 node
|
|
|
|
+ */
|
|
|
|
+ setCurrentNode(node) {
|
|
|
|
+ if (!this.nodeKey) throw new Error('[Tree] nodeKey is required in setCurrentNode');
|
|
|
|
+ this.store.setUserCurrentNode(node);
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * @description 通过 key 设置某个节点的当前选中状态
|
|
|
|
+ * @method setCurrentKey
|
|
|
|
+ * @param {all} key 待被选节点的 key,若为 null 则取消当前高亮的节点
|
|
|
|
+ */
|
|
|
|
+ setCurrentKey(key) {
|
|
|
|
+ if (!this.nodeKey) throw new Error('[Tree] nodeKey is required in setCurrentKey');
|
|
|
|
+ this.store.setCurrentNodeKey(key);
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * @description 根据 data 或者 key 拿到 Tree 组件中的 node
|
|
|
|
+ * @method getNode
|
|
|
|
+ * @param {all} data 要获得 node 的 key 或者 data
|
|
|
|
+ */
|
|
|
|
+ getNode(data) {
|
|
|
|
+ return this.store.getNode(data);
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * @description 删除 Tree 中的一个节点
|
|
|
|
+ * @method remove
|
|
|
|
+ * @param {all} data 要删除的节点的 data 或者 node
|
|
|
|
+ */
|
|
|
|
+ remove(data) {
|
|
|
|
+ this.store.remove(data);
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * @description 为 Tree 中的一个节点追加一个子节点
|
|
|
|
+ * @method append
|
|
|
|
+ * @param {Object} data 要追加的子节点的 data
|
|
|
|
+ * @param {Object} parentNode 子节点的 parent 的 data、key 或者 node
|
|
|
|
+ */
|
|
|
|
+ append(data, parentNode) {
|
|
|
|
+ this.store.append(data, parentNode);
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * @description 为 Tree 的一个节点的前面增加一个节点
|
|
|
|
+ * @method insertBefore
|
|
|
|
+ * @param {Object} data 要增加的节点的 data
|
|
|
|
+ * @param {all} refNode 要增加的节点的后一个节点的 data、key 或者 node
|
|
|
|
+ */
|
|
|
|
+ insertBefore(data, refNode) {
|
|
|
|
+ this.store.insertBefore(data, refNode);
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * @description 为 Tree 的一个节点的后面增加一个节点
|
|
|
|
+ * @method insertAfter
|
|
|
|
+ * @param {Object} data 要增加的节点的 data
|
|
|
|
+ * @param {all} refNode 要增加的节点的前一个节点的 data、key 或者 node
|
|
|
|
+ */
|
|
|
|
+ insertAfter(data, refNode) {
|
|
|
|
+ this.store.insertAfter(data, refNode);
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * @description 通过 keys 设置节点子元素
|
|
|
|
+ * @method updateKeyChildren
|
|
|
|
+ * @param {String, Number} key 节点 key
|
|
|
|
+ * @param {Object} data 节点数据的数组
|
|
|
|
+ */
|
|
|
|
+ updateKeyChildren(key, data) {
|
|
|
|
+ if (!this.nodeKey) throw new Error('[Tree] nodeKey is required in updateKeyChild');
|
|
|
|
+ this.store.updateChildren(key, data);
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ created() {
|
|
|
|
+ this.isTree = true;
|
|
|
|
+
|
|
|
|
+ let props = this.props;
|
|
|
|
+ if (typeof this.props === 'function') props = this.props();
|
|
|
|
+ if (typeof props !== 'object') throw new Error('props must be of object type.');
|
|
|
|
+
|
|
|
|
+ this.store = new TreeStore({
|
|
|
|
+ key: this.nodeKey,
|
|
|
|
+ data: this.treeData,
|
|
|
|
+ lazy: this.lazy,
|
|
|
|
+ props: props,
|
|
|
|
+ load: this.load,
|
|
|
|
+ showCheckbox: this.showCheckbox,
|
|
|
|
+ showRadio: this.showRadio,
|
|
|
|
+ currentNodeKey: this.currentNodeKey,
|
|
|
|
+ checkStrictly: this.checkStrictly || this.checkOnlyLeaf,
|
|
|
|
+ checkDescendants: this.checkDescendants,
|
|
|
|
+ expandOnCheckNode: this.expandOnCheckNode,
|
|
|
|
+ defaultCheckedKeys: this.defaultCheckedKeys,
|
|
|
|
+ defaultExpandedKeys: this.defaultExpandedKeys,
|
|
|
|
+ expandCurrentNodeParent: this.expandCurrentNodeParent,
|
|
|
|
+ autoExpandParent: this.autoExpandParent,
|
|
|
|
+ defaultExpandAll: this.defaultExpandAll,
|
|
|
|
+ filterNodeMethod: this.filterNodeMethod,
|
|
|
|
+ childVisibleForFilterNode: this.childVisibleForFilterNode,
|
|
|
|
+ showNodeIcon: this.showNodeIcon,
|
|
|
|
+ isInjectParentInNode: this.isInjectParentInNode
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ this.childNodesId = this.store.root.childNodesId;
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ beforeDestroy() {
|
|
|
|
+ if (this.accordion) {
|
|
|
|
+ uni.$off(`${this.elId}-tree-node-expand`)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ };
|
|
|
|
+</script>
|
|
|
|
+
|
|
|
|
+<style>
|
|
|
|
+ .ly-tree {
|
|
|
|
+ position: relative;
|
|
|
|
+ cursor: default;
|
|
|
|
+ background: #FFF;
|
|
|
|
+ color: #606266;
|
|
|
|
+ padding: 30rpx;
|
|
|
|
+ max-height: 600rpx;
|
|
|
|
+ overflow-y: scroll;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ .ly-tree.is-empty {
|
|
|
|
+ background: transparent;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* lyEmpty-start */
|
|
|
|
+ .ly-empty {
|
|
|
|
+ width: 100%;
|
|
|
|
+ display: flex;
|
|
|
|
+ justify-content: center;
|
|
|
|
+ margin-top: 100rpx;
|
|
|
|
+ }
|
|
|
|
+ /* lyEmpty-end */
|
|
|
|
+
|
|
|
|
+ /* lyLoader-start */
|
|
|
|
+ .ly-loader {
|
|
|
|
+ margin-top: 100rpx;
|
|
|
|
+ display: flex;
|
|
|
|
+ align-items: center;
|
|
|
|
+ justify-content: center;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ .ly-loader-inner,
|
|
|
|
+ .ly-loader-inner:before,
|
|
|
|
+ .ly-loader-inner:after {
|
|
|
|
+ background: #efefef;
|
|
|
|
+ animation: load 1s infinite ease-in-out;
|
|
|
|
+ width: .5em;
|
|
|
|
+ height: 1em;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ .ly-loader-inner:before,
|
|
|
|
+ .ly-loader-inner:after {
|
|
|
|
+ position: absolute;
|
|
|
|
+ top: 0;
|
|
|
|
+ content: '';
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ .ly-loader-inner:before {
|
|
|
|
+ left: -1em;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ .ly-loader-inner {
|
|
|
|
+ text-indent: -9999em;
|
|
|
|
+ position: relative;
|
|
|
|
+ font-size: 22rpx;
|
|
|
|
+ animation-delay: 0.16s;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ .ly-loader-inner:after {
|
|
|
|
+ left: 1em;
|
|
|
|
+ animation-delay: 0.32s;
|
|
|
|
+ }
|
|
|
|
+ /* lyLoader-end */
|
|
|
|
+
|
|
|
|
+ @keyframes load {
|
|
|
|
+ 0%,
|
|
|
|
+ 80%,
|
|
|
|
+ 100% {
|
|
|
|
+ box-shadow: 0 0 #efefef;
|
|
|
|
+ height: 1em;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ 40% {
|
|
|
|
+ box-shadow: 0 -1.5em #efefef;
|
|
|
|
+ height: 1.5em;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+</style>
|