vueelementui侧边栏(Vue Element UI自定义描述列表组件)
类别:编程学习 浏览量:2500
时间:2022-03-29 10:51:28 vueelementui侧边栏
Vue Element UI自定义描述列表组件本文实例为大家分享了Vue Element UI自定义描述列表组件的具体代码,供大家参考,具体内容如下
效果图
写在前面
写后台管理经常从列表点击查看详情,展示数据信息,Element UI虽然有表格组件,但是描述组件并没有,之前团队的成员遇到这种情况都自己去写样式,写起来也麻烦,而且每个人写出来的样式也不统一,破坏了项目的整体风格。
像是Ant Design UI就有描述组件,用起来特别舒服,所以索性自己结合Element UI的el-row和el-col自己写了一个。
实现哪些功能
1、每行的高度根据改行中某一列的最大高度自动撑开
2、列宽度自动补全,避免最后一列出现残缺的情况
3、支持纯文本与HTML插槽
4、支持每行几列的设置
5、支持每列宽度自定义
6、支持动态数据重绘
组件设计
1、使用父子组件嵌套实现,父组件为 e-desc, 子组件为 e-desc-item 。
2、e-desc-item传递props的label 和 插槽的value,使用 $slots.content来显示DOM
3、利用 el-row 和 el-col 来实现整体组件布局
封装e-desc组件
<template> <li class="desc" :style="{margin}"> <!-- 标题 --> <h1 v-if="title" class="desc-title" v-html="title"></h1> <el-row class="desc-row"> <slot/> </el-row> </li> </template> <script> export default { name: 'EDesc', // 通过provide提供给子组件 provide () { return { labelWidth: this.labelWidth, column: this.column, size: this.size } }, props: { // 数据源,监听数据重绘 data: { type: Object, required: true, default () { return {} } }, // 标题 title: { type: String, default: '' }, // 边距 margin: { type: String, default: '0' }, // label宽度 labelWidth: { type: String, default: '120px' }, column: { // 每行显示的项目个数 type: [Number, String], default: 3 }, size: { // 大小 type: String, default: '' } }, watch: { data: { handler () { this.$nextTick(() => { // 筛选出子组件e-desc-item const dataSource = this.$slots.default const dataList = [] dataSource.forEach(item => { if (item.componentOptions && item.componentOptions.tag === 'e-desc-item') { dataList.push(item.componentInstance) } }) // 剩余span let leftSpan = this.column const len = dataList.length dataList.forEach((item, index) => { // 处理column与span之间的关系 // 剩余的列数小于设置的span数 const hasLeft = leftSpan <= (item.span || 1) // 当前列的下一列大于了剩余span const nextColumnSpan = (index < (len - 1)) && (dataList[index + 1].span >= leftSpan) // 是最后一行的最后一列 const isLast = index === (len - 1) if (hasLeft || nextColumnSpan || isLast) { // 满足以上条件,需要自动补全span,避免最后一列出现残缺的情况 item.selfSpan = leftSpan leftSpan = this.column } else { leftSpan -= item.span || 1 } }) }) }, deep: true, immediate: true } } } </script> <style scoped lang="scss"> .desc{ .desc-title { margin-bottom: 10px; color: #333; font-weight: 700; font-size: 16px; line-height: 1.5715; } .desc-row{ display: flex; flex-wrap: wrap; border-radius: 2px; border: 1px solid #EBEEF5; border-bottom: 0; border-right: 0; width: 100%; } } </style>
封装e-desc-item组件
<template> <el-col :span="computedSpan" class="desc-item"> <li class="desc-item-content" :class="size"> <label class="desc-item-label" :style="{width: labelWidth}" v-html="label"></label> <li class="desc-item-value" v-if="$slots"> <!-- 纯文本 --> <slot v-if="$slots.default && $slots.default[0].text"/> <!-- HTML --> <slot name="content" v-else-if="$slots.content"/> <span v-else>暂无数据</span> </li> </li> </el-col> </template> <script> export default { name: 'EDescItem', inject: ['labelWidth', 'column', 'size'], props: { span: { type: [Number, String], required: false, default: 0 }, label: { type: String, required: false, default: '' } }, data () { return { // 子组件自己的span selfSpan: 0 } }, computed: { computedSpan () { // 子组件自己的span,用于父组件计算修改span if (this.selfSpan) { return 24 / this.column * this.selfSpan } else if (this.span) { // props传递的span return 24 / this.column * this.span } else { // 未传递span时,取column return 24 / this.column } } } } </script> <style scoped lang="scss"> .desc-item { border-right: 1px solid #EBEEF5; border-bottom: 1px solid #EBEEF5; .desc-item-content { display: flex; justify-content: flex-start; align-items: center; color: rgba(0,0,0,.65); font-size: 14px; line-height: 1.5; width: 100%; background-color: #fafafa; height: 100%; .desc-item-label{ border-right: 1px solid #EBEEF5; display: inline-block; padding: 12px 16px; flex-grow: 0; flex-shrink: 0; color: rgba(0, 0, 0, 0.6); font-weight: 400; font-size: 14px; line-height: 1.5; height: 100%; display: flex; align-items: center; } .desc-item-value{ background: #fff; padding: 12px 16px; flex-grow: 1; overflow: hidden; word-break: break-all; height: 100%; display: flex; align-items: center; color: #444; span{ color: #aaa; } } &.small { .desc-item-label, .desc-item-value { padding: 10px 14px; } } } } </style>
使用方式
<template> <e-desc :data='info' margin='0 12px' label-width='100px'> <e-desc-item label="姓名">{{info.name}}</e-desc-item> <e-desc-item label="年龄">{{ info.age }}岁</e-desc-item> <e-desc-item label="性别">{{ info.sex }}</e-desc-item> <e-desc-item label="学校">{{ info.school }}</e-desc-item> <e-desc-item label="专业">{{ info.major }}</e-desc-item> <e-desc-item label="爱好">{{ info.hobby }}</e-desc-item> <e-desc-item label="手机号">{{ info.phone }}</e-desc-item> <e-desc-item label="微信">{{ info.wx }}</e-desc-item> <e-desc-item label="QQ">{{ info.qq }}</e-desc-item> <e-desc-item label="住址">{{ info.address }}</e-desc-item> <e-desc-item label="自我描述" :span='2'>{{ info.intro }}</e-desc-item> <e-desc-item label="操作" :span='3'> <template slot="content"> <el-button size="small" type="primary">修改</el-button> <el-button size="small" type="danger">删除</el-button> </template> </e-desc-item> </e-desc> </template> <script> import EDesc from './e-desc' import EDescItem from './e-desc-item' export default { components: { EDesc, EDescItem }, data () { return { info: { name: 'Jerry', age: 26, sex: '男', school: '四川大学', major: '码农专业', address: '四川省成都市', hobby: '搬砖、前端、赚钱', phone: 18888888888, wx: 'Nice2cu_Hu', qq: 332983810, intro: '我是一个粉刷匠,粉刷本领强。我要把那新房子,刷得更漂亮。刷了房顶又刷墙,刷子飞舞忙。哎呀我的小鼻子,变呀变了样。我是一个粉刷匠,粉刷本领强。我要把那新房子,刷得更漂亮。刷了房顶又刷墙,刷子飞舞忙。哎呀我的小鼻子,变呀变了样。' } } } } </script>
参数说明
至此,代码就写完啦,考虑不周或者有bug的地方,还望多多留言告知我哟
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持开心学习网。
您可能感兴趣
- springboot vue 异地登录(vue+springboot实现登录验证码)
- vue实现列表向上滚动更新(vue实现列表无缝滚动)
- vue走马灯特效(Javascript结合Vue实现对任意迷宫图片的自动寻路)
- vue如何excel表格上传功能(Vue + iView实现Excel上传功能的完整代码)
- vue怎么实现拖动(Vue拖动截图功能的简单实现方法)
- vue改数组和对象值(vue $set 实现给数组集合对象赋值)
- vue中的指令及用法(详解Vue进阶构造属性)
- vue界面自动生成(Vue中实现3D标签云的详细代码)
- vuejs filter过滤器的使用(Vue过滤器filter实现及应用场景详解)
- vue的弹框怎么用(vue自定义弹框效果确认框、提示框)
- vue监控对象变化(Vue之监听方法案例详解)
- vue编程加入购物车(vuex实现简单的购物车功能)
- vue前端搜索功能如何实现(使用Vue3+Vant组件实现App搜索历史记录功能示例代码)
- vue通过什么获取dom(vue异步更新dom的实现浅析)
- vue是怎样进行页面跳转(Vue实现登陆跳转)
- vuekeep-alive源码(vue中keepAlive组件的作用和使用方法详解)
- 刚红就耍大牌,《琉璃》角色滤镜碎一地,心疼工作人员(琉璃角色滤镜碎一地)
- 袁冰妍郑业成这对可以处,有脸红情话他们是真的敢说(袁冰妍郑业成这对可以处)
- 《祝卿好》台词又土又甜,就喜欢这么直接的恋爱(祝卿好台词又土又甜)
- 大女主 汤唯垂青电视圈,搭档朱亚文出演《大明皇妃孙若微传》(汤唯垂青电视圈)
- 红色代表什么(红色代表什么情感和含义)
- 高中数学题(高中数学题型总结及解题方法)
热门推荐
- 好用又便宜的云主机(如何购买真正的云主机)
- dedecms关键词限制(dedecms tag标签伪静态的修改方法)
- js编写简单网页计算器(js实现网页计算器)
- sql server 共享锁
- nginx-rtmp-module 配置(Nginx搭建rtmp直播服务器实现代码)
- web服务器搭建自己的网站(单台web服务器如何尽可能的提高网站性能)
- php语法检测方法(php中文语义分析实现方法示例)
- 网络虚拟机系统安装教程(NPOINT免费虚拟主机管理系统windows2003的安装方法)
- 使用canvas画个正方形(canvas小画板之平滑曲线的实现)
- 如何替换html5视频播放器(HTML5自定义视频播放器源码)
排行榜
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9