资讯专栏INFORMATION COLUMN

如何实现一个这样的级联组件

daydream / 3758人阅读

摘要:封装组件系列文章如何实现一个这样的级联组件组件背景根据产品原型实现一个级联组件,下面看演示图应用场景很多,如后台管理系统,旅游系统,广告投放系统,营销系统等,现在流行,,三大框架,下面看看怎么使用实现实现逻辑产品经理的评审功能需求如下根据大

Vue封装组件系列文章

如何实现一个这样的级联组件

组件背景

根据产品原型实现一个级联组件,下面看演示图

应用场景很多,如:后台管理系统,旅游系统,广告投放系统,营销系统...等,现在流行VueReactAnagular 三大框架,下面看看怎么使用Vue实现
实现逻辑

产品经理的评审功能需求如下

根据大分类到子分类层级选择,无层级限制(根据UI的横板宽度,适合做多级,但深度很深的场景并不多)

每个层级支持全选,根据子级可以推导全选项选中,并对其父级执行选中操作

已选层级可显示出结果列表,可对其结果操作,并有快速清空结果功能

分类名称字数并不做限制,待选区域分类名称应在该项中居中显示,长度过长换行显示

结果选项结构简化,每项固定一行,过长在尾部出现...代表过长,鼠标移上时显示全部内容

思路

Vue.js 的核心包括一套“响应式系统”。

"响应式",开发思路跟Jquery的开发思路完全不同。

“响应式”,是指当数据改变后,Vue 会通知到使用该数据的代码。例如,视图渲染中使用了数据,数据改变后,视图也会自动更新。

根据地区数据 JSON 可以看出其结构

[
  {
    "value": "中国",
    "key": 1156,
    "id": 1156,
    "children": [
      {
        "value": "北京市",
        "id": 10000,
        "key": 10000,
        "children": []
      },
      {
        "value": "河北省",
        "key": 200107,
        "id": 200107,
        "children": [
          {
            "value": "石家庄",
            "key": 20010701,
            "id": 20010701
          },
          {
            "value": "唐山市",
            "key": 20010702,
            "id": 20010702,
            "children": [
               {
                  "value": "路南区",
                  "key": 2001070201,
                 "id": 2001070201,
                  "children": []
               }
            ]
          }
        ]
      }
    ]

中国

直辖市

xx省

xx市

xx区

xx市

xx县

待选数据组件

这是一个循环嵌套的数据对象,而组件嵌套似乎不能满足产品需求,如果使用数组来代替层级,似乎可以解决数据嵌套的问题

array => level 1 -> level 2 -> level 3 -> level 4

level 1 => current, children => level 2 (array)
level 2 => current, children => level 3 (array)
...

每个level 都是一个整体,
有标题 title
有全选 计算data中是否都选中 select
子集的集合数据 data
有当前选中 current
标记当期层级 数组的索引 level

首先定义个空的数组代表组件

const array = []

把数据处理成数组格式就能展开这个组件,那怎么处理数据呢
初始化组件时不是所有都显示,必须让用户选择当前一个顶级大类

拿到所有顶级大类,并构建第一个元素

title = 省级
data = 顶级大类
current = 空
level = 1
select = false

array.push({title, select, data, current, level})

在选择顶级大类时,给这个数组增加其一个子集元素

array.push({title, select, data, current, level})
...

依次类推

结果选择器

获取组件的选择结果,
可以过滤数据的check 属性得到,
可使用Vue的计算属性得知随时的结果

结果选择框可以直接绑定已选的计算组件,可构建结果UI

组件构想

主组件

布局组件

选择项

主组件 Selecter

用来负责组件框架, 左右分栏,
左边是选择区域, 右边是结果区域
这个是组件引用层,统一对外提供导入props 数据 和 导出的 emit 事件
组件需要做到完全配置化,内部所以参数需要被抽象

选择区

更具层级平均分配空间,所有在横向固定空间中,不能做过多的层级,太窄了没法显示
因为需要循环显示其层级,抽离层级为布局组件,布局组件由 标题滚动的选择区域 组成

结果区

在有选择时才显示,有标题栏显示,结果区可统计结果个数,选择项使用Tag标签,支持快速删除,建立纵向滚动条
可使用布局组件 与选择区保持风格统一,

布局组件 item

要兼容选择区与结果区使用,所以统计个数得有开关控制,
边框,颜色 UI 控制

抽象 清空按钮UI
抽象 统计个数UI

选择项 box(子组件)

最关键的组件就算这个了

逻辑 双向绑定

v-model 绑定数据的好处是: 数据在内部发生了改变,而在原始端同样改变了,只要使用就可以了,
当然在使用上也有些不方便的地方,
props导入的数据,通过什么props 属性接收呢, value

...
props: {
  value: {
    type: Array
  }
}
...

在组件内部是不能Set 改变的,只能通过事件传到父组件中来
通过什么方法名来传呢, input (初级很多人不知道)
this.$emit("input", val)

原始数据构建选择层级组件

在初始化过程中,构建第一层级组件的 title data current level
假使省市json 数据为 cityJson 构建第一层级的data

const data = this.cityJson.map(ret => {
  delete ret.children
  return ret
})

当用户选择层级的 item 时触发 动作新增层级数据
当用户选中层级的 item 时触发 动作新增层级数据 选中该层级下所有数据

全选 清空 删除 代码

贴上所有源代码,难免里面有些引用的文件,如果不能直接使用,请不要喷,因为这篇文章不是送个伸手党的,是你有一定的基础,想提升一下技能的你

主组件 Selecter


布局组件 item


选择项(子组件)box


优化体验

半选功能

在一个大分类的子分类里选择的分类,但是切到别的大类项,虽然结果框里有选择的分类,但是待选的框里还是不能显示子集,需求上线后,客户反应体验不好,所以就研究了复选框的 半选状态,其实改起来很简单,只要在计算属性的加个布尔值显示半选,布尔值就是该分类的data里是否有选中的项check = true

行内文本过长,换行显示优化
因为分类的字数没有限制,做前端其实不能相信用户,同时也不能相信后端返回给的数据,也不能相信产品,在产品没有碰到过字数限制的功能时候产生的问题时,都是期待着用户是个正常的用户的。

文本过长有两种方式解决:

在文本区域设置固定宽度,在超过长度显示... (如果要显示全,只能增加鼠标悬停显示功能了)

item 行的高度不使用line-height的参数,用padding 做上下间隔后,让文本自动换行 (这样的问题是,右手边图标的居中问题,字数太多就会加高item项,美观度没那么统一)

经验总结

很多前端新人都接触Vue一年、甚至两年多才会使用像element uiiviewvant开源的UI基础库,但细心的你可能发现,这些只适合参照原型图实现html编码,但业务的层次抽离、逻辑的复用、组件化业务层方面都没有手把手教我们上路。

三大流行框架的核心是快速地组件化开发,而我们只是简单的在路由组件页面堆积UI库的组件吗,显然这不是我们想要的高效开发。一个项目可以大到100多个页面,如果不抽离组件,重复工作量不可预估,效率更是谈不上了。那么如何像作者一样能更深层次使用Vue呢,其实element ui的开源库,每一个组件的实现其实都是很基础的方法实现的,假如你要实现这样的基础库,你就会想办法去看源代码,看着看着你就学会了作者的很多思想,那还会有什么的组件实现不了了?

师傅领进门,修行靠个人,人人都是我们的老师。不知你是否赞成...

以上,欢迎拍砖~

欢迎关注我的开源仓库
GITHUB:xiejunping (Cabber) · GitHub
微信二维码: 扫码添加好友,交个朋友

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/105745.html

相关文章

  • 从零开始实现一个Vue级联组件

    摘要:从零开始实现一个级联组件本文实现级联组件需要用到自定义指令和组件通信相关知识,最好先阅读以下两篇文章自定义指令组件基础与通信一组件简介本文实现的是一个省市县多级联动组件,当组件渲染完成后默认会加载出所有的省名称,当用户点击某个省的名称后,右 从零开始实现一个Vue级联组件 本文实现级联组件需要用到自定义指令和组件通信相关知识,最好先阅读以下两篇文章: Vue自定义指令 Vue组件基础与...

    binaryTree 评论0 收藏0
  • Mybatis N+1问题解析

    摘要:问题解析因为热爱,所以拼搏。如何解决问题本身给出解决方案,就是延迟加载。延迟加载延迟加载会解决上述的问题,也就是在个级联表的情况下,只加载需求的数据库表数据。在特定的关联中,使用属性覆盖该内容的功能。 Mybatis N+1问题解析 因为热爱,所以拼搏。 --RuiDer 前导必备 Mybatis 数据库 级联 N+1问题?? N+1问题来源于数据库中常见的...

    qqlcbb 评论0 收藏0
  • Python-SQLAlchemy:第4节:级联

    摘要:上一篇文章第节关系操作级联是在一对多关系中父表与子表进行联动操作的数据库术语。注意级联独立于本身针对外键的级联定义。代码执行后数据库表中的内容的变化表五年二班理想路号楼表理想男静安区女静安区小马哥女闸口区张三韩永跃男静安区 上一篇文章:Python-SQLAlchemy:第3节:关系操作 级联是在一对多关系中父表与子表进行联动操作的数据库术语。因为父表与子表通过外键关联,所以对父表或...

    henry14 评论0 收藏0
  • CSS优先级详解

    摘要:优先级是由选择器组成的匹配规则决定的。这些继承的样式的优先级永远低于元素本身的样式,包括通用选择器最终的颜色是红色的。永远都要优先考虑使用样式规则的优先级来解决问题而不是。 概念 浏览器是通过判断优先级,来决定到底哪些属性值是与元素最相关的,从而应用到该元素上。优先级是由选择器组成的匹配规则决定的。 如何计算? 优先级是根据由每种选择器类型构成的级联字串计算而成的. 它不是一个对...

    Juven 评论0 收藏0
  • CSS优先级详解

    摘要:优先级是由选择器组成的匹配规则决定的。这些继承的样式的优先级永远低于元素本身的样式,包括通用选择器最终的颜色是红色的。永远都要优先考虑使用样式规则的优先级来解决问题而不是。 概念 浏览器是通过判断优先级,来决定到底哪些属性值是与元素最相关的,从而应用到该元素上。优先级是由选择器组成的匹配规则决定的。 如何计算? 优先级是根据由每种选择器类型构成的级联字串计算而成的. 它不是一个对...

    n7then 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<