可以全选,点击全选按钮直接全部选中
可以单选,点击单选只会选择选中的
实现:
<el-checkbox v-model="selectAll" @change="handleSelectAll">全选设备</el-checkbox>
当全选设备按钮被点击时,触发change方法 绑定的数据是seleceAll
默认不全选
const selectAll = ref(false);
- 如果参数 val 为真(即选中),则将 deviceList 中每个设备的
stationLocationCode
取出,赋值给 selectedDevices; - 如果 val 为假(即取消选中),则将 selectedDevices 清空。
- 这里是记录选择的设备
- ...作用是遍历当前使用的对象能够访问到的所有属性,并将属性放入当前对象中
const selectedDevices = ref([]);
const handleSelectAll = (val) => {
selectedDevices.value = val ? [...deviceList.value.map(d => d.stationLocationCode)] : [];
};
多选:
checkbox-group
元素能把多个 checkbox 管理为一组,只需要在 Group 中使用 v-model
绑定 Array
类型的变量即可。 只有一个选项时的默认值类型为 Boolean
,当选中时值为true
。 el-checkbox
标签中的内容将成为复选框按钮之后的描述。
- 使用
el-row
和el-col
布局,展示多个设备项; - 通过
v-for
循环渲染 deviceList 中的每个设备; - 每个设备显示为一个
el-checkbox
,绑定device.stationLocationCode
作为标识; - 当复选框状态改变时,触发 updateSelectAll 方法。
<el-checkbox-group v-model="selectedDevices" class="device-checkbox-group">
<el-row :gutter="20">
<el-col
v-for="device in deviceList"
:key="device.stationLocationCode"
:span="6"
>
<el-checkbox
:label="device.stationLocationCode"
@change="updateSelectAll"
>{{device.name}}</el-checkbox>
</el-col>
</el-row>
</el-checkbox-group>
- 如果 selectedDevices 的长度等于 deviceList 的长度,说明所有设备都被选中,则将 selectAll 设为
true
; - 否则设为
false
。
这段代码监听 selectedDevices 的变化,当其值改变时,判断选中的设备数量是否等于总设备数量,若相等则将 selectAll.value
设为 true
,否则设为 false
。
作用是控制“全选”状态是否成立。
const updateSelectAll = () => {
selectAll.value = selectedDevices.value.length === deviceList.value.length;
};
watch(selectedDevices, (newVal) => {
selectAll.value = newVal.length === deviceList.value.length;
});
<template>
<div class="ai-main full-div">
<el-card >
<template #header>
<div class="card-header">
<span>历史数据下载</span>
</div>
</template>
<el-form ref="formRef" :model="sysAlarmCfg" label-width="80px" class="demo-dynamic"
:disabled="userStore.token == null">
<el-checkbox v-model="selectAll" @change="handleSelectAll">全选设备</el-checkbox>
<el-checkbox-group v-model="selectedDevices" class="device-checkbox-group">
<el-row :gutter="20">
<el-col
v-for="device in deviceList"
:key="device.stationLocationCode"
:span="6"
>
<el-checkbox
:label="device.stationLocationCode"
@change="updateSelectAll"
>{{device.name}}</el-checkbox>
</el-col>
</el-row>
</el-checkbox-group>
<el-row >
<el-col :span="12">
<div class="mb10" >
<el-form-item label="开始时间" class="obtime-container">
<Time v-model="obstartTime" :format="'YYYY-MM-DD HH:mm'" :value-format="'YYYY-MM-DD HH:mm:00'"
@change="changeTime"></Time>
</el-form-item>
</div>
</el-col>
<el-col :span="12"> <!-- 从4改为2 -->
<div class="mb10" >
<el-form-item label="结束时间" class="obtime-container">
<Time v-model="oboverTime" :format="'YYYY-MM-DD HH:mm'" :value-format="'YYYY-MM-DD HH:mm:00'"
@change="changeTime"></Time>
</el-form-item>
</div>
</el-col>
</el-row>
</el-form>
</el-card>
<div class="operation-btn">
<el-button type="primary" @click="handleSave" class="rightBtn"
v-hasPermi="['/gateway/protoBufferWeb.StationStatusInfo/SetStationStatusOpen']">开始下载历史数据</el-button>
</div>
</div>
</template>
<script setup>
import {getDeviceList} from "@/utils/mock";
import moment from "moment";
import { ref, onMounted} from "vue";
const { proxy } = getCurrentInstance();
const deviceList = ref([])
import useUserStore from "@/store/modules/user";
const userStore = useUserStore();
let oboverTime = ref(moment().format("YYYY-MM-DD HH:00:00"));
let obstartTime = ref(moment().subtract(1, 'days').format("YYYY-MM-DD HH:00:00"));
console.log(obstartTime.value);
console.log(oboverTime.value);
const selectAll = ref(false);
const selectedDevices = ref([]);
const devices = ref([
{id: 'device1', name: '智能气温测量仪'},
{id: 'device2', name: '机械风测量仪'},
{id: 'device3', name: '智能湿度测量仪'},
{id: 'device4', name: '智能地温测量仪'}
]);
const updateSelectAll = () => {
selectAll.value = selectedDevices.value.length === deviceList.value.length;
};
const handleSelectAll = (val) => {
selectedDevices.value = val ? [...deviceList.value.map(d => d.stationLocationCode)] : [];
};
watch(selectedDevices, (newVal) => {
selectAll.value = newVal.length === deviceList.value.length;
});
onMounted(() => {
getDeviceList().then(res => {
console.log(res);
deviceList.value = res;
console.log(deviceList.value);
})
});
console.log(getDeviceList());
const handleSave = () => {
// 表单校验
if (!obstartTime.value) {
proxy.$message.error('请选择开始时间范围');
return;
}
if (!oboverTime.value) {
proxy.$message.error('请选择结束时间范围');
return;
}
// 开始时间不能晚于结束时间
const startTime = moment(obstartTime.value);
const endTime = moment(oboverTime.value);
if (startTime.isAfter(endTime)) {
proxy.$message.error('开始时间不能晚于结束时间');
return;
}
// 检查至少选择了一个设备
if (selectedDevices.value.length === 0) {
proxy.$message.error('请至少选择一个设备');
return;
}
// 执行下载逻辑
downloadHistoryData();
};
const downloadHistoryData = () => {
// 这里添加实际的下载逻辑
proxy.$message.success('开始下载历史数据');
console.log('下载参数:', {
devices: selectedDevices.value,
startTime: obstartTime.value,
endTime: oboverTime.value
});
};
</script>
<style lang="scss" scoped>
.ai-main {
padding: 0 250px;
display: flex;
flex-direction: column;
overflow-y: scroll;
border-radius: 0;
}
.el-row {
margin-bottom: 10px;
}
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
}
.text {
font-size: 14px;
}
.item {
line-height: 8vh;
display: flex;
.el-input-number {
height: 30px;
margin: auto 5px;
}
}
.itembox {
display: flex;
height: 8vh;
justify-content: space-around;
}
.factor-cfg-item {
align-items: center;
}
.close-icon {
position: relative;
cursor: pointer;
&::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 24px; // 固定宽度
height: 24px; // 固定高度
background-color: gray;
border-radius: 50%;
z-index: -1;
}
}
.confirm-container {
button {
color: #4cb9d4 !important;
}
::v-deep .el-button:focus,
.el-button:hover {
color: #4cb9d4 !important;
}
}
.full-div {
width: 100%;
height: 100%;
}
.harf-div {
width: 100%;
}
.stationParams-div {
padding: 20px;
}
.card-header {
display: flex;
justify-content: space-between;
}
.operation-btn {
display: flex;
justify-content: center;
margin: 30px 0;
}
.el-icon svg {
width: 17px;
height: 17px;
margin-left: -145px;
}
:deep(.el-switch) {
// 自定义样式
margin-right: 40px;
.el-switch__label {
width: 30px;
white-space: nowrap; // 防止文本换行
margin-left: 0.5px;
color: #333;
}
}
:deep(.el-switch__core) {
margin-left: 45px;
width: 30px;
background: linear-gradient(to right, rgba(196, 163, 163, 0.2588235294) 0%, rgb(209 217 222 / 87%) 100%);
}
.el-col-2 {
flex: 0 0 8.3333333333%;
max-width: 1.733333%;
}
.device-checkbox-group {
margin: 15px 0;
display: flex;
flex-wrap: wrap;
align-items: center; // 添加垂直居中对齐
.el-checkbox {
margin-right: 20px;
margin-bottom: 10px; // 添加底部间距
display: flex;
align-items: center; // 复选框和文字垂直居中
}
}
.obtime-container {
display: flex;
align-items: center;
.el-form-item__content {
display: flex;
align-items: center;
}
}
</style>