| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- <template>
- <div class="desc" :style="{ margin }">
- <!-- 标题 -->
- <h1 v-if="title" class="desc-title" v-html="title"></h1>
- <el-row class="desc-row" ref='elRow'>
- <slot />
- </el-row>
- </div>
- </template>
- <script>
- export default {
- name: 'EDesc',
- // 通过provide提供给子组件
- provide() {
- return {
- labelWidth: this.labelWidth,
- column: this.column,
- size: this.size
- }
- },
- props: {
- // 标题
- 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: ''
- }
- },
- data() {
- return {
- // 监听插槽变化
- observe: new MutationObserver(this.computedSpan)
- }
- },
- mounted() {
- this.$nextTick(() => {
- this.computedSpan()
- this.observe.observe(this.$refs.elRow.$el, { childList: true })
- })
- },
- methods: {
- computedSpan() {
- // 筛选出子组件e-desc-item(防御:slots 可能为 undefined)
- const slotNodes = (this.$slots && this.$slots.default) ? this.$slots.default : []
- if (!Array.isArray(slotNodes) || slotNodes.length === 0) {
- return
- }
- const dataList = []
- slotNodes.forEach(node => {
- if (
- node &&
- node.componentOptions &&
- node.componentOptions.tag === 'e-desc-item' &&
- node.componentInstance
- ) {
- dataList.push(node.componentInstance)
- }
- })
- // 若没有 e-desc-item,直接返回
- if (dataList.length === 0) return
- // 剩余span(确保为数字)
- let leftSpan = Number(this.column) || 1
- 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 = Number(this.column) || 1
- } else {
- leftSpan -= item.span || 1
- }
- })
- }
- },
- beforeDestroy() {
- if (this.observe) {
- this.observe.disconnect()
- }
- }
- }
- </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>
|