您好,欢迎进入某某沙盘有限公司官网!

咨询热线:

400-888-8888

前端基础:广告系统中级联面板组件制作

发布时间:2021-05-28人气:
本文摘要:需求分析凭据效果图,首先需要把省市区的数据按列展示在左侧区域,点击父级节点联动展示子级数据,每次点击展开节点的下一级所在的列。勾选父级节点,子级节点全选,反之全选子级节点,父节点变为勾选状态。 每次举行勾选之后,右侧面板展示勾选效果。这里有一个细节,就是右侧面板展示的选择效果不是简朴的展示每一个被勾选中的节点。而是依据当某一个节点下的子节点全部被选中,则只展示父节点的原则,举行展示。 我把它简朴称为级联数据的压缩原则。

2020欧洲杯线上买球平台

需求分析凭据效果图,首先需要把省市区的数据按列展示在左侧区域,点击父级节点联动展示子级数据,每次点击展开节点的下一级所在的列。勾选父级节点,子级节点全选,反之全选子级节点,父节点变为勾选状态。

每次举行勾选之后,右侧面板展示勾选效果。这里有一个细节,就是右侧面板展示的选择效果不是简朴的展示每一个被勾选中的节点。而是依据当某一个节点下的子节点全部被选中,则只展示父节点的原则,举行展示。

我把它简朴称为级联数据的压缩原则。经由上面的分析可以发现这个组件本质上是一个扁平化了的checkbox-tree组件。之前关于类似省市区这种带有级联关系的数据选择,传统的交互设计往往就是接纳的checkbox-tree。

开发这个组件之前,已经有过重构老项目中的checkbox-tree的履历,参考的是element-ui的tree组件,学习了许多关于依赖于树形结构的组件构建技巧。组件借鉴了element-ui和iview的tree组件,在此由衷感受这些开源项目。

有了上述的分析,我们来正式开撸代码。因为是使用vue作为技术栈。第一步,也是最关键的一步,就是界说好组件的props和data。

props和data props: { data: {//展示数据 type: Array, required: true }, props: {//数据中的key和label字段别名, 因为外部数据(例如后端返回的树形结构)中标志label和key的字段往往不是牢固的 type: Object, default() { return { key: "id", label: "label" }; } }, settings: { /*设置,允许自界说每一级,eg:[ { level: 1,//列的级别,因为组件内部有一个虚拟的根节点,所以level从1开始 title: "一级分类",//列的标题 hasAllCheck: true,//是否展示全选checkbox showCheckBox: true//是否带有checkbox }, { level: 2, title: "二级分类", hasAllCheck: true, showCheckBox: true } ]*/ type: Array, required: true }, checkedLevel: {//数据展示的级别 type: Number, required: true }, zipLevel: {//数据压缩的级别 type: Number, required: true }, isSingle: {//是否是单选模式,如果为true,则降级为一个级联选择器 type: Boolean, default: false } }data() { return { rootNode: null,//组件内部使用的树形数据结构。接纳Node类型对data举行包装获得的树的根节点 flattenData: [],//扁平化后的数据,利便查找任意节点 curShowList: [],//控制当前面板的展开收起状态 checkedData: []//勾选中的数据 }; }Node数据类型组件内部使用了Node 类型的工具来包装用户传入的数据,用来生存现在节点的状态。关于Node类型的详细包装历程这里就不再赘述,需要的话可以看源码或者搜索相关数据结构的先容。这里仅对比一下用户传入的data和组建内部的Node。

2020欧洲杯线上买球首页

用户传入的:[ { id: 1, label: "一级 1", children: [ { id: 4, label: "二级 1-1", children: [ { id: 9, label: "三级 1-1-1" }, { id: 10, label: "三级 1-1-2" } ] } ] }, { id: 2, label: "一级 2", children: [ { id: 5, label: "二级 2-1" }, { id: 6, label: "二级 2-2" } ] }, { id: 3, label: "一级 3", children: [ { id: 7, label: "二级 3-1" }, { id: 8, label: "二级 3-2", children: [ { id: 11, label: "三级 3-2-1" }, { id: 12, label: "三级 3-2-2" }, { id: 13, label: "三级 3-2-3" } ] } ] } ]组件内部包装过的rootNodeNode类型的数据添加了checked(是否勾选),disabled(是否禁用),id(组件内部自增的唯一标识),level(节点深度),selected(是否选中),text(节点的文本)。提前界说好这些属性才气够让我们的组件酿成响应式的(这些属性用户可以在初始化的时候选择传入也可以不传)。

同时具有parent和childNodes来举行任意偏向上的查找。有了根节点之后,通过查找childNodes而且递归就能够构建出级联面板的template。节点的联动 handleCheck(isCheck, id, immediate = true/*是否立刻举行数据压缩 */) { const checkedLevel = this.checkedLevel; //勾选当前级别及子级 const selectNode = this.flattenData.find(item => item.id === id); if (!selectNode) { return; } //递归 //由父到子 function setCheck(node) { node.checked = isCheck; if (!node.childNodes.length && node.level < checkedLevel) { node.noChildChecked = isCheck; } if (!Array.isArray(node.childNodes) || !node.childNodes.length) { return; } node.childNodes.forEach(node => { setCheck(node); }); } //由子到父 function setParentCheck(parent) { if (!parent || !parent.parent) { return; } parent.checked = parent.childNodes.every(child => { return child.checked === true; }); setParentCheck(parent.parent); } setCheck(selectNode); setParentCheck(selectNode.parent); if (immediate) { this.getCheckedData(); } }节点的联动首先通过扁平化数据查找到当前节点。

再对该节点举行由父到子和由子到父两个偏向的checked设置。这里因为涉及到全选或者批量设置节点的勾选状态,所以有一个参数标志是否立刻挪用数据压缩的方法。

列的展开列的展开通过节点的select来触发,包罗勾选和点击事件。handleSelect(id) { //单选 const selectNode = this.flattenData.find(item => item.id === id); selectNode.parent.childNodes.forEach(node => (node.selected = false)); selectNode.selected = true; //下一级展示出来,更深的层级不渲染 if (selectNode.level < this.maxLevel) { this.curShowList[selectNode.level] = !!selectNode.childNodes.length; for (let i = selectNode.level + 1; i < this.maxLevel; i++) { this.curShowList[i] = false; } } //单选模式,逻辑变为类似级联选择器,选择非最深条理的节点直接清空当前节点下所有的checked效果,视为重新选择 if (this.isSingle && selectNode.level !== this.maxLevel) { this.flattenData.forEach(p => (p.checked = false)); this.getCheckedData(); } }列的展开通过控制curShowList数组,数组的每一项的true or false对应每一列的展开或者收起。这里分外提供一个isSingle的props可以把组件降级为级联选择器,满足只能单选的情况。

节点选择后的数据压缩 getCheckedData() { const result = []; const toZipData = this.flattenData.filter(p => p.level === this.zipLevel); function step(nodes) { if (!nodes || !nodes.length) { return; } const curSelectData = nodes.filter(p => p.checked || p.noChildChecked); const noSelectData = nodes.filter( p => !(p.checked || p.noChildChecked) ); result.push(...curSelectData); noSelectData.forEach(p => step(p.childNodes)); } step(toZipData); this.checkedData = result;}首先通过扁平化的数组过滤出目的压缩级此外数据,直接把其中选中的数据push到效果中,只把没有勾选的数据看成下一次递归历程的目的数据,递归出口是节点不存在或者没有子节点。方法 setCheckedNodes(keys) {//设置节点的选中,可用于搜索 /* public API */ keys.forEach(key => { this.setCheckedNode(key, false); }); this.getCheckedData(); }, getCheckedNodes(isZip = true) {//获取选中的数据 /* public API */ if (isZip) { return this.checkedData.map(item => { return { id: item.id, text: item.text, data: item.data, level: item.level }; }); } else { return this.flattenData.filter(p => p.checked || p.noChildChecked); } }扩展偏向组件需要支持懒加载,满足数据量大的情况。

组件没有提供插槽,例如右侧面板数据展示的定制化,左侧列的标题等。链接:https://juejin.im/post/5cbad2f751882532350bb1e1。


本文关键词:前端,基础,广告,系统,中级,联,面板,组件,制作,2020欧洲杯线上买球首页

本文来源:2020欧洲杯线上买球平台-www.rich30.com


400-888-8888