element ui踩坑
项目适配需要rem转换 ,但UI组件内部未转换
问题:由于组件内 ,某些组件宽度和高度是通过prop传参,然后对行内样式动态赋值,所以单位还是px
网上找的方法:
将element ui
的 github
源码拉下来,然后修改组件源码,然后打包,然后打补丁替换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 勾选回显
el-table-column
需要加上reserve-selection
el-table
需要加上:row-key="getRowKeys"
- 如果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"