您的位置:首页技术文章
文章详情页

Vue Element UI自定义描述列表组件

【字号: 日期:2022-09-29 14:34:37浏览:2作者:猪猪

本文实例为大家分享了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来显示DOM3、利用 el-row 和 el-col 来实现整体组件布局

封装e-desc组件

<template> <div :style='{margin}'> <!-- 标题 --> <h1 v-if='title' v-html='title'></h1> <el-row class='desc-row'> <slot/> </el-row> </div></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'> <div :class='size'> <label : v-html='label'></label> <div 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> </div> </div> </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传递的spanreturn 24 / this.column * this.span } else { // 未传递span时,取columnreturn 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>参数说明

Vue Element UI自定义描述列表组件

至此,代码就写完啦,考虑不周或者有bug的地方,还望多多留言告知我哟

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持好吧啦网。

标签: Vue
相关文章: