因为项目需求,需要在表格中双击某一列的值时,那一列变成可编辑的状态,elementui里面表格满足不了需求,只能手写
<template>
<div class="table_container">
<div class="header">
<div :style="{ 'width': getScaleByUI(40) + 'px' }" v-if="serialNumber">序号</div>
<div v-for="(item, index) in header" :key="index" :style="{ 'width': getScaleByUI(item.width) + 'px' }">
{{ item.label }}
</div>
</div>
<div class="body">
<div class="body_item" v-for="(items, indexs) in tableData" :key="indexs"
:style="{ backgroundColor: indexs % 2 == 0 ? '' : '#303135' }">
<div :style="{ 'width': getScaleByUI(40) + 'px' }" v-if="serialNumber">{{ indexs + 1 }}</div>
<div v-for="(item, index) in header" :key="index" :style="{ 'width': getScaleByUI(item.width) + 'px' }">
<el-tooltip v-if="!item.isOperation" class="box-item" effect="light" :content="items[item.prop]"
placement="top-start">
<div class="ellipsis font" v-if="!item.canDouble">{{ items[item.prop]
}}</div>
<el-input style="width: 100%;height: 100%;" :readonly="readonly" @dblclick="change(item)"
v-model="items[item.prop]" class="w-50 m-2" size="large" @change="changeName(item, items)" @blur="blur(item)" />
</el-tooltip>
<div v-if="item.isOperation" style="width: 100%;display: flex;"
:style="{ 'justify-content': item.operation.length == 1 ? 'center' : 'space-between' }">
<div v-for="(i, n) in item.operation" :key="n" :style="{ 'color': i.color }" style="cursor: pointer"
@click="i.buttonClick(items, indexs)">{{ i.label }}</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup lang='ts'>
import { getScaleByUI } from "@/utils/tools.ts";
import { ref } from "vue";
interface props {
header: any,
tableData: any,
serialNumber:boolean //是否显示序号
}
defineProps<props>();
const emit = defineEmits(['onChange'])
const readonly = ref(true);
const change = (item: any) => {
if (item.canDouble) {
readonly.value = false
}
}
const changeName = (item: any,items:any) => {
if (item.canDouble) {
readonly.value = true;
emit('onChange',items);
}
}
const blur = (item: any) => {
if (item.canDouble) {
readonly.value = true;
}
};
</script>
<style scoped lang='scss'>
.table_container {
width: 100%;
.header {
width: 100%;
height: 30px;
background: #303135;
font-size: 12px;
font-family: Alibaba PuHuiTi, Alibaba PuHuiTi;
font-weight: 400;
color: #E5E5E5;
line-height: 30px;
text-align: center;
display: flex;
}
.body {
width: 100%;
.body_item {
width: 100%;
height: 30px;
display: flex;
text-align: center;
font-size: 12px;
font-family: Alibaba PuHuiTi, Alibaba PuHuiTi;
font-weight: 400;
color: #E5E5E5;
line-height: 30px;
.font {
padding: 0 6px;
}
::v-deep(.el-input__wrapper) {
background-color: transparent !important;
box-shadow:none;
}
::v-deep(.el-input__inner) {
width: 100%;
height: 100%;
color: #E5E5E5;
text-align: center;
font-size: 12px;
}
}
}
}</style>
其中的getScaleByUI
是用来做自适应的
// 获取当前屏幕大小与1920的比列,计算大小
export const getScaleByUI = (size:number) =>{
const scale = document.documentElement.clientWidth / 1920;
return size * scale;
}
父组件使用方式
<myTable :serialNumber="true" :header="watchhouseHeader" :tableData="watchhouseTableData" @onChange="change"></myTa
const change = (item: any) => {
console.log(item, "item");
}
const detailsRow = (row: any, index: number) => {
console.log(row, index);
}
const watchhouseHeader = ref([{
label: "名称",
prop: "name",
width: 100,
canDouble: true, //该项是否可以双击编辑
}, {
label: "编号",
prop: "id",
width: 80
}, {
isOperation: true, //是否是操作选项
label: "操作",
width: 60,
operation: [{
label: "查看",
color: "#73AFFE", //字体颜色
buttonClick: detailsRow, //点击后执行的函数
}]
}]);
let watchhouseTableData = ref([{
name: "哇哈哈",
id: 13246
}, {
name: "哇哈哈",
id: 13246
},]);
正常情况的效果图片
双击后的效果图片
失去焦点后,会触发onChange,会返回当前行的数据