背景
由于公司业务很多地方用到table,每个地方功能不一,抽时间整理了一份。如果遇到其他暂无的功能,请在底下留言,看到后第一时间码:😁😁😁😁😁
主要功能如下
- 自定义列数
- 自定义下拉多选
- 自定义下拉单选
- 自定义日历
- 超出一行显示省略号
- 超出一行显示图标(可自定义)
主要参数如下
- informations:父组件传过来的数据
- triangle: 是否有下拉选项
- showSelect: 多个下拉框时,表示当前点击的下拉框 true/false
- triangleTyle: 0 多选 1 单选 2日历
- isEllipsisIcon:超出是否显示图标 默认不显示
- imgUrl:超出显示的图标
- columnNum:每行几列(自定义)
- column:每行几列(默认)
- isEllipsisSymbol:超出是否显示省略号,默认不显示
- selectDate:下拉列表的数据
正文
新建两个文件,father.vue和child.vue,父组件将子组件引入即可
父组件
<template>
<div class="page-box">
<UseTable :informations="examineInfos"></UseTable>
</div>
</template>
<script setup>
import { ref } from 'vue'
import UseTable from '../widgets/table.vue'
const examineInfos = ref({
list: [
{
label: '收入',
content: '10万元',
},
{
label: '支出',
content: '10万元',
},
{
label: '人员',
content: '10人',
},
{
label: '总额',
content: '10万元',
},
{
label: '入园时间',
content: '2022-08-10',
},
{
label: '是否成交',
content: '已成交',
},
{
label: '员工数量',
content: '10人',
},
{
label: '手机号',
content: 13888888888,
},
{
label: '类别',
content: 'A类别',
},
{
label: '账号管理人',
content: 'bear',
},
{
label: '手机号',
content: '13888888888',
},
{
label: '邮箱',
content: '暂未绑定邮箱',
},
],
column: 2,
})
</script>
子组件
<template>
<div class="examineInfoList">
<ul>
<li
v-for="(item, index) in informations.list"
:key="index"
:style="item.itemWidth"
>
<span class="colorSpan">{{ item.label }}</span>
<div :class="[item.isEllipsisIcon && 'isEllipsisIcon']">
<span
:class="[
item.triangle && 'triangle',
item.showSelect && 'rotate',
item.isEllipsisSymbol && 'isEllipsisSymbol',
]"
@click="changeSelect(index)"
>
<template v-if="item.triangleTyle == 0">
<template
v-for="(selectItem, selectIndex) in allCheckSelect"
:key="selectIndex"
>{{ selectItem.name }}</template
></template
><template v-else-if="item.triangleTyle == 1">{{
choseRadio ? choseRadio.name : ''
}}</template>
<el-date-picker
v-else-if="item.triangleTyle == 2"
v-model="completionTimeLimitPlaeholder"
type="date"
placeholder="Pick a day"
@change="timeChange"
/>
<template v-else>{{ item.content }}</template></span
>
<div v-if="item.showSelect" class="triangleBox">
<el-checkbox-group
v-if="item.triangleTyle == 0"
v-model="allCheckSelect"
>
<el-checkbox
v-for="items in item.selectDate"
:key="items.value"
:label="items"
size="large"
@change="handleChoseSelect(index)"
>{{ items.name }}
</el-checkbox>
</el-checkbox-group>
<el-radio-group v-if="item.triangleTyle == 1" v-model="choseRadio">
<el-radio
v-for="items in item.selectDate"
:key="items.value"
:label="items"
@change="handleChoseRadio(index)"
>{{ items.name }}</el-radio
>
</el-radio-group>
</div>
<p v-if="item.isEllipsisIcon">
<el-tooltip effect="light" placement="right" trigger="hover">
<template #content>
<span class="popperClass">{{ item.content }}</span>
</template>
<el-button>
<img
:src="informations.imgUrl ? informations.imgUrl : imgUrl"
alt=""
/>
</el-button>
</el-tooltip>
</p>
</div>
</li>
</ul>
</div>
</template>
<script name="UsecenterTable" setup>
import { computed, ref, onMounted, onUpdated } from 'vue'
const props = defineProps({
informations: {
type: Object,
default: () => {
return {}
},
},
})
const informations = computed(() => {
const { list, column } = props.informations
if (list) {
list.map((item) => {
if (item.columnNum) {
item.itemWidth = 'width:' + 100 / item.columnNum + '%'
} else {
item.itemWidth = 'width:' + 100 / column + '%'
}
})
}
return props.informations
})
// select
const allCheckSelect = ref()
const emits = defineEmits([
'choseSelectDate',
'choseRadioDate',
'completionTime',
])
const handleChoseSelect = (index) => {
informations.value.list[index].showSelect =
!informations.value.list[index].showSelect
emits('choseSelectDate', allCheckSelect)
}
const changeSelect = (index) => {
informations.value.list[index].showSelect =
!informations.value.list[index].showSelect
}
//radio
const choseRadio = ref(null)
const handleChoseRadio = (index) => {
// eslint-disable-next-line no-console
console.log(choseRadio)
informations.value.list[index].showSelect =
!informations.value.list[index].showSelect
emits('choseRadioDate', choseRadio)
}
// 日历
let completionTimeLimitPlaeholder = ref('请选择日期')
const timeChange = (val) => {
console.log(val)
completionTimeLimitPlaeholder.value = val
emits('completionTime', val)
}
const imgUrl = ref('../assets/vue.svg')
</script>
<style scoped>
.examineInfoList {
border: 1px solid #e9eeff;
opacity: 1;
border-radius: 0px;
width: 100%;
display: flex;
flex-direction: column;
}
.examineInfoList > ul {
display: flex;
flex-wrap: wrap;
}
.examineInfoList > ul > li {
display: flex;
border-bottom: 1px solid #e9eeff;
}
.examineInfoList > ul > li:last-child {
border: none;
}
.examineInfoList > ul > li span {
font-size: 18px;
font-weight: 400;
color: #666666;
padding: 20px 30px;
line-height: 20px;
}
.examineInfoList > ul > li span.colorSpan {
display: flex;
align-items: center;
background: #f9faff;
font-size: 18px;
font-weight: 400;
line-height: 0px;
color: #00165d;
flex: 1;
max-width: 200px;
}
.examineInfoList > ul > li > div {
flex: 1.51;
display: flex;
position: relative;
}
.examineInfoList > ul > li div.isEllipsisIcon {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.examineInfoList > ul > li > div > p {
background-color: #ffffff;
width: 60px;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
position: absolute;
right: 0;
}
.examineInfoList > ul > li > div > p img {
width: 18px;
height: 18px;
position: absolute;
right: 20px;
top: 50%;
transform: translateY(-50%);
background-color: #ffffff;
cursor: pointer;
}
.examineInfoList > ul > li > div span {
flex: 1;
display: flex;
align-items: center;
}
.examineInfoList > ul > li > div span.isEllipsisSymbol {
width: 100%;
word-break: break-all;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1; /* 这里是超出几行省略 */
overflow: hidden;
border: 20px solid #ffffff;
box-sizing: border-box;
padding: 0 10px;
}
.examineInfoList > ul > li > div span.triangle {
cursor: pointer;
}
.examineInfoList > ul > li > div span.triangle::after {
content: '';
border-left: 10px solid transparent;
border-right: 10px solid transparent;
border-top: 10px solid #c9c9c9;
width: 0;
height: 0;
position: absolute;
right: 30px;
top: 50%;
transform: translateY(-50%);
transform: translateY(-50%) rotate(0deg);
transition: transform 0.3s ease-in-out;
}
.examineInfoList > ul > li > div span.triangle.rotate::after {
transform: translateY(-50%) rotate(180deg);
}
.examineInfoList > ul > li > div .triangleBox {
position: absolute;
top: 100%;
left: 0;
width: 100%;
background: #ffffff;
box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.1);
z-index: 1;
}
:deep(.el-checkbox) {
font-size: 16px;
font-weight: 400;
line-height: 34px;
color: #00165d;
padding: 15px 20px;
}
:deep(.el-checkbox-group) {
display: flex;
flex-direction: column;
}
:deep(.it-date-picker) {
margin-bottom: 0;
}
.popperClass {
width: 200px;
display: flex;
padding: 10px;
font-size: 0.18rem;
font-weight: 400;
color: #666666;
line-height: 0.2rem;
}
</style>
<style>
.el-popper__arrow {
display: block !important;
}
.el-popper.is-light {
margin-top: 8px !important;
}
.el-button.el-tooltip__trigger {
border: none !important;
}
</style>
以上就是完整代码,这里下载🤞。如果不如之处还望多多指点,需要其他功能请在评论区留言,收到后第一时间码。觉得有用抬抬小手点一下赞👍👍~~~~😊😊😊