vue2+element-ui el-tree树形控件封装
1.封装
根据官网配置项封装了下el-tree 方便维护和复用,有用的话点赞收藏叭~
<template><div class="my-tree"><el-inputv-if="hasSearch"v-model="filterText"class="search-input"placeholder="输入关键字进行过滤"></el-input><slot></slot><el-tree ref="myTree":icon-class="iconClass" :filter-node-method="filterNodeMethod":default-checked-keys="defaultCheckedKeys" :check-strictly="checkStrictly" :show-checkbox="showCheckbox" :default-expanded-keys="defaultExpandedKeys":highlight-current="highlightCurrent":check-on-click-node="checkOnClickNode":default-expand-all="defaultExpandAll":expand-on-click-node="expandOnClickNode":node-key="nodeKey":data="treeData":props="defaultProps" :empty-text="emptyText":render-content="renderContent"@node-click="nodeClick"@check="check"@check-change="checkChange"@current-change="currentChange"@node-expand="nodeExpand"@node-collapse="nodeCollapse"></el-tree></div>
</template><script>
export default {name: 'MyTree',props: {nodeKey: {type: String,default: 'id'},// 树形控件展示数据treeData: {type: Array,default: function () {return []}},// 默认展开的节点的 key 的数组 defaultExpandedKeys: {type: Array,default: function () {return []}},// props配置项defaultProps: {type: Object,default: function () {return {label: 'label',children: 'children',disabled: function (data, node) {return data}}}},// 内容为空时的文案emptyText: {type: String,default: '暂无数据'},// 是否高亮当前选中highlightCurrent: {type: Boolean,default: false},// 是否默认展开所有节点defaultExpandAll: {type: Boolean,default: false},// 是否在点击节点的时候展开或者收缩节点, 默认值为 true,如果为 false,则只有点箭头图标的时候才会展开或者收缩节点。expandOnClickNode: {type: Boolean,default: true},// 是否在点击节点的时候选中节点,默认值为 false,即只有在点击复选框时才会选中节点。checkOnClickNode: {type: Boolean,default: false},// 节点是否可被选择showCheckbox: {type: Boolean,default: false},// 在显示复选框的情况下,是否严格的遵循父子不互相关联的做法checkStrictly: {type: Boolean,default: false},// 默认勾选的节点的 key 的数组defaultCheckedKeys: {type: Array,default: function () {return []}},// 是否需要搜索功能hasSearch: {type: Boolean,default: false},// 自定义树节点的图标iconClass: {type: String,default: ''},// 自定义节点内容renderContent: {type: Function,default: function (h, { node, data, store }) {return (<span class="custom-tree-node"><span>{node.label}</span></span>)}}},data() {return {filterText: '' // 关键字过滤值}},watch: {filterText(val) {this.$refs.myTree.filter(val)}},methods: {// 节点被点击时的回调nodeClick(data, node, self) {this.$emit('nodeClick', { data, node, self })},// 当复选框被点击的时候触发check(data, checkObj) {this.$emit('check', { data, checkObj })},// 节点选中状态发生变化时的回调checkChange(data, isChecked, childIsCheked) {// 传递给 data 属性的数组中该节点所对应的对象、节点本身是否被选中、节点的子树中是否有被选中的节点this.$emit('checkChange', { data, isChecked, childIsCheked })},// 当前选中节点变化时触发的事件currentChange(data, node) {this.$emit('currentChange', { data, node })},// 对树节点进行筛选时执行的方法,返回 true 表示这个节点可以显示,返回 false 则表示这个节点会被隐藏filterNodeMethod(value, data, node) {if (!value) return truereturn data[this.defaultProps.label].indexOf(value) !== -1},// 节点被展开时触发的事件nodeExpand(data, node, el) {this.$emit('nodeExpand', { data, node, el })},// 节点被关闭时触发的事件nodeCollapse(data, node, el) {this.$emit('nodeCollapse', { data, node, el })},// 若节点可被选择(即 show-checkbox 为 true),则返回目前被选中的节点所组成的数组getCheckedNodes(leafOnly = false, includeHalfChecked = false) {return this.$refs.myTree.getCheckedNodes(leafOnly, includeHalfChecked)},// 设置目前勾选的节点,使用此方法必须设置 node-key 属性setCheckedNodes(nodes) {this.$refs.myTree.setCheckedNodes(nodes)},// 若节点可被选择(即 show-checkbox 为 true),则返回目前被选中的节点的 key 所组成的数组getCheckedKeys(leafOnly = false, includeHalfChecked = false) {return this.$refs.myTree.getCheckedKeys(leafOnly, includeHalfChecked)},// 通过 keys 设置目前勾选的节点,使用此方法必须设置 node-key 属性setCheckedKeys(keys, leafOnly = false) {this.$refs.myTree.setCheckedKeys(keys, leafOnly)},// 通过 key / data 设置某个节点的勾选状态,使用此方法必须设置 node-key 属性setChecked(keyordata, checked, deep = false) {this.$refs.myTree.setChecked(keyordata, checked, deep)},// 若节点可被选择(即 show-checkbox 为 true),则返回目前半选中的节点所组成的数组getHalfCheckedNodes() {return this.$refs.myTree.getHalfCheckedNodes()},// 若节点可被选择(即 show-checkbox 为 true),则返回目前半选中的节点的 key 所组成的数组getHalfCheckedKeys() {return this.$refs.myTree.getHalfCheckedKeys()},// 获取当前被选中节点的 key,使用此方法必须设置 node-key 属性,若没有节点被选中则返回 nullgetCurrentKey() {return this.$refs.myTree.getCurrentKey()},// 获取当前被选中节点的 data,若没有节点被选中则返回 nullgetCurrentNode() {return this.$refs.myTree.getCurrentNode()},// 通过 key 设置某个节点的当前选中状态,使用此方法必须设置 node-key 属性setCurrentKey(key) {this.$refs.myTree.setCurrentKey(key)},// 通过 node 设置某个节点的当前选中状态,使用此方法必须设置 node-key 属性setCurrentNode(node) {this.$refs.myTree.setCurrentNode(node)},// 设置 node-key 属性 (node) 待被选节点的 node getNode 根据 data 或者 key 拿到 Tree 组件中的 nodegetNode(data) {return this.$refs.myTree.getNode(data)},// 删除 Tree 中的一个节点,使用此方法必须设置 node-key 属性remove(data) {this.$refs.myTree.remove(data)},// 为 Tree 中的一个节点追加一个子节点append(data, parentNode) {this.$refs.myTree.append(data, parentNode)},// 递归拉平数据recursion(arr) {return [].concat(...arr.map(item => {if (item[this.defaultProps['children']]) {let arr = [].concat(item, ...this.recursion(item[this.defaultProps['children']]))delete item[this.defaultProps['children']]return arr}return [].concat(item)}))},// 获取拉平的treeData数据getFlatData() {let cloneData = JSON.parse(JSON.stringify(this.treeData))return this.recursion(cloneData)}}
}
</script><style lang="scss" scoped>.my-tree {.search-input {margin-bottom: 10px;}}
</style>
2.使用
<template><div class="tree-box"><my-tree ref="myTree" :tree-data="treeData" icon-class="el-icon-star-on" :default-checked-keys="defaultCheckedKeys" :show-checkbox="true" :default-expanded-keys="defaultExpandedKeys" :highlight-current="true" :check-on-click-node="false" :default-props="defaultProps" @nodeClick="nodeClick" @checkChange="checkChange" @check="check"></my-tree><div class="info-box"><p>当前选中:{{ chooseObj.name||'-' }}</p><p>当前勾选:{{ curChecks||'-' }}</p></div><div class="btn-box"><el-button type="primary" @click="getCheckedNodes">根据node获取勾选项Id</el-button><el-button type="primary" @click="setCheckedNodes">根据node设置勾选三级 3-2-2</el-button><el-button type="primary" @click="getCheckedKeys">根据key获取勾选项Id</el-button><el-button type="primary" @click="setCheckedKeys">根据key设置勾选三级 3-2-2</el-button><el-button type="primary" @click="setChecked">勾选三级 3-1-1</el-button></div></div>
</template><script>
import MyTree from '../../components/MyTree/index.vue'
export default {components: { MyTree },data() {return {treeData: [{id: 1,name: '一级 2',child: [{id: 3,name: '二级 2-1',child: [{id: 4,name: '三级 3-1-1',child: [{id: 8,name: '四级 4-1-1'}, {id: 9,name: '四级 4-1-2',disabled: true}]},{id: 5,name: '三级 3-1-2',disabled: true,child: [{id: 10,name: '四级 4-1-3'}, {id: 11,name: '四级 4-1-4',disabled: true}]}]}, {id: 2,name: '二级 2-2',disabled: true,child: [{id: 6,name: '三级 3-2-1'}, {id: 7,name: '三级 3-2-2',disabled: true}]}]}],defaultExpandedKeys: [5],defaultCheckedKeys: [9],defaultProps: {label: 'name',children: 'child'},chooseObj: {},checkInfo: {checkObj: {checkedNodes: [{ name: '四级 4-1-2' }]}}}},computed: {curChecks() {if (this.checkInfo && this.checkInfo.checkObj) {return this.checkInfo.checkObj.checkedNodes.map(item => item.name).join('、')} else {return ''}}},methods: {// 节点被点击时获取选中项nodeClick(obj) {this.chooseObj = obj.data},// 节点选中状态发生变化时的回调checkChange(obj) {},// 当复选框被点击的时候触发check(obj) {this.checkInfo = obj},// 根据node获取当前勾选项getCheckedNodes() {let checkArr = this.$refs.myTree.getCheckedNodes(true, true)this.$message.success(`当前勾选id有:${checkArr.map(item => item.id).join('、')}`)},// 根据node设置目前勾选的节点setCheckedNodes() {this.$refs.myTree.setCheckedNodes([{id: 7,name: '三级 3-2-2',disabled: true}])},// 根据key获取当前勾选项getCheckedKeys() {let checkArr = this.$refs.myTree.getCheckedKeys(true, true)this.$message.success(`当前勾选id有:${checkArr.map(item => item).join('、')}`)},// 根据key设置目前勾选的节点setCheckedKeys() {this.$refs.myTree.setCheckedKeys([7])},// 勾选三级 3-1-1setChecked() {this.$refs.myTree.setChecked(4, !this.$refs.myTree.getNode(4).checked)}}
}
</script><style lang="scss" scoped>.tree-box {width: 60%;margin: 0 auto;::v-deep .el-tree-node__expand-icon {font-size: 16px;}}
</style>
3.重置样式
如若要对不同的一级二级节点设置不同的样式可以参考这样:
/* 一级节点样式 */>.el-tree-node>.el-tree-node__content {height: 44px;font-size: 14px;color: #333;font-family: PingFang SC-Medium, PingFang SC;font-weight: 500;background-color: #F5F5F7;margin-bottom: 8px;padding-left: 12px !important;}/* 二级节点样式 */>.el-tree-node .el-tree-node .el-tree-node__content {height: 34px;font-size: 13px;color: #444;margin-bottom: 8px;padding-left: 36px !important;&:before {content: "";display: inline-block;width: 6px;height: 6px;background-color: #54B7AD;border-radius: 50%;margin-right: 8px;}}/* 三级节点样式 */>.el-tree-node .el-tree-node .el-tree-node .el-tree-node__content {height: 30px;font-size: 12px;color: #444;margin-bottom: 4px;padding-left: 50px !important;&:before {display: none;}}
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
