• iView 用renderContent自定义树组件


    iview的树组件在有默认选中状态的时候默认选中状态的样式改变有bug,默认选中的样式不好看,鉴于此,有renderContent来改造iview的树组件,

    效果如图

    代码如下

    <template>
      <div class="transfer">
        <div class="transfer-left">
          <div class="transfer-header">
            <h2 class="title">源数据</h2>
          </div>
          <div class="transfer-body">
            <vue-scroll>
              <Tree
                ref="tree"
                :data="data2"
                multiple
                :render="renderContent">
              </Tree>
            </vue-scroll>
          </div>
        </div>
        <div class="transfer-middle"></div>
        <div class="transfer-right">
          <div class="transfer-header">
            <h2 class="title">目的数据</h2>
          </div>
          <div class="transfer-body">
            <ul class="transfer-lists">
              <li class="transfer-list" v-for="(item, index) in selectedList" :key="index">
                <span class="name">{{item.title}}</span>
                <Button class="btn-del" icon="md-close" type="text" @click="cancelSelected(item, index)"></Button>
              </li>
            </ul>
          </div>
        </div>
      </div>
    </template>
    <script>
    export default {
      name: 'transfer',
      data () {
        return {
          SelectClass: 'ivu-tree-title ivu-tree-title-selected',
          DefineClass: 'ivu-tree-title',
          selectedList: [],
          selectedData: [
            {
              'id': 111,
              'title': 'leaf 1-1-1'
            },
            {
              'id': 112,
              'title': 'leaf 1-1-2'
            }
          ],
          data2: [
            {
              id: 1,
              title: 'parent 1',
              expand: true,
              hasChild: true,
              children: [
                {
                  id: 11,
                  title: 'parent 1-1',
                  expand: true,
                  hasChild: true,
                  children: [
                    {
                      id: 111,
                      title: 'leaf 1-1-1'
                    },
                    {
                      id: 112,
                      title: 'leaf 1-1-2'
                    }
                  ]
                },
                {
                  id: 12,
                  title: 'parent 1-2',
                  expand: true,
                  hasChild: true,
                  children: [
                    {
                      id: 121,
                      title: 'leaf 1-2-1'
                    },
                    {
                      id: 122,
                      title: 'leaf 1-2-2'
                    }
                  ]
                }
              ]
            }
          ]
        }
      },
      created () {
        for (let i = 0, l = this.selectedData.length; i < l; i++) {
          this.traverseTree(this.data2[0], this.selectedData[i].id, false)
        }
        this.selectedList = this.selectedData
      },
      methods: {
        iconType (hasChild, expand) {
          let iconType = 'ios-document'
          if (hasChild) {
            if (expand) {
              iconType = 'ios-folder-open'
            } else {
              iconType = 'ios-folder'
            }
          } else {
            iconType = 'ios-document'
          }
          return iconType
        },
        cancelSelected (item, index) {
          this.selectedList.splice(index, 1)
          this.traverseTree(this.data2[0], item.id, true)
          this.$refs.tree.$el.querySelectorAll('.ivu-tree-title-selected')[index].className = 'ivu-tree-title'
        },
        traverseTree (node, id, isDel) {
          if (!node) {
            return
          }
          if (node.id === id) {
            if (isDel) {
              node.selected = false
            } else {
              node.selected = true
            }
          }
          let children = node.children
          if (children && children.length > 0) {
            for (let i = 0, l = children.length; i < l; i++) {
              this.traverseTree(children[i], id, isDel)
            }
          }
        },
        renderContent (h, { root, node, data }) {
          if (node.node.selected) {
            return h('div', {
              class: ['ivu-tree-title', 'ivu-tree-title-selected'],
              on: {
                click: (e) => {
                  let thisClassName = e.target.className
                  let parentClassName = e.target.parentNode.className
                  if (thisClassName === this.SelectClass || parentClassName === this.SelectClass) {
                    node.node.selected = false
                    if (thisClassName === this.SelectClass) {
                      e.target.className = this.DefineClass
                    } else {
                      e.target.parentNode.className = this.DefineClass
                    }
                  } else {
                    node.node.selected = true
                    if (thisClassName === this.DefineClass) {
                      e.target.className = this.SelectClass
                    } else {
                      e.target.parentNode.className = this.SelectClass
                    }
                  }
                  this.OnSelect(node)
                }
              }
            },
            [
              h('Icon', {
                props: {
                  type: this.iconType(node.node.hasChild, node.node.expand)
                }
              }),
              h('span', data.title),
              h('Icon', {
                props: {
                  type: 'md-checkmark'
                }
              })
            ])
          } else {
            return h('div', {
              class: ['ivu-tree-title'],
              on: {
                click: (e) => {
                  let thisClassName = e.target.className
                  let parentClassName = e.target.parentNode.className
                  if (thisClassName === this.SelectClass || parentClassName === this.SelectClass) {
                    node.node.selected = false
                    if (thisClassName === this.SelectClass) {
                      e.target.className = this.DefineClass
                    } else {
                      e.target.parentNode.className = this.DefineClass
                    }
                  } else {
                    node.node.selected = true
                    if (thisClassName === this.DefineClass) {
                      e.target.className = this.SelectClass
                    } else {
                      e.target.parentNode.className = this.SelectClass
                    }
                  }
                  this.OnSelect(node)
                }
              }
            },
            [
              h('Icon', {
                props: {
                  type: this.iconType(node.node.hasChild, node.node.expand)
                }
              }),
              h('span', data.title),
              h('Icon', {
                props: {
                  type: 'md-checkmark'
                }
              })
            ])
          }
        },
        OnSelect (data) {
          this.$emit('OnSelectChange', data)
          this.selectedList = this.$refs.tree.getSelectedNodes()
        }
      }
    }
    </script>
    <style lang="scss" scoped>
    @import './transfer.scss';
    </style>
    <style lang="scss">
    .transfer {
      .ivu-tree-title-selected,
      .ivu-tree-title-selected:hover,
      .ivu-tree-title:hover {
        background-color: #fff;
      }
      .ivu-tree-title {
        vertical-align: middle;
        span {
          margin: 0 5px;
        }
        .ivu-icon {
          color: #2b85e4;
          font-size: 16px;
          &.ivu-icon-md-checkmark {
            display: none;
          }
        }
        &.ivu-tree-title-selected {
          .ivu-icon {
            &.ivu-icon-md-checkmark {
              display: inline-block;
              color: #19be6b;
            }
          }
        }
      }
    }
    </style>

     对于节点的点击事件,可以做简单的抽离,js部分代码如下:

    export default {
      name: 'transfer',
      data () {
        return {
          nodeKey: null,
          SelectClass: 'ivu-tree-title ivu-tree-title-selected',
          DefineClass: 'ivu-tree-title',
          selectedList: [],
          selectedData: [
            {
              'id': 111,
              'title': 'leaf 1-1-1'
            },
            {
              'id': 112,
              'title': 'leaf 1-1-2'
            }
          ],
          data2: [
            {
              id: 1,
              title: 'parent 1',
              expand: true,
              hasChild: true,
              children: [
                {
                  id: 11,
                  title: 'parent 1-1',
                  expand: true,
                  hasChild: true,
                  children: [
                    {
                      id: 111,
                      title: 'leaf 1-1-1'
                    },
                    {
                      id: 112,
                      title: 'leaf 1-1-2'
                    }
                  ]
                },
                {
                  id: 12,
                  title: 'parent 1-2',
                  expand: true,
                  hasChild: true,
                  children: [
                    {
                      id: 121,
                      title: 'leaf 1-2-1'
                    },
                    {
                      id: 122,
                      title: 'leaf 1-2-2'
                    }
                  ]
                }
              ]
            }
          ]
        }
      },
      created () {
        for (let i = 0, l = this.selectedData.length; i < l; i++) {
          this.traverseTree(this.data2[0], this.selectedData[i].id, false)
        }
        this.selectedList = this.selectedData
      },
      methods: {
        iconType (hasChild, expand) {
          let iconType = 'ios-document'
          if (hasChild) {
            if (expand) {
              iconType = 'ios-folder-open'
            } else {
              iconType = 'ios-folder'
            }
          } else {
            iconType = 'ios-document'
          }
          return iconType
        },
        cancelSelected (item, index) {
          this.selectedList.splice(index, 1)
          this.traverseTree(this.data2[0], item.id, true)
          this.$refs.tree.$el.querySelectorAll('.ivu-tree-title-selected')[index].className = 'ivu-tree-title'
        },
        renderContent (h, { root, node, data }) {
          if (node.node.selected) {
            return h('div', {
              class: ['ivu-tree-title', 'ivu-tree-title-selected'],
              on: {
                click: (e) => {
                  let thisClassName = e.target.className
                  let parentClassName = e.target.parentNode.className
                  let o = this.changeNode(thisClassName, parentClassName)
                  node.node.selected = o.selected
                  if (thisClassName === o.otherClassName) {
                    e.target.className = o.className
                  } else if (parentClassName === o.otherClassName) {
                    e.target.parentNode.className = o.className
                  }
                  this.OnSelect(node)
                }
              }
            },
            [
              h('Icon', {
                props: {
                  type: this.iconType(node.node.hasChild, node.node.expand)
                }
              }),
              h('span', data.title),
              h('Icon', {
                props: {
                  type: 'md-checkmark'
                }
              })
            ])
          } else {
            return h('div', {
              class: ['ivu-tree-title'],
              on: {
                click: (e) => {
                  let thisClassName = e.target.className
                  let parentClassName = e.target.parentNode.className
                  let o = this.changeNode(thisClassName, parentClassName)
                  node.node.selected = o.selected
                  if (thisClassName === o.otherClassName) {
                    e.target.className = o.className
                  } else if (parentClassName === o.otherClassName) {
                    e.target.parentNode.className = o.className
                  }
                  this.OnSelect(node)
                }
              }
            },
            [
              h('Icon', {
                props: {
                  type: this.iconType(node.node.hasChild, node.node.expand)
                }
              }),
              h('span', data.title),
              h('Icon', {
                props: {
                  type: 'md-checkmark'
                }
              })
            ])
          }
        },
        OnSelect (data) {
          this.$emit('OnSelectChange', data)
          this.selectedList = this.$refs.tree.getSelectedNodes()
        },
        changeNode (thisClassName, parentClassName) {
          let selected = false
          let className = this.DefineClass
          let otherClassName = this.SelectClass
          if (thisClassName === this.SelectClass || parentClassName === this.SelectClass) {
            selected = false
            className = this.DefineClass
            otherClassName = this.SelectClass
          } else {
            selected = true
            className = this.SelectClass
            otherClassName = this.DefineClass
          }
          return {
            selected,
            className,
            otherClassName
          }
        },
        traverseTree (node, id, isDel) {
          if (!node) {
            return
          }
          if (node.id === id) {
            if (isDel) {
              node.selected = false
            } else {
              node.selected = true
            }
          }
          let children = node.children
          if (children && children.length > 0) {
            for (let i = 0, l = children.length; i < l; i++) {
              this.traverseTree(children[i], id, isDel)
            }
          }
        }
      }
    }
  • 相关阅读:
    Hadoop概述与配置
    组件间通讯及钩子函数
    react组件
    JSX
    Node.js二分查找
    链表
    微信支付V3
    在有序数组中查找某一特定元素的索引
    给定一个只包括 ‘(‘,‘)‘,‘{‘,‘}‘,‘[‘,‘]‘ 的字符串,判断字符串是否有效。
    我的前半生
  • 原文地址:https://www.cnblogs.com/ToBeBest/p/9606213.html
Copyright © 2020-2023  润新知