理解Vue递归组件,实现Tree树形控件实例~
2020/3/5 11:02:42
本文主要是介绍理解Vue递归组件,实现Tree树形控件实例~,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
思考了两天时间,准备仿照ant-design-vue实现一个基于vue的树形控件。主要用到了vue递归组件思想、input的CheckBox类型输入框的使用。
需求
- 能够将传入的Json数据生成树形目录。
- 能够初始化选中节点。
- 能够手动选中节点,最终可将所有选中节点打印出来。
- 能够在初始化禁用节点。
- 能够折叠树形目录。
- 修改原生CheckBox样式。
实例截图
做好的树形控件如下所示,点击获取选中节点key将弹出所有选中的节点:
手把手实现
了解Vue递归组件
在vue的文档(cn.vuejs.org/v2/guide/co…
- 组件有name属性
- 递归调用需要有条件
根据以上说明创建了基础树形控件tree.vue:
全局变量:global.js
在写组件获取节点内容是发现由于是递归组件,并不好拿到每级选中的节点。因此在这里创建global.js全局变量记录所有选中节点。也便于删除和加入节点。 默认选中的节点如下:
const nodes = ['1', '1-1', '1-1-2', '1-2-2'] export default { nodes } 复制代码
写好后需要在main.js上挂载。
import global from 'common/js/global' Vue.prototype.$global = global 复制代码
基础组件(递归组件):tree.vue
说明:这里不需要再用components属性去声明自己了,有了name属性后直接在template中就可以调用名为name值的组件。
<template> <ul class="ul-wrapper"> <!-- 包裹层--> <li v-for="item in list" :key="item.key"> <!-- 遍历--> <div> <!-- 是否展开图标--> <img class="icon" v-show="item.children" @click="changeShow" :src="require(`../common/images/${imgUrl}`)" > <!-- CheckBox--> <input type="checkbox" :name="item.key" @click="clickbox" :checked="isChecked(item.key)" :disabled="item.disabled" > <div class="checkbox-title">{{item.title}}</div> <!-- CheckBox内容--> </div> <tree v-if="showChildren" :list="item.children"></tree> <!-- 遍历children--> </li> </ul> </template> <script type='text/ecmascript-6'> export default { name: 'tree', props: { list: { // 所有树节点 type: Array, default: () => { return [] } } }, data () { return { showChildren: true // 是否展开根目录 } }, computed: { // computed属性计算展开图标 imgUrl () { return this.showChildren ? 'down.png' : 'right.png' } }, methods: { clickbox (e) { // 点击CheckBox时需要加入或删除已选中this.$global.nodes的节点数组中 const checked = e.target.checked const key = e.target.name const nodes = this.$global.nodes // this.$global.nodes是全局变量,便于递归组件记录选中节点 if (checked) { if (!nodes.includes(key)) { this.$global.nodes.push(key) } } else { this.$global.nodes = nodes.filter((item) => { return key !== item }) } }, changeShow () { // 点击是否展开根目录,当前状态取反即可 this.showChildren = !this.showChildren }, isChecked (key) { // 查看是否已经存在于选中节点中 return this.$global.nodes.includes(key) } } } </script> <style lang="stylus"> .ul-wrapper // ul包裹层,每层需要向右偏移30px margin 10px 30px 0 .checkbox-title, .icon display inline-block vertical-align middle .icon margin-left -20px height 18px width 18px input[type="checkbox"] // CheckBox样式修改 position relative display inline-block vertical-align middle padding 0 margin-right 5px height 18px width 18px border 1px solid #ccc border-radius 3px input[type="checkbox"]:checked::before // CheckBox选中状态时样式修改 position absolute top 0 left 0 padding-left 2px content: "\2713"; height 15px width 13px font-size 12px font-weight: bold; background #1296db color #fff border-radius 3px border 0 input[type="checkbox"]:disabled::before // CheckBox禁用状态时样式修改 position absolute top 0 left 0 padding-left 2px content: ""; height 15px width 13px font-size 12px font-weight: bold; background #ccc color #fff border-radius 3px border 0 </style> 复制代码
应用组件 tree-apply.vue
<template> <div class="tree-wrapper"> <div class="btn" @click="showNodes"> 点击获取选中节点key </div> <Tree :list="treeData"></Tree> </div> </template> <script type='text/ecmascript-6'> import Tree from 'base/tree' export default { data () { return { treeData: [] // 全部节点 } }, created () { this.getData() }, methods: { getData () { this.axios.get('/tree').then((res) => { // 获取mock数据 this.treeData = res.data }) }, showNodes () { alert(this.$global.nodes) } }, components: { Tree } } </script> <style lang="stylus"> .btn margin 20px text-align center </style> 复制代码
mock数据tree.json
这里采用了模拟数据的方法,mock的具体使用方法在我上一篇写的《better-scroll实现轮播图组件》中有提到:blog.csdn.net/qq_39083496…
- 是否禁用CheckBox是根据 "disabled": "true",决定的。
- title(必须)是显示的label名。
- key(必须)才是真正的关键字,理解为最后提交时的必要字段。
[{ "title": "1", "key": "1", "children": [ { "title": "1-1", "key": "1-1", "children": [ { "title": "1-1-1", "key": "1-1-1" }, { "title": "1-1-2", "key": "1-1-2" }, { "title": "1-1-3", "key": "1-1-3" } ] }, { "title": "1-2", "key": "1-2", "children": [ { "title": "1-2-1", "key": "1-2-1" }, { "title": "1-2-2", "key": "1-2-2" }, { "title": "1-2-3", "key": "1-2-3" } ] }, { "title": "1-3", "key": "1-3" } ] }, { "title": "2", "key": "2", "disabled": "true", "children": [ { "title": "2-1", "key": "2-1" }, { "title": "2-2", "key": "2-2" }, { "title": "2-3", "key": "2-3" } ] }, { "title": "3", "key": "3" }] 复制代码
接口:
const Mock = require('mockjs') Mock.mock('/tree', 'get', require('./json/tree.json')) 复制代码
总结
到此就完成了树形控件的生成,需求部分都已经满足。如果通过以上代码片段不能明白的话,可以在我的github上找到源码。欢迎来访,欢迎Star~
github.com/Gesj-yean/v…
这篇关于理解Vue递归组件,实现Tree树形控件实例~的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-10-04package.json 文件位置在哪?-icode9专业技术文章分享
- 2024-10-01Craco.js学习:从入门到实践指南
- 2024-10-01Create-React-App学习:入门与实践指南
- 2024-10-01CSS-in-JS学习:从入门到实践指南
- 2024-09-30JSX语法学习:从入门到初步掌握
- 2024-09-30Mock.js学习:入门教程与实战演练
- 2024-09-30React Hooks学习:从入门到实践
- 2024-09-30受控组件学习:React中的基础入门教程
- 2024-09-29JS定时器教程:初学者必看指南
- 2024-09-29JS对象教程:初学者的全面指南