element ui踩坑

项目适配需要rem转换 ,但UI组件内部未转换

问题:由于组件内 ,某些组件宽度和高度是通过prop传参,然后对行内样式动态赋值,所以单位还是px
网上找的方法:
element uigithub源码拉下来,然后修改组件源码,然后打包,然后打补丁替换lib文件夹。

个人觉得太繁琐,问题在于,所有的组件都得适配,那不得所有的组件都得进行源码修改

思路:
1.将传参加上单位 rem
2.将组件改为按需引入,在注册之前改写,或者监听,将已赋值的行内样式,单位转为rem
main.js中引入

//主动引入后会将element ui 内部css转为rem
import "element-ui/lib/theme-chalk/index.css";

//rem转换
function pxToRem(_s, fontSize = 1920 / 20) {
  //匹配:20px或: 20px不区分大小写
  var reg = /(\:|: )+(\d)+(px)/gi;
  let newStr = _s.replace(reg, function (_x) {
    _x = _x.replace(/(\:|: )/, "").replace(/px/i, "");
    return ":" + parseFloat(_x) / fontSize + "rem";
  });
  return newStr;
}
// element组件
import { Table } from "element-ui";
// element组件
Vue.component("ElTable", {
  ...Table,
  watch: {
    ...Table.watch,
    bodyHeight: {
      immediate: true,
      handler(value) {
        //单位换算
        this.$nextTick(() => {
          let domContent = app.querySelectorAll("*[style]");
          Array.prototype.slice.call(domContent, 0);
          domContent.forEach((el) => {
            if (el.classList.value.includes("el-")) {
              let cloneDom = el.cloneNode();
              let style = pxToRem(cloneDom.getAttribute("style"));
              el.setAttribute("style", style);
            }
          });

          let col = app.querySelectorAll(".el-table *[width]");
          Array.prototype.slice.call(col, 0);
          col.forEach((el) => {
            let width = el.getAttribute("width");
            width = Number.parseFloat(width) / (1920 / 20);
            el.setAttribute("width", width);
          });
        });
        // 单位换算
      },
      deep: true,
    },
    data: {
      immediate: true,
      handler(value) {
        this.store.commit("setData", value);
        //单位换算
        this.$nextTick(() => {
          let domContent = app.querySelectorAll("*[style]");
          Array.prototype.slice.call(domContent, 0);
          domContent.forEach((el) => {
            if (el.classList.value.includes("el-")) {
              let cloneDom = el.cloneNode();
              let style = pxToRem(cloneDom.getAttribute("style"));
              el.setAttribute("style", style);
            }
          });

          let col = app.querySelectorAll(".el-table *[width]");
          Array.prototype.slice.call(col, 0);
          col.forEach((el) => {
            let width = el.getAttribute("width");
            width = Number.parseFloat(width) / (1920 / 20);
            el.setAttribute("width", width);
          });
        });
      },
    },
  },
});

form表单 动态重置表单项的值 未触发

 <el-form-item
                label="保障期限 : "
                prop="insurDeadline"
                ref="insurDeadlineRef"
              >
                <el-select v-model="formData.insurDeadline">
                  <el-option
                    :label="i.label"
                    :value="i.value"
                    v-for="i in insurDeadlineList"
                    :key="i.value"
                  ></el-option>
                </el-select>
              </el-form-item>
			  
    this.$refs.insurDeadlineRef.resetField();//重置该表单项

解决:因为 formData 初始时没有insurDeadline属性,所以在data(){}中声明时就要带上该属性,否则没有动态更新

el-table 插槽内 v-if未生效

v-if需要改为三元表达式,或者调用 this.$forceUpdate()强制刷新试一下

el-table 勾选回显

  1. el-table-column 需要加上 reserve-selection
  2. el-table 需要加上 :row-key="getRowKeys"
  3. 如果table放在弹框里,按照官网示例写的代码回显勾选 就会出现奇特的bug,第一次打开会回显勾选,第二次则不会,第三次又回显,以此类推;
    因为再次触发 this.$refs[ref].toggleRowSelection(item); 所以已勾选的话,再次触发会清除勾选

已修改好的代码:


  <el-table
                  :data="adminList"
                  :bordered="true"
                  @selection-change="adminSelectionChange"
                  ref="adminFableRef"
                  :row-key="getRowKeys"
                >
                  <el-table-column
                    type="selection"
                    reserve-selection
                    width="55"
                  >
                  </el-table-column>
</el-table>
 getRowKeys(row) {
      return row.id;
    },
 adminSelectionChange(val) {
      const result = val.reduce((item, next) => {
        typeof item.find((ele) => ele["id"] === next["id"]) === "undefined" &&
          item.push(next);
        return item;
      }, []);

      this.personForm.adminList = result;
    },
  //toggleSelection(rows) {
        //if (rows) {
          //rows.forEach(row => {
           // this.$refs.multipleTable.toggleRowSelection(row);
          //});
       // } else {
          //this.$refs.multipleTable.clearSelection();
        //}
      //},
//改为
  toggleSelection(rows) {
    this.$refs.multipleTable.clearSelection();
        if (rows) {
          rows.forEach(row => {
            this.$refs.multipleTable.toggleRowSelection(row,true); //true 为勾选
          });
        }
      },

el-table 跨页回显勾选
有分页数据之后再重新赋值一下 tableOptions.multipleSelection 才能更新勾选

 <el-table
  ...
    ref="elTable"
    @select="selectClick"
    :row-key="(row) => {return row.id}"

  data(){
    return {
      tableOptions:{
          multipleSelection:[],
	  tableData:[]
       }
    }
  }
   selectClick: (selection, row) => {
            const findItem = this.tableOptions.multipleSelection.find(
              (item) => item.id == row.id
            )
            if (findItem) {
              const filter = this.tableOptions.multipleSelection.filter(
                (item) => item.id !== row.id
              )
              this.tableOptions.multipleSelection = filter

              // 取消选中效果
              this.$refs.elTable.toggleRowSelection(
                findItem,
                false
              )
            } else {
              this.tableOptions.multipleSelection.push(row)
            }
          },

 rowSelection() {
      this.$nextTick(() => {
        this.tableOptions.multipleSelection.forEach((item) => {
          const findItem = this.tableOptions.tableData.find(
            (i) => i.id === item.id
          )
          findItem && this.$refs.elTable.toggleRowSelection(findItem, true)
        })
      })
    },
 watch: {
    'tableOptions.multipleSelection': {
      handler(newVal, oldVal) {
        if (newVal.length) {
          this.rowSelection()
        }
      }
    }
  },

element-puls 无限滚动组件 v-infinite-scroll 触底未触发

一定要写该属性

infinite-scroll-distance="1" 
posted @ 2023-09-27 11:18  混名汪小星  阅读(111)  评论(0编辑  收藏  举报