vue:实现一个简单的分类树

1.起因

项目中需要列表左侧的分类树可以展示多级,原有的样式与el-tree的样式不符合,所以就想着自己来实现一个

2.实现

首先我们需要创建两个文件 treeCatalog.vue 和 treeCatalogChildren.vue 其实两者的代码是差不多一样的,但这是为了能够实现递归

代码的相关实现如下:

// treeCatalog.vue
<template>
  <div>
    <div v-for="(item, index) of treeList" :key="index">
      <div
        class="catalog-item font-14 p-l-24 cp"
        :class="{ 'catalog-item__active': item._active }"
        @click="handleItemClick(item)"
      >
        <span :style="{ 'padding-left': margin + 'px' }">{{ item.name }}</span>
        <div v-if="item.childrenCount > 0" class="catalog-item__arrow">
          <i class="el-icon-caret-left" :class="{ 'expand': item._showChild }" @click.stop="handleLoadChildren(item)"></i>
        </div>
      </div>
      <template v-if="item._showChild">
        <tree-catalog-children
          :treeList="item.children"
          :margin="margin + 20"
          @tree-click="$emit('tree-click')"
        ></tree-catalog-children>
      </template>
    </div>
  </div>
</template>

<script>
export default {
  props: {
    treeList: {
      type: Array,
      default: () => [],
    },
    // 传margin形成层级样式
    margin: {
      type: Number,
      default: 0,
    },
  },
  components: {
    // 一定要这么引入,不然Vue的解析会出问题
    treeCatalogChildren: () => import('./treeCatalogChildren.vue'),
  },
  methods: {
    handleItemClick(item) {
      this.$set(item, '_active', true)
      // 向上派发一个事件
      this.$emit('tree-click', item)
    },
    // 懒加载子节点
    handleLoadChildren(item) {
      if (item._showChild) {
        item._showChild = false
        return
      }
      if (item.children.length > 0) {
        this.$set(item, '_showChild', true)
        return
      }
      // 加载children...
      item.children = data
      this.$set(item, '_showChild', true)
    },
  },
}
</script>

<style>
</style>
// treeCatalogChildren.vue
<template>
  <div>
    <!-- @click="handleCatalogSelect(index)" -->
    <div v-for="(item, index) of treeList" :key="index">
      <div
        class="catalog-item font-14 p-l-24 cp"
        :class="{ 'catalog-item__active': item._active }"
        @click="handleItemClick(item)"
      >
        <span :style="{ 'padding-left': margin + 'px' }">{{ item.name }}</span>
        <div v-if="item.childrenCount > 0" class="catalog-item__arrow">
          <i class="el-icon-caret-left" :class="{ 'expand': item._showChild }" @click.stop="handleLoadChildren(item)"></i>
        </div>
      </div>
      <template v-if="item._showChild">
        <tree-catalog
          :treeList="item.children"
          :margin="margin + 20"
        ></tree-catalog>
      </template>
    </div>
  </div>
</template>

<script>
export default {
  props: {
    treeList: {
      type: Array,
      default: () => [],
    },
    margin: {
      type: Number,
      default: 0,
    },
  },
  components: {
    treeCatalog: () => import('./treeCatalog.vue'),
  },
  methods: {
    handleItemClick(item) {
      this.$set(item, '_active', true)
      // 向上派发一个事件
      this.$emit('tree-click', item)
    },
    // 懒加载子节点
    handleLoadChildren(item) {
      if (item._showChild) {
        item._showChild = false
        return
      }
      if (item.children.length > 0) {
        this.$set(item, '_showChild', true)
        return
      }
      // 加载children...
      item.children = data
      this.$set(item, '_showChild', true)
    },
  },
}
</script>

<style>
</style>
// 相关的css样式
.catalog-item {
  position: relative;
  padding-right: 40px;
  line-height: 61px;
  color: #333;
  & + .catalog-item {
    border-top: 1px solid #efefef;
  }
  &.catalog-item__active {
    background: #18bd9b;
    color: #ffffff;
  }
  &__arrow {
    position: absolute;
    top: 0;
    right: 20px;
    i {
      font-size: 18px !important;
    }
  }
  .el-icon-caret-left {
    transition: transform .5s;
  }
  .expand {
    transform: rotate(-90deg);
  }
}

这样子我们就能实现一个很好的分类树效果了

在这里插入图片描述

3.扩展

项目中分类树不需要多选的功能,所以现在说下实现多选的思路

1.我们在外面维护一个多选数组,然后传到组件里

2.里面每个组件使用el-checkbox-group来绑定这个数组

3.点击的时候在往上派发事件

End

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Spring Cloud项目中实现三级分类,可以采用形结构的方式实现。具体步骤如下: 1. 定义一个分类类,包含分类ID、分类名称、分类父ID等属性。 ``` public class Category { private int id; private String name; private int parentId; // getter和setter方法省略 } ``` 2. 构建形结构,可以使用递归方式实现。首先需要定义一个方法,该方法接收一个分类列表和一个分类ID,返回该父分类下的所有子分类。 ``` private List<Category> getChildren(List<Category> categories, int parentId) { List<Category> children = new ArrayList<>(); for (Category category : categories) { if (category.getParentId() == parentId) { children.add(category); List<Category> grandchildren = getChildren(categories, category.getId()); children.addAll(grandchildren); } } return children; } ``` 3. 在Spring Cloud项目中,可以定义一个RESTful API接口,用于获取分类列表。 ``` @RestController @RequestMapping("/categories") public class CategoryController { @Autowired private CategoryService categoryService; @GetMapping("") public List<Category> getAllCategories() { return categoryService.getAllCategories(); } } ``` 4. 在前端中,可以使用Vue.js实现形结构的展示。首先需要定义一个组件,用于展示单个分类的信息。 ``` <template> <div> <span>{{ category.name }}</span> <ul v-if="category.children"> <category-item v-for="child in category.children" :key="child.id" :category="child"></category-item> </ul> </div> </template> <script> export default { name: 'category-item', props: { category: { type: Object, required: true } } } </script> ``` 5. 在前端中,可以定义一个根组件,用于展示整个分类。 ``` <template> <div> <category-item v-for="category in categories" :key="category.id" :category="category"></category-item> </div> </template> <script> import CategoryItem from './CategoryItem.vue' export default { name: 'category-tree', components: { CategoryItem }, data() { return { categories: [] } }, mounted() { axios.get('/categories').then(response => { this.categories = response.data }) } } </script> ``` 以上就是使用Spring Cloud和Vue.js实现三级分类的步骤。在实际开发中,还需要考虑数据的缓存和更新等问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值