vue3/element plus自定义封装tree

// tree-item.vue
<template>
  <div class="tree-item">
    <div @click="handleToggle(list)" @dblclick="handleDblClick(list)" class="tree-title">
      <el-icon v-if="hasChild" :color="'blue'" :size="15" @click="add(list)">
        <CirclePlus />
      </el-icon>
      <el-icon v-else :color="'blue'" :size="15" @click="tips(list)">
        <Remove />
      </el-icon>
      <el-icon v-if="hasChild && list.label != '根目录'" :color="'blue'" :size="15" @click="tips(list)">
        <Remove />
      </el-icon>
      <h4 style="margin-left: 5px">{
   
   { list.label }}</h4>
    </div>
    <div v-show="open" class="child-content">
      <tree-item v-for="(item, index) in list.children" :list="item" :key="index"></tree-item>
    </div>
  </div>
</template>

<script>
import {
      
       ElMessage } from "element-plus";
export default {
      
      
  name: "TreeItem",
  // vue3 使用 defineProps 声明 props
  /**
  const props = defineProps({
    str: {
      type: String,
      default: "",
    },
  });
  */
  props: {
      
      
    list: {
      
      
      type: [Object, Array],
      required: true
    }
  },
  data() {
      
      
    return {
      
      
      open: false
    };
  },
  // vue3引入 import { computed } from 'vue'
  /**
vue.3.0 中用于从vue 按需导入 computed 计算属性。
如果传入的是一个getter 函数, 会返回一个不允许修改的计算属性。
使用ref 创建一个响应式对象, 在模板中使用不用自动解套。 直接渲染使用。
传入一个对象, 包含get 和 set 函数, 就可以创建一个可以修改的计算属性。
只可以获取值,不允许修改值直接使用 computed 计算属性使用箭头函数。
既可以获取值, 也可以修改值, computed 计算属性中传入一个对象。 get 方法 和 set 方法。
而且,vue3的过滤器已经移除,所以建议用计算属性去替代过滤器
*/
  computed: {
      
      
    hasChild() {
      
      
      return this.list.children && this.list.children.length;
    }
  },
  methods: {
      
      
    add(list) {
      
      
      console.log(list);
      // vue3方式
      ElMessage({
      
      
        message: `增加数据`,
        type: "warning"
      });
    },
    tips(list) {
      
      
      ElMessage({
      
      
        message: `删除${ 
        list.label}`,
        type: "warning"
      });
    },
    handleToggle(list) {
      
      
      console.log(list);
      if (this.hasChild) {
      
      
        this.open = !this.open;
      }
    },
    handleDblClick(list) {
      
      
      console.log(111);
      ElMessage({
      
      
        message: `修改${ 
        list.label}名称`,
        type: "warning"
      });
    }
  }
};
</script>

<style lang="less" scoped>
.tree-item {
      
      
  font-size: 15px;
  cursor: pointer;

  .tree-title {
      
      
    display: flex;
    justify-content: flex-start;
    align-items: center;
  }
}

.child-content {
      
      
  margin-left: 20px;
}
</style>

// tree.vue
<template>
  <div class="tree-wrap">
    <div v-for="(item, index) in dataSource" :key="index">
      <tree-item :list="item"></tree-item>
    </div>
  </div>
</template>

<script>
// vue3以setup语法糖进行挂载,只需要导入然后直接可以挂载子组件
import TreeItem from "./tree-item.vue";
export default {
      
      
  name: "tree",
  props: {
      
      
    dataSource: {
      
      
      type: [Object, Array],
      required: true
    }
  },
  components: {
      
      
    TreeItem
  }
};
</script>
<style scoped>
.tree-wrap {
      
      
  width: 100%;
  /* padding: 0 50px; */
}
</style>

// 父组件引入
import xTree from "./tree.vue";
<template>
      <x-tree :data-source="tree"></x-tree>
</template>
<script lang="ts">
export default defineComponent({
      
      
  setup() {
      
      
    let tree = reactive([
      {
      
      
        label: "根目录",
        children: [
          {
      
      
            label: "车辆",
            children: [
              {
      
      
                label: "出租车"
              },
              {
      
      
                label: "公交车"
              }
            ]
          },
          {
      
      
            label: "企业"
          },
          {
      
      
            label: "人员"
          }
        ]
      }
    ]);
    }
    )}
    </script>

猜你喜欢

转载自blog.csdn.net/Xiang_Gong_Ya_/article/details/132184259