Vue Element UI自定義描述列表組件
本文實(shí)例為大家分享了Vue Element UI自定義描述列表組件的具體代碼,供大家參考,具體內(nèi)容如下
效果圖

寫(xiě)在前面
寫(xiě)后臺(tái)管理經(jīng)常從列表點(diǎn)擊查看詳情,展示數(shù)據(jù)信息,Element UI雖然有表格組件,但是描述組件并沒(méi)有,之前團(tuán)隊(duì)的成員遇到這種情況都自己去寫(xiě)樣式,寫(xiě)起來(lái)也麻煩,而且每個(gè)人寫(xiě)出來(lái)的樣式也不統(tǒng)一,破壞了項(xiàng)目的整體風(fēng)格。
像是Ant Design UI就有描述組件,用起來(lái)特別舒服,所以索性自己結(jié)合Element UI的el-row和el-col自己寫(xiě)了一個(gè)。
實(shí)現(xiàn)哪些功能
1、每行的高度根據(jù)改行中某一列的最大高度自動(dòng)撐開(kāi)
2、列寬度自動(dòng)補(bǔ)全,避免最后一列出現(xiàn)殘缺的情況
3、支持純文本與HTML插槽
4、支持每行幾列的設(shè)置
5、支持每列寬度自定義
6、支持動(dòng)態(tài)數(shù)據(jù)重繪
組件設(shè)計(jì)
1、使用父子組件嵌套實(shí)現(xiàn),父組件為 e-desc, 子組件為 e-desc-item 。
2、e-desc-item傳遞props的label 和 插槽的value,使用 $slots.content來(lái)顯示DOM
3、利用 el-row 和 el-col 來(lái)實(shí)現(xiàn)整體組件布局
封裝e-desc組件
<template>
<div class="desc" :style="{margin}">
<!-- 標(biāo)題 -->
<h1 v-if="title" class="desc-title" v-html="title"></h1>
<el-row class="desc-row">
<slot/>
</el-row>
</div>
</template>
<script>
export default {
name: 'EDesc',
// 通過(guò)provide提供給子組件
provide () {
return {
labelWidth: this.labelWidth,
column: this.column,
size: this.size
}
},
props: {
// 數(shù)據(jù)源,監(jiān)聽(tīng)數(shù)據(jù)重繪
data: {
type: Object,
required: true,
default () {
return {}
}
},
// 標(biāo)題
title: {
type: String,
default: ''
},
// 邊距
margin: {
type: String,
default: '0'
},
// label寬度
labelWidth: {
type: String,
default: '120px'
},
column: {
// 每行顯示的項(xiàng)目個(gè)數(shù)
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之間的關(guān)系
// 剩余的列數(shù)小于設(shè)置的span數(shù)
const hasLeft = leftSpan <= (item.span || 1)
// 當(dāng)前列的下一列大于了剩余span
const nextColumnSpan = (index < (len - 1)) && (dataList[index + 1].span >= leftSpan)
// 是最后一行的最后一列
const isLast = index === (len - 1)
if (hasLeft || nextColumnSpan || isLast) {
// 滿足以上條件,需要自動(dòng)補(bǔ)全span,避免最后一列出現(xiàn)殘缺的情況
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="desc-item-content" :class="size">
<label class="desc-item-label" :style="{width: labelWidth}" v-html="label"></label>
<div 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>暫無(wú)數(shù)據(jù)</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,用于父組件計(jì)算修改span
if (this.selfSpan) {
return 24 / this.column * this.selfSpan
} else if (this.span) {
// props傳遞的span
return 24 / this.column * this.span
} else {
// 未傳遞span時(shí),取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="學(xué)校">{{ info.school }}</e-desc-item>
<e-desc-item label="專業(yè)">{{ info.major }}</e-desc-item>
<e-desc-item label="愛(ài)好">{{ info.hobby }}</e-desc-item>
<e-desc-item label="手機(jī)號(hào)">{{ 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: '四川大學(xué)',
major: '碼農(nóng)專業(yè)',
address: '四川省成都市',
hobby: '搬磚、前端、賺錢',
phone: 18888888888,
wx: 'Nice2cu_Hu',
qq: 332983810,
intro: '我是一個(gè)粉刷匠,粉刷本領(lǐng)強(qiáng)。我要把那新房子,刷得更漂亮。刷了房頂又刷墻,刷子飛舞忙。哎呀我的小鼻子,變呀變了樣。我是一個(gè)粉刷匠,粉刷本領(lǐng)強(qiáng)。我要把那新房子,刷得更漂亮。刷了房頂又刷墻,刷子飛舞忙。哎呀我的小鼻子,變呀變了樣。'
}
}
}
}
</script>
參數(shù)說(shuō)明

至此,代碼就寫(xiě)完啦,考慮不周或者有bug的地方,還望多多留言告知我喲
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
前端Vue3實(shí)現(xiàn)圖片標(biāo)點(diǎn)兩種方式總結(jié)
這篇文章主要介紹了如何使用Vue3和Ant?Design?Vue4.x實(shí)現(xiàn)圖像標(biāo)點(diǎn)和質(zhì)量檢測(cè)功能,文章詳細(xì)描述了兩種方式,每種方式都包括前端顯示代碼、配置基本數(shù)據(jù)、繪制圓點(diǎn)和序號(hào)以及處理圖片點(diǎn)擊的步驟,需要的朋友可以參考下2024-11-11
vue使用Sass時(shí)報(bào)錯(cuò)問(wèn)題的解決方法
這篇文章主要介紹了vue使用Sass時(shí)報(bào)錯(cuò)問(wèn)題的解決方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-10-10
Vite配置路徑別名的簡(jiǎn)單實(shí)現(xiàn)方法
Vite項(xiàng)目中我們可以手動(dòng)將src路徑設(shè)置**@**路徑別名,可以省下很多引入路徑的冗余路徑,下面這篇文章主要給大家介紹了關(guān)于Vite配置路徑別名的簡(jiǎn)單實(shí)現(xiàn)方法,需要的朋友可以參考下2023-04-04
vue在使用element組件出現(xiàn)<el-input>標(biāo)簽無(wú)法輸入的問(wèn)題
這篇文章主要介紹了vue在使用element組件出現(xiàn)<el-input>標(biāo)簽無(wú)法輸入的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04
vue中使用scrollTo沒(méi)有效果的完美解決方法
這篇文章主要介紹了在vue中使用scrollTo沒(méi)有效果的解決方法,本文給大家分享具體操作步驟,在這里需要注意scrollTo要作用在可滾動(dòng)的元素上,不然不生效,scrollTop就會(huì)一直為0,需要的朋友可以參考下2023-10-10

