您好,登錄后才能下訂單哦!
這篇文章主要介紹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 來實現整體組件布局
<template> <div class="desc" :> <!-- 標題 --> <h2 v-if="title" class="desc-title" v-html="title"></h2> <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>
<template> <el-col :span="computedSpan" class="desc-item"> <div class="desc-item-content" :class="size"> <label class="desc-item-label" : 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>暫無數據</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傳遞的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>
Vue是一款友好的、多用途且高性能的JavaScript框架,使用vue可以創建可維護性和可測試性更強的代碼庫,Vue允許可以將一個網頁分割成可復用的組件,每個組件都包含屬于自己的HTML、CSS、JavaScript,以用來渲染網頁中相應的地方,所以越來越多的前端開發者使用vue。
以上是“Vue Element UI自定義描述列表組件的示例分析”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。