Element-UI使用及遇到的问题

1. el-tooltip 超出宽度显示文字提示,否则隐藏

<!-- 第一种方法 -->
<template>
  <div class="menu-item-container">
    <el-tooltip :content="contentHover" placement="right" :disabled="isShowTooltip">
      <p class="title-container" @mouseover="onMouseOver(title)">
        <span class="menu-title" :ref="title">{{ title }}</span>
      </p>
    </el-tooltip>
  </div>
</template>

<script>
  export default {
    name: 'MenuItem',
    props: {
      title: String
    },
    data() {
      return {
        isShowTooltip: false,
        contentHover: ''
      };
    },
    methods: {
      /**
       * 鼠标移入事件
       * @param {title} ref 的 title 值
       */
      onMouseOver(title) {
        const el = this.$refs[title];
        const parentWidth = el.parentNode.offsetWidth; // 获取元素父级可视宽度
        const contentWidth = el.offsetWidth; // 获取元素可视宽度
        this.isShowTooltip = contentWidth <= parentWidth; 
        // 鼠标悬停后显示的内容
        this.contentHover = title;
      }
    }
  }
</script>

<style scoped>
  .title-container {
    overflow: hidden;
    width: 100%;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
</style>
<!-- 第二种方法 解决 el-autocomplete中 搜索列表 tooltip进入下一项闪烁问题 -->
<template>
  <el-autocomplete class="inline-input" placeholder="搜索">
    <template slot-scope="{ item }">
      <el-tooltip :content="item.title" placement="right" :disabled="isShowTooltip">
        <p class="ellispis" @mouseover="onMouseOver($event)">{{ item.title }}</p>
      </el-tooltip>
    </template>
  </div>
</template>

<script>
  export default {
    data() {
      return {
        isShowTooltip: true,
        contentHover: ''
      };
    },
    methods: {
      // 鼠标移入事件
      onMouseOver(e) {
        const el = e.target;
        // scrollWidth: 对象的实际内容的宽度,不包括边线宽度,会随对象中内容超过可视区后而变大
        // offsetWidth: 对象整体的实际宽度,包括滚动条等边线,会随对象显示大小的变化而改变
        this.isShowTooltip = el.scrollWidth <= el.offsetWidth; 
      }
    }
  }
</script>

<style lang="less">
  .ellispis {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .el-tooltip__popper {
    top: -100px; // 解决 tooltip与非tooltip来回切换,左上角会闪现tooltip弹框
  }
</style>

2. 使用阿里乾坤等微前端嵌入Element-UI弹出框页面时

2.1 改变Popover 弹出框样式在微前端中不生效

原因:Popover默认是插入到body元素上的,此时得修改成插入到父级元素中

<template>
  <el-popover
    :append-to-body="false"
    placement="bottom"
    width="200"
    trigger="click"
    :popper-options="popperOptions"
  >
    <el-button ref="popRef" slot="reference">click 激活</el-button>
    <p>内容</p>
  </el-popover>
</template>

当插入到父元素后悔发现原本的弹框边界悔自动变换位置的特性失效了

解决办法:设置popper-options中的boundariesElement为边界判定的HTMLElement元素

<script>
export default {
  data() {
    return {
      popperOptions: {
        boundariesElement: 'body',
        gpuAcceleration: false
      }
    }
  },
  mounted() {
    // 这里尝试后发现 第一个 offsetParent 值必须为边界容器,否则不生效,具体原因不清楚,欢迎大佬解答
    this.popperOptions.boundariesElement = this.$refs.moreImg.offsetParent
  }
}
</script>

2.2 当把el-dialog中的modal-append-to-bodyappend-to-body都设为false时,关闭弹框时,遮罩层挡住问题

解决办法:控制v-modalhidden属性来显示隐藏遮罩层

<template>
  <div ref="dialogContainer">
    <el-dialog
      :visible.sync="dialog.visible"
      width="30%"
      :modal-append-to-body="false"
      :append-to-body="false"
      @open="haddleDia(true)"
      @close="haddleDia(false)"
    ></el-dialog>
  </div>
</template>

<script>
export default {
  data() {
    return {
      dialog: {
        visible: false
      }
    }
  },
  methods: {
    haddleDia(bool) {
      this.dialog.visible = bool
      this.$refs.dialogContainer.lastChild.hidden = !bool
    }
  }
}
</script>

3. el-table相关问题

3.1 自定义expand展开收缩

<template>
  <el-table ref="table" :data="tableData">
    <template v-for="(header, i) in headerList">
      <el-table-column
        :key="i"
        :prop="header.prop"
        :label="header.label"
        :width="header.width || 'auto'"
      />
    </template>
    <el-table-column label="操作" width="120">
      <template slot-scope="scope">
        <p class="btn" @click="toogleExpand(scope.row)">查看详情</p>
      </template>
    </el-table-column>
    <el-table-column type="expand" width="1">
      <template slot-scope="props">
        详情内容
      </template>
    </el-table-column>
  </el-table>
</template>

<script>
export default {
  data() {
    return {
      headerList: [
        { prop: 'name', label: '姓名' },
        { prop: 'time', label: '时间' }
      ]
    }
  },
  methods: {
    toogleExpand(row) {
      this.$refs.table.toggleRowExpansion(row)
    }
  }
}
</script>

3.2 自定义filter筛选图标和内容

<template>
  <el-table ref="table" :data="tableData">
    <el-table-column width="108">
      <template slot="header">
        <el-popover placement="bottom-start" trigger="click">
          <p slot="reference">
            <span>分类</span>
            <img src="">
          </p>
        </el-popover>
      </template>
      <template slot-scope="scope">
        <p>表格body内容</p>
      </template>
    </el-table-column>
  </el-table>
</template>

<style lang="scss">
  .el-table {
    .el-table__header-wrapper {
      overflow: initial;
      thead {
        th.el-table__cell,
        .cell {
          overflow: initial;
        }
      }
    }
  }
</style>

3.3. el-date-picker设置时间跨度

<template>
  <el-date-picker
    v-model="timeRange"
    type="daterange"
    start-placeholder="开始日期"
    end-placeholder="结束日期"
    value-format="yyyy-MM-dd"
    :picker-options="pickerOptions"
  ></el-date-picker>
</template>

<script>
export default {
  data() {
    return {
      timeRange: '',
      timeOptionRange: '',
      pickerOptions: {
        disabledDate: (time) => {
          // 选择时间不能小于当天
          if (time.getTime() < Date.now() - 8.64e7) {
            return true;
          }

          // 最长跨度为 180 天
          const maxNum = 60 * 60 * 24 * 1000 * 179;
          // 最短为 2 天
          const minNum = 60 * 60 * 24 * 1000 * 2

          if (this.timeOptionRange) {
            const maxLongTime = this.timeOptionRange + maxNum
            const minLongTime = this.timeOptionRange - maxNum

            const maxShortTime = this.timeOptionRange + minNum
            const minShortTime = this.timeOptionRange - minNum

            return (time.getTime() > maxLongTime || time.getTime() < minLongTime) || (time.getTime() > minShortTime && time.getTime() < maxShortTime);
          }
        },
        onPick: ({ minDate, maxDate }) => {
          // 当第一时间选中才设置禁用
          if (minDate && !maxDate) {
            this.timeOptionRange = minDate.getTime();
          }
          if (maxDate) {
            this.timeOptionRange = null;
          }
        }
      }
    }
  }
}
</script>

3.4 el-treeel-select结合实现树状多选

3.4.1 代码
3.4.2 效果图:

3.5 el-table动态行合并

<template>
  <el-table 
    :data="tableData" 
    border
    :span-method="objectSpanMethod"
  >
    <template v-for="header in headerList">
      <el-table-column
        :key="header.prop"
        :prop="header.prop"
        :label="header.label"
        :width="header.width || 'auto'"
      />
    </template>
  </el-table>
</template>

<script>
export default {
  data() {
    return {
      headerList: [],
      tableData: [],
      merges: {},
      mcIndexs: [0, 1, 2] // 要合并的列
    }
  },
  created() {
    this.headerList = this.initHeaderList()
    this.tableData = this.initTableData()
    this.getMerges(this.tableData)
  },
  methods: {
    initHeaderList() {
      return [
        { label: '日期', prop: 'date', width: 180 },
        { label: '姓名', prop: 'name', width: 180 },
        { label: '地址', prop: 'address', width: 220 }
      ]
    },
    initTableData() {
      return [
        { date: '2016-05-02', name: '王小虎', address: '上海市普陀区金沙江路 1518 弄' }, 
        { date: '2016-05-02', name: '王小虎', address: '上海市普陀区金沙江路 1517 弄' }, 
        { date: '2016-05-03', name: '王小虎', address: '上海市普陀区金沙江路 1519 弄' }, 
        { date: '2016-05-03', name: '高启强', address: '上海市普陀区金沙江路 1519 弄' }
      ]
    },
    // 单元格合并
    objectSpanMethod({ row, rowIndex, columnIndex }) {
      return this.merges[`${rowIndex}_${columnIndex}`]
    },
    getMerges(tableData) {
      this.merges = {}

      const pathvNum = {}
      tableData.forEach((row) => {
        this.mcIndexs.forEach(columnIndex => {
          const pathV = this.getPathV(row, columnIndex)
          pathvNum[pathV] = pathvNum[pathV] ? pathvNum[pathV] + 1 : 1
        })
      })

      const merged = {}
      tableData.forEach((row, rowIndex) => {
        this.mcIndexs.forEach(columnIndex => {
          const pathV = this.getPathV(row, columnIndex)
          if (!merged[pathV]) {
            if (!this.merges[`${rowIndex}_${columnIndex}`]) {
              this.merges[`${rowIndex}_${columnIndex}`] = [pathvNum[pathV], 1]
            }
            merged[pathV] = true
          } else {
            this.merges[`${rowIndex}_${columnIndex}`] = [0, 0]
          }
        })
      })

      console.log(this.merges);
    },
    // 获取某一行从第一列值到columnIndex列值的和
    getPathV(row, columnIndex) {
      const vs = []
      for (let i = 0; i <= columnIndex; i++) {
        const column = this.headerList[i]
        vs.push(row[column.prop])
      }
      return vs.join('->')
    }
  }
}
</script>
3.5.2 效果图

3.6 el-table表格列宽随内容自适应

3.6.1 代码
<script>
export default {
  created() {
    this.headerList.forEach(c => {
      c.width = this.flexTableWidth(c, this.tableData)
    })
  },
  methods: {
    // 获取某一行从第一列值到columnIndex列值的和
    getPathV(row, columnIndex) {
      const vs = []
      for (let i = 0; i <= columnIndex; i++) {
        const column = this.headerList[i]
        vs.push(row[column.prop])
      }
      return vs.join('->')
    },
    /**
     * @param { Object } c 表头项
     * @param { Array } tableData 表格数据
     * @param { Number } maxWidth 单列最大宽度
     */
    flexTableWidth(c, tableData, maxWidth) {
      // 获取该列中最长的内容
      let index = 0
      let columnContent = '' // 占位最宽的内容
      const canvas = document.createElement('canvas')
      const context = canvas.getContext('2d')
      context.font = '14px'
      tableData.forEach((v, i) => {
        if (v[c.prop] === null) return

        const curr_temp = v[c.prop] + ''
        const max_temp = tableData[index][c.prop] + ''
        const curr_temp_w = context.measureText(curr_temp).width
        const max_temp_w = context.measureText(max_temp).width
        if (curr_temp_w > max_temp_w) {
          index = i
        }
      })
      columnContent = tableData[index][c.prop] + ''
      // 小于表头宽度时,取表头宽度
      const title_w = context.measureText(c.label).width
      const column_w = context.measureText(columnContent).width

      if (maxWidth && column_w > maxWidth) {
        return maxWidth
      }
      if (column_w < title_w && c.label !== '') {
        columnContent = c.label
      }
      return context.measureText(columnContent).width + 20
    }
  }
}
</script>
3.6.2 参考文献

Element UI实现表格列宽随内容自适应

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,392评论 5 470
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,258评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,417评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,992评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,930评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,199评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,652评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,327评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,463评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,382评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,432评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,118评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,704评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,787评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,999评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,476评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,057评论 2 341

推荐阅读更多精彩内容