从资源库选择树组件封装

从资源库组件选择 可配置的资源选择器
a. 配置初始选中路径
b. 配置单选多选
c. 配置资源选择类型
d. 配置资源选择规则,如不可选同名资源,选了⽗禁⽤⼦,选了⽗关联⼦
e. 配置视图模式
组件使⽤
a. 引⼊组件PickResourceModal(有弹窗外壳,直接传⼊visible控制显隐)或者 PickResourcePage(没有弹窗外壳,外层不⼿动控制的话,弹窗直接加载显示)
b. 传⼊属性,属性分为两个部分, 1:配置属性 2.回调函数onOk和onCancel c. 配置属性分为两种情况:
1.有明确使⽤场景的
2.没有明确使⽤场景
d. 1.有明确使⽤场景的,提供属性uploadType和其他可变参数属性。
e. 针对uploadType的具体做法:在UploadType枚举中增加你的场景代号,⽐如现有的上传素材 UploadMaterial为1(传⼊属性就是 uploadType={UploadType.UploadMaterial})。在 usageWithOption中set当前场景的固定配置,⽐如是否可选⼀级⽂件夹,单选还是多选等。示 例:

export const usageWithOption = new Map() 
// 在默认配置的基础上,为使⽤场景设置固定的配置属性 
const UploadMaterialOption = cloneDeep(basePickResourceOptions) 
UploadMaterialOption.checkRules.canOnlyCheckParent = true 
UploadMaterialOption.checkRules.canCheckSameResource = false 
usageWithOption.set(UploadType.UploadMaterial, UploadMaterialOption)

a. 针对其他可变参数属性,⽐如初次打开组件默认选中路径,查看PickResourceProps使⽤对应的 属性名传⼊即可
b. 没有明确使⽤场景的,为其提供基本配置basePickResourceOptions,其他配置通过 pickResourceOptions传⼊,直接和basePickResourceOptions合并,新传⼊的属性覆盖基础属 性配置
调研
a. antd 树选择
antd的tree⽤的组件是RcTree
RcTree处理选择规则


image.png

image.png

b.也调⽤了⽆限层级的菜单实现,⼤部分案例使⽤的也是递归实现,资源库选择组件的实现基础也是递归


image.png

根据要实现的功能,我们需要存的数据如下(其他⼀些为了处理空⻚⾯或者选择⻚⾯就不展示了):

/** 树资源 */ 
resources: [], 
/** 当前屏⽹格模式下的资源(其实就是⾯包屑对应最后⼀层的资源) */ 
currentGridResources: [], 
/** 当前选中的item(就是当前激活的路径) */ 
activePaths: [],
 /** 当前选择的item */
 checkedResource: [], 
/** 当前因为⽗被选择⽽禁⽤的item */
 checkParentLinkDisabled: [], 
/** 还有资源本身带的disabled,是禁⽤了就不可再释放的标识, 在请求资源后,进⾏资源转换的时候就配在资源上了*/

组件的展示⽅案
a. 在列表模式,我们不知道实际上会展示到第⼏层资源,所以创建了⼀个递归组件


image.png

a. 在⽹格模式,我们当前屏展示始终是选中最后⼀层的数据,正常的视图组件,但是需要找出当前 最后⼀层数据
b. 最后⼀层数据由两个因素会影响,资源树(⽐如:新加载出来下⼀层)和当前激活的路径(⽐ 如:单击了⾯包屑或者选中了屏幕上某个资源)
c. 在model中找到updateResource和updateActivePath,在更新这两个数据的地⽅同时更新 currentGridResources即可
d. ⼤部分情况下,更新的currentGridResources就是下⼀层加载出来的资源,特殊情况有两个:
e. 1.单击⾯包屑 2.排序(每⼀层都可排序,只需要判断当前的排序是最后⼀层的排序再去改变 currentGridResources) f. 单击⾯包屑可能需要重新加载资源(不必特殊处理),也可能直接改变选中路径。如果直接改变 了选中路径,那么就需要根据选中路径在资源树中找到最后⼀层的资源
g. 这⾥只是找到资源,不需要改变树结构的数据,根据activePaths的深度,3层及其以内⽤⼴度优 先搜索,3层以上⽤深度优先搜索,搜到即⽌⼴度优先和深度优化搜索
深度优先


image.png

image.png

广度优先
image.png

image.png

这样做的好处是,如果我们最后⼀层选中的资源位于前⼏层,但⽐较深层的地⽅,就不⽤遍历后⼏层及其 ⼦节点。
如果我们选中的资源位于后⼏层,但⽐较浅层的地⽅,就不⽤遍历前⼏层⽐较深的⼦节点。但如果我们最 后⼀层选中的资源位于最后⼏层⼜⽐较深的资源,那么作⽤不⼤
组件的⼀些重点逻辑实现⽅案
a. 初始化资源
ⅰ. 根据配置拿到初始展示路径
ⅱ. 根据路径请求第⼀屏或第⼀和第⼆屏的资源
ⅲ. 转换资源,⽣成resources
b. 选中资源
ⅰ. 改变activePaths,选中资源数组
ⅱ. 判断下⼀层有没有数据,有资源直接更新⾯包屑即可,展示资源会根据activePaths改变
ⅲ. 下⼀层没有资源,加载完成后,把新加载的资源需要放进资源树resources ⅳ. 我们虽然能知道是哪⼀个⽗加载出来的新资源,但也需要在resources中找到这个⽗,把新资 源加到⽗的children中,也就是要改变树资源的数据,这⾥⽤的递归实现 递归好处是代码简洁易懂,坏处是有调⽤栈溢出的⻛险,但实际场景中我们的压栈次数并不会很多 ⽐如:


image.png

调⽤栈情况:
image.png

从压栈数量来看,只有 节点.children.length>0 && 节点在当前选中路径 的时候才会压栈,也就是只有⽤ 户选择展开⼀个节点后,在递归中这个节点才会压栈。 结合浏览器引擎可以⽀持调⽤的深度来看调⽤栈溢出的⻛险还是可控的
最后如果有关联选⼦,关联禁⽤⼦,根据规则处理禁⽤或关联选中的资源
c. 跳转⾯包屑
ⅰ. 判断单击的⾯包屑在树资源中有没有对应的数据
ⅱ. 有资源,说明加载过了,直接改变选中数组和⾯包屑,展示资源会根据activePaths改变
ⅲ. 没有资源,说明这层数据之前没有加载,那么从初始化数据开始
d. 选择资源
ⅰ. 拿到选择的资源和现有的checkedResource,根据配置:单选,多选,是否跨⽗来处理好新⼀ 轮的选中资源
ⅱ. 最后如果有关联选⼦,关联禁⽤⼦,根据规则处理禁⽤或关联选中的资源
e.取消选择资源
ⅰ. 先处理更新选中资源
ⅱ. 最后如果有关联选⼦,关联禁⽤⼦,根据规则处理禁⽤或关联选中的资源
f.根据规则处理禁⽤或关联选中的资源
ⅰ. 关联禁⽤或者关联选择分为两种情况,针对新加载出的⼀层资源进⾏处理,这种情况下,只 需要循环新加载出⼀层资源,该

放进禁⽤的放禁⽤,该放进选中资源的放进选中资源
ⅱ. 第⼆种情况,针对选择资源的孩⼦及孙⼦进⾏递归,根据规则,将选择资源或者取消选择资源 的孩⼦及孙⼦放进对应的禁
⽤资源或者选中资源即可
g.禁⽤重名资源
ⅰ. 根据已有的checkedResource,判断当前可⻅的资源是否属于同名同类型的资源,如果是就 禁⽤
在实现过程已经做了的优化:
1.之前choose和checked属性都是附着在资源本身身上,就是每个资源都带着⾃⼰的选择和选中以及禁 ⽤属性,这样,每次进⾏选择,选中以及处理规则连带的的时候都要去遍历所有节点。 现在把选中,选择,禁⽤都剥离和资源剥离开,只有需要改变树结构需要遍历全部节点,其他选择或 选中的时候都只需要遍历⼀层数据或者选择项的⼦及孙⼦
2.资源的展示使⽤了虚拟列表和虚拟⽹格
3.资源的选中选择状态存储在dom元素身上,避免再次进行状态判断
经过这些措施,⽬前展开多层,其中有2000⼀层的数据,整体性能还可以,没有明显卡顿
展示组件:

微信图片_20220117224210.jpg
微信图片_20220114172901.jpg
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,372评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,368评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,415评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,157评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,171评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,125评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,028评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,887评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,310评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,533评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,690评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,411评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,004评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,812评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,693评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,577评论 2 353

推荐阅读更多精彩内容