美文网首页
Vue 自写Tree组件

Vue 自写Tree组件

作者: Nolenj | 来源:发表于2019-11-23 11:04 被阅读0次

底层探索,追求原生,仅此而已

<!-- 递归组件,必须声明name,然后就可以自调用 -->
<template>
  <div>
    <div v-for="node in list" v-bind:key="node.id" class="nolenj_tree_node" @click="NodeClick(node)">
      <span v-if="node.child.length>0" class="iconfont "
      :class="[node.OpenStatus?'nolenj_icon_turning_down':'nolenj_icon_turning_right',(node.isactive)?(node.OpenStatus?'op':'close'):'']"
        @click="clickicon(node)"></span>
      <span v-else class="iconfont nolenj_icon_turning_right nolenj_tree_node_nochild" style="color: transparent;"></span>
      <span class="nolenj_tree_node_title">{{node.title}}</span>
      <transition name="tree">
        <Tree v-if="node.child.length>0 && node.OpenStatus" :list='node.child' class="nolenj_tree_node_child" :id="node.id"></Tree>
      </transition>
    </div>
  </div>
</template>

<script>
  export default {
    name: 'Tree',
    props: {
      list: {
        type: Array
      }
    },
    data() {
      return {}
    },
    mounted() {
      this.$el.style.setProperty('--max-height', this.$el.scrollHeight + 'px')
    },
    methods: {
      clickicon(d) {
        d.OpenStatus = !d.OpenStatus;
        //用来阻止刚加载的动画效果
        d['isactive'] = true;
      },
      NodeClick(d){
        this.$emit('NodeClick',d)
      }
    },
    components: {

    }
  }
</script>

<style scoped>
  div,
  span {
    /* 禁止选中文本 */
    user-select: none;
    -webkit-user-select: none;
  }
  .nolenj_tree_node_child {
    margin-left: 2rem;
    overflow: hidden;
  }
  .nolenj_icon_turning_right:before {
    display: inline-block;
  }
  /* 动画进行时的样式 */
  .tree-enter-active,
  .tree-leave-active {
    /* 指定样式过度,max-height也可以All表示全部样式 */
    transition: max-height 0.6s;
  }
  /* 动画开始 */
  .tree-enter,
  .tree-leave-to {
    max-height: 0;
  }
  /* 动画结束 */
  .tree-enter-to,
  .tree-leave {
    /* 变量写法,同时也是从style文档获取 var(--max-height) */
    max-height: var(--max-height);
  }
  .op {
    display: inline-block;
    animation: op 0.6s;
  }
  @keyframes op {
    from {
      transform: rotate(-90deg);
    }
    to {
      transform: rotate(0deg);
    }
  }
  .close {
    display: inline-block;
    animation: close 0.6s;
  }
  @keyframes close {
    from {
      transform: rotate(90deg);
    }

    to {
      transform: rotate(0deg);
    }
  }
</style>

调用方法

<template>
  <div id="body">    
        <Tree :list='treedatamodule' @NodeClick="TreeClick"></Tree>
  </div>
</template>
<script>
  import Tree from '@/components/Tree/Tree.vue'
  export default {
    data() {
      return {
        // OpenStatus必须有且默认为false,child必须有且默认为[]
        treedatamodule: [{
            id: 1,
            title: '广东',
            OpenStatus: false,
            child: [{
              id: 2,
              title: '中山',
              OpenStatus: false,
              child: [{
                id: 4,
                title: '东凤',
                OpenStatus: false,
                child: []
              }, {
                id: 5,
                title: '横栏',
                OpenStatus: false,
                child: []
              }, {
                id: 6,
                title: '东升',
                OpenStatus: false,
                child: []
              }, ]
            }, {
              id: 3,
              title: '广州',
              OpenStatus: false,
              child: [{
                id: 7,
                title: '番禺',
                OpenStatus: false,
                child: []
              }, ]
            }, ]
          },
          {
            id: 10,
            title: '广西',
            OpenStatus: false,
            child: []
          }
        ]
      }
    },
    methods: {
      TreeClick(d) {
        console.log(d);
      }
    },
    components: {
      Tree,
    },
  }
</script>
<style scoped>
</style>

欢迎评论和建议

相关文章

网友评论

      本文标题:Vue 自写Tree组件

      本文链接:https://www.haomeiwen.com/subject/zkxhwctx.html