input标签中 :class=”{active=isActive}”的Boolean值没有效果的解决方法。

问题描述:

input标签中 :class=”{active=isActive}”的Boolean值没有效果的解决方法。

代码
<template>
  <input v-bind:class="{ active: isActive }" name="asd" value="123">
</template>

<script>
  export default {
    data() {
      return {
        isActive: ture,
      }
    },
  };
</script>
<style>
  .active {
    pointer-events: none;
    opacity: 0.5;
  }
</style>
想要的效果:

想要的效果

实际效果:

实际效果


原因分析:

因为isActive的值默认为ture,所以input标签渲染出来后本应是

 <input class="active" name="asd" value="123">

但实际上ture并没有起到作用。实际上渲染出来的是

<input name="asd" value="123">

由此可知是Boolean值出了问题,导致class="active"没有渲染出来


解决方案:

只需要把ture改为!!+1就可以了。
同理,如果是false就改为!!+0。

<script>
  export default {
    data() {
      return {
        isActive: !!+1,
      }
    },
  };
</script>
效果:

最终效果


!!+1写法的相关知识

类型转换

快速转 Number

var a = '1'
console.log(typeof a)
console.log(typeof Number(a)) // 普通写法
console.log(typeof +a) // 高端写法

快速转 Boolean

var a = 0

console.log(typeof a)
console.log(typeof Boolean(a)) // 普通写法
console.log(typeof !!a) // 高端写法

混写

先转为 Number 再转为 Boolean

var a = '0'

console.log(!!a) // 直接转将得到 true,不符合预期
console.log(!!+a) // 先转为 Number 再转为 Boolean,符合预期
<template> <!-- 权限检查:只有 SYSADMIN 能看到页面内容 --> <div v-if="form.usepermission === 'SYSADMIN'"> <div style="width: 100%; overflow-x: auto; padding: 16px; box-sizing: border-box;"> <!-- 查询区域:添加Flex布局实现左右分布 --> <div class="search-area"> <el-form :inline="true" :model="queryParams" class="demo-form-inline"> <!-- 左侧区域:关键词、查询、重置 --> <div class="form-left"> <el-form-item label="关键词"> <el-input v-model="queryParams.keyword" placeholder="课程关键词/工号/姓名"></el-input> </el-form-item> <el-form-item> <el-button type="primary" @click="handleQuery" >查询</el-button> </el-form-item> <el-form-item> <el-button @click="handleReset">重置</el-button> </el-form-item> </div> <!-- 右侧区域:审核按钮、下载按钮 --> <div class="form-right"> <el-form-item> <el-button type="primary" @click="handleParticipate"> {{ isAuditMode ? '取消审核' : '参训审核' }} </el-button> </el-form-item> <el-form-item> <el-button @click="handleDownload">DOWNLOAD <i class="el-icon-download"></i></el-button> </el-form-item> </div> </el-form> </div> <!-- 当前筛选条件显示 --> <div v-if="hasActiveFilters" class="active-filters"> <span class="filters-label">当前筛选:</span> <el-tag v-for="(value, column) in filters" :key="column" closable type="primary" @close="clearFilter(column)" class="filter-tag" > {{ getColumnLabel(column) }}: {{ value }} </el-tag> <el-button type="text" @click="clearAllFilters" class="clear-all">清除所有</el-button> </div> <!-- 表格区域 --> <div class="table-area"> <el-table ref="multipleTableRef" :data="filteredTableData" border style="width: 100%" @selection-change="handleSelectionChange" :row-key="row => row.id" > <el-table-column type="selection" width="35"></el-table-column> <!-- 序号列 <el-table-column prop="id" label="序号" min-width="50" show-overflow-tooltip> <template #header> <div class="filter-header" :class="{ 'filter-active': filters.id }"> <span>序号</span> <el-dropdown trigger="click" @command="handleFilter"> <el-icon :class="{ 'filter-icon-active': filters.id }"><Filter /></el-icon> <template #dropdown> <el-dropdown-menu> <el-dropdown-item :command="{ column: 'id', value: 'all' }" :class="{ 'dropdown-item-active': !filters.id }" > 全部 </el-dropdown-item> <el-dropdown-item v-for="id in getUniqueValues('id')" :key="id" :command="{ column: 'id', value: id }" :class="{ 'dropdown-item-active': filters.id === id }" > {{ id }} </el-dropdown-item> </el-dropdown-menu> </template> </el-dropdown> </div> </template> </el-table-column> --> <!-- 添加序号显示 --> <el-table-column prop="id" label="序号" min-width="50" show-overflow-tooltip> <template #default="scope"> {{ scope.$index + 1 }} <!-- 关键修改:索引+1得到从1开始的序号 --> </template> </el-table-column> <!-- 区分列 --> <el-table-column prop="category" label="区分" min-width="80" show-overflow-tooltip> <template #header> <div class="filter-header" :class="{ 'filter-active': filters.category }"> <span>区分</span> <el-dropdown trigger="click" @command="handleFilter"> <el-icon :class="{ 'filter-icon-active': filters.category }"><Filter /></el-icon> <template #dropdown> <el-dropdown-menu> <el-dropdown-item :command="{ column: 'category', value: 'all' }" :class="{ 'dropdown-item-active': !filters.category }" > 全部 </el-dropdown-item> <el-dropdown-item v-for="category in getUniqueValues('category')" :key="category" :command="{ column: 'category', value: category }" :class="{ 'dropdown-item-active': filters.category === category }" > {{ category }} </el-dropdown-item> </el-dropdown-menu> </template> </el-dropdown> </div> </template> </el-table-column> <!-- 等级列 --> <el-table-column prop="level" label="等级" min-width="60" show-overflow-tooltip> <template #header> <div class="filter-header" :class="{ 'filter-active': filters.level }"> <span>等级</span> <el-dropdown trigger="click" @command="handleFilter"> <el-icon :class="{ 'filter-icon-active': filters.level }"><Filter /></el-icon> <template #dropdown> <el-dropdown-menu> <el-dropdown-item :command="{ column: 'level', value: 'all' }" :class="{ 'dropdown-item-active': !filters.level }" > 全部 </el-dropdown-item> <el-dropdown-item v-for="level in getUniqueValues('level')" :key="level" :command="{ column: 'level', value: level }" :class="{ 'dropdown-item-active': filters.level === level }" > {{ level }} </el-dropdown-item> </el-dropdown-menu> </template> </el-dropdown> </div> </template> </el-table-column> <!-- 课程名称列 --> <el-table-column prop="coursename" label="课程名称" min-width="120" show-overflow-tooltip> <template #header> <div class="filter-header" :class="{ 'filter-active': filters.coursename }"> <span>课程名称</span> <el-dropdown trigger="click" @command="handleFilter"> <el-icon :class="{ 'filter-icon-active': filters.coursename }"><Filter /></el-icon> <template #dropdown> <el-dropdown-menu> <el-dropdown-item :command="{ column: 'coursename', value: 'all' }" :class="{ 'dropdown-item-active': !filters.coursename }" > 全部 </el-dropdown-item> <el-dropdown-item v-for="course in getUniqueValues('coursename')" :key="course" :command="{ column: 'coursename', value: course }" :class="{ 'dropdown-item-active': filters.coursename === course }" > {{ course }} </el-dropdown-item> </el-dropdown-menu> </template> </el-dropdown> </div> </template> </el-table-column> <!-- 期数列 --> <el-table-column prop="period" label="期数" min-width="70" show-overflow-tooltip> <template #header> <div class="filter-header" :class="{ 'filter-active': filters.period }"> <span>期数</span> <el-dropdown trigger="click" @command="handleFilter"> <el-icon :class="{ 'filter-icon-active': filters.period }"><Filter /></el-icon> <template #dropdown> <el-dropdown-menu> <el-dropdown-item :command="{ column: 'period', value: 'all' }" :class="{ 'dropdown-item-active': !filters.period }" > 全部 </el-dropdown-item> <el-dropdown-item v-for="period in getUniqueValues('period')" :key="period" :command="{ column: 'period', value: period }" :class="{ 'dropdown-item-active': filters.period === period }" > {{ period }} </el-dropdown-item> </el-dropdown-menu> </template> </el-dropdown> </div> </template> </el-table-column> <!-- 姓名列 --> <el-table-column prop="name" label="姓名" min-width="60" show-overflow-tooltip> <template #header> <div class="filter-header" :class="{ 'filter-active': filters.name }"> <span>姓名</span> <el-dropdown trigger="click" @command="handleFilter"> <el-icon :class="{ 'filter-icon-active': filters.name }"><Filter /></el-icon> <template #dropdown> <el-dropdown-menu> <el-dropdown-item :command="{ column: 'name', value: 'all' }" :class="{ 'dropdown-item-active': !filters.name }" > 全部 </el-dropdown-item> <el-dropdown-item v-for="name in getUniqueValues('name')" :key="name" :command="{ column: 'name', value: name }" :class="{ 'dropdown-item-active': filters.name === name }" > {{ name }} </el-dropdown-item> </el-dropdown-menu> </template> </el-dropdown> </div> </template> </el-table-column> <!-- 工号列 --> <el-table-column prop="employeeid" label="工号" min-width="80" show-overflow-tooltip> <template #header> <div class="filter-header" :class="{ 'filter-active': filters.employeeid }"> <span>工号</span> <el-dropdown trigger="click" @command="handleFilter"> <el-icon :class="{ 'filter-icon-active': filters.employeeid }"><Filter /></el-icon> <template #dropdown> <el-dropdown-menu> <el-dropdown-item :command="{ column: 'employeeid', value: 'all' }" :class="{ 'dropdown-item-active': !filters.employeeid }" > 全部 </el-dropdown-item> <el-dropdown-item v-for="empId in getUniqueValues('employeeid')" :key="empId" :command="{ column: 'employeeid', value: empId }" :class="{ 'dropdown-item-active': filters.employeeid === empId }" > {{ empId }} </el-dropdown-item> </el-dropdown-menu> </template> </el-dropdown> </div> </template> </el-table-column> <!-- Team列 --> <el-table-column prop="team" label="Team" min-width="100" show-overflow-tooltip> <template #header> <div class="filter-header" :class="{ 'filter-active': filters.team }"> <span>Team</span> <el-dropdown trigger="click" @command="handleFilter"> <el-icon :class="{ 'filter-icon-active': filters.team }"><Filter /></el-icon> <template #dropdown> <el-dropdown-menu> <el-dropdown-item :command="{ column: 'team', value: 'all' }" :class="{ 'dropdown-item-active': !filters.team }" > 全部 </el-dropdown-item> <el-dropdown-item v-for="team in getUniqueValues('team')" :key="team" :command="{ column: 'team', value: team }" :class="{ 'dropdown-item-active': filters.team === team }" > {{ team }} </el-dropdown-item> </el-dropdown-menu> </template> </el-dropdown> </div> </template> </el-table-column> <!-- Group列 --> <el-table-column prop="grouptext" label="Group" min-width="100" show-overflow-tooltip> <template #header> <div class="filter-header" :class="{ 'filter-active': filters.grouptext }"> <span>Group</span> <el-dropdown trigger="click" @command="handleFilter"> <el-icon :class="{ 'filter-icon-active': filters.grouptext }"><Filter /></el-icon> <template #dropdown> <el-dropdown-menu> <el-dropdown-item :command="{ column: 'grouptext', value: 'all' }" :class="{ 'dropdown-item-active': !filters.grouptext }" > 全部 </el-dropdown-item> <el-dropdown-item v-for="group in getUniqueValues('grouptext')" :key="group" :command="{ column: 'grouptext', value: group }" :class="{ 'dropdown-item-active': filters.grouptext === group }" > {{ group }} </el-dropdown-item> </el-dropdown-menu> </template> </el-dropdown> </div> </template> </el-table-column> <!-- Part列 --> <el-table-column prop="department" label="Part" min-width="110" show-overflow-tooltip> <template #header> <div class="filter-header" :class="{ 'filter-active': filters.department }"> <span>Part</span> <el-dropdown trigger="click" @command="handleFilter"> <el-icon :class="{ 'filter-icon-active': filters.department }"><Filter /></el-icon> <template #dropdown> <el-dropdown-menu> <el-dropdown-item :command="{ column: 'department', value: 'all' }" :class="{ 'dropdown-item-active': !filters.department }" > 全部 </el-dropdown-item> <el-dropdown-item v-for="dept in getUniqueValues('department')" :key="dept" :command="{ column: 'department', value: dept }" :class="{ 'dropdown-item-active': filters.department === dept }" > {{ dept }} </el-dropdown-item> </el-dropdown-menu> </template> </el-dropdown> </div> </template> </el-table-column> <!-- 联系方式列 --> <el-table-column prop="contact" label="联系方式" min-width="70" show-overflow-tooltip> <template #header> <div class="filter-header" :class="{ 'filter-active': filters.contact }"> <span>联系方式</span> <el-dropdown trigger="click" @command="handleFilter"> <el-icon :class="{ 'filter-icon-active': filters.contact }"><Filter /></el-icon> <template #dropdown> <el-dropdown-menu> <el-dropdown-item :command="{ column: 'contact', value: 'all' }" :class="{ 'dropdown-item-active': !filters.contact }" > 全部 </el-dropdown-item> <el-dropdown-item v-for="contact in getUniqueValues('contact')" :key="contact" :command="{ column: 'contact', value: contact }" :class="{ 'dropdown-item-active': filters.contact === contact }" > {{ contact }} </el-dropdown-item> </el-dropdown-menu> </template> </el-dropdown> </div> </template> </el-table-column> <!-- 参训现况列 --> <el-table-column prop="status" label="参训现况" min-width="100" show-overflow-tooltip> <template #header> <div class="filter-header" :class="{ 'filter-active': filters.status }"> <span>参训现况</span> <el-dropdown trigger="click" @command="handleFilter"> <el-icon :class="{ 'filter-icon-active': filters.status }"><Filter /></el-icon> <template #dropdown> <el-dropdown-menu> <el-dropflow-item :command="{ column: 'status', value: 'all' }" :class="{ 'dropdown-item-active': !filters.status }" > 全部 </el-dropflow-item> <el-dropdown-item v-for="status in getUniqueValues('status')" :key="status" :command="{ column: 'status', value: status }" :class="{ 'dropdown-item-active': filters.status === status }" > {{ status }} </el-dropdown-item> </el-dropdown-menu> </template> </el-dropdown> </div> </template> <template #default="scope"> <el-select v-model="scope.row.status" placeholder="请选择" @change="handleStatusChange(scope.row)"> <el-option label="参加" value="参加"></el-option> <el-option label="未参加" value="未参加"></el-option> </el-select> </template> </el-table-column> <!-- 考试得分 --> <el-table-column prop="score" label="考试得分" min-width="70" show-overflow-tooltip> <template #header> <div class="filter-header" :class="{ 'filter-active': filters.score }"> <span>考试得分</span> <el-dropdown trigger="click" @command="handleFilter"> <el-icon :class="{ 'filter-icon-active': filters.score }"><Filter /></el-icon> <template #dropdown> <el-dropdown-menu> <el-dropdown-item :command="{ column: 'score', value: 'all' }" :class="{ 'dropdown-item-active': !filters.score }" > 全部 </el-dropdown-item> <el-dropdown-item v-for="score in getUniqueValues('score')" :key="score" :command="{ column: 'score', value: score }" :class="{ 'dropdown-item-active': filters.score === score }" > {{ score }} </el-dropdown-item> </el-dropdown-menu> </template> </el-dropdown> </div> </template> </el-table-column> <!-- 审核状态列 --> <el-table-column prop="auditstatus" label="审核状态" min-width="80" show-overflow-tooltip> <template #header> <div class="filter-header" :class="{ 'filter-active': filters.auditstatus }"> <span>审核状态</span> <el-dropdown trigger="click" @command="handleFilter"> <el-icon :class="{ 'filter-icon-active': filters.auditstatus }"><Filter /></el-icon> <template #dropdown> <el-dropdown-menu> <el-dropdown-item :command="{ column: 'auditstatus', value: 'all' }" :class="{ 'dropdown-item-active': !filters.auditstatus }" > 全部 </el-dropdown-item> <el-dropdown-item v-for="auditStatus in getUniqueValues('auditstatus')" :key="auditStatus" :command="{ column: 'auditstatus', value: auditStatus }" :class="{ 'dropdown-item-active': filters.auditstatus === auditStatus }" > {{ auditStatus }} </el-dropdown-item> </el-dropdown-menu> </template> </el-dropdown> </div> </template> </el-table-column> </el-table> <!-- 审核操作按钮:仅isAuditMode为true时显示 --> <div v-if="isAuditMode" class="action-buttons" style="margin: 10px 0;"> <el-button type="primary" @click="handleApprove">审核通过</el-button> <el-button type="danger" @click="handleReject">审核不通过</el-button> </div> <div class="pagination"> <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="queryParams.pageNum" :page-sizes="[10, 20, 50]" :page-size="queryParams.pageSize" layout="total, sizes, prev, pager, next, jumper" :total="filteredTotal"> </el-pagination> </div> </div> </div> </div> <!-- 无权限时的提示 --> <div v-else class="permission-denied"> <el-result icon="warning" title="权限不足" sub-title="您没有访问此页面的权限,请联系管理员。" > <template #extra> <el-button type="primary" @click="handleGoBack">返回</el-button> <el-button @click="handleContactAdmin">联系管理员</el-button> </template> </el-result> </div> </template> <script setup> import { ref, reactive, onMounted, computed } from 'vue' import { useRouter } from 'vue-router' import axios from 'axios' import { ElMessage, ElMessageBox } from 'element-plus' import { Filter } from '@element-plus/icons-vue' import { useUserStore } from '@/stores/auth' const router = useRouter() const userStore = useUserStore() // 用户权限信息 const form = ref({ usepermission: userStore.permission || '' }) console.log('我的权限:', form.value.usepermission) // 查询参数 const queryParams = reactive({ keyword: '', pageNum: 1, pageSize: 10 }) // 表格数据 const tableData = ref([]) // 筛选条件 const filters = reactive({}) // 总条数 const total = ref(0) // 选中数据 const multipleSelection = ref([]) // 表格引用 const multipleTableRef = ref(null) // 核心状态变量:仅通过"参训审核/取消审核"按钮修改 const isAuditMode = ref(false) // 列名映射 const columnLabels = { id: '序号', category: '区分', level: '等级', coursename: '课程名称', period: '期数', name: '姓名', employeeid: '工号', team: 'Team', grouptext: 'Group', department: 'Part', contact: '联系方式', status: '参训现况', score:'考试得分', auditstatus: '审核状态' } // 获取列标签 const getColumnLabel = (column) => { return columnLabels[column] || column } // 检查是否有活跃的筛选条件 const hasActiveFilters = computed(() => { return Object.keys(filters).length > 0 }) // 获取唯一列表 const getUniqueValues = (column) => { const values = tableData.value.map(item => item[column]).filter(Boolean) return [...new Set(values)] } // 处理筛选 const handleFilter = (command) => { const { column, value } = command if (value === 'all') { // 删除该列的筛选条件 delete filters[column] } else { // 设置筛选条件 filters[column] = value } // 重置到第一页 queryParams.pageNum = 1 } // 清除单个筛选条件 const clearFilter = (column) => { delete filters[column] } // 清除所有筛选条件 const clearAllFilters = () => { Object.keys(filters).forEach(key => { delete filters[key] }) } // 筛选后的数据 const filteredTableData = computed(() => { let filtered = tableData.value // 应用所有筛选条件 Object.keys(filters).forEach(column => { filtered = filtered.filter(item => item[column] === filters[column]) }) return filtered }) // 筛选后的总条数 const filteredTotal = computed(() => filteredTableData.value.length) // 获取表格数据 const fetchData = async () => { // 如果没有权限,不执行数据获取 if (form.value.usepermission !== 'SYSADMIN') { return } try { const res = await axios.get('/api/training/list', { params: queryParams }) // 处理数据:接口返回的status为空时,默认设为"未参加" const formattedData = res.data.data.records.map(record => ({ ...record, status: record.status ?? '未参加' })) tableData.value = formattedData total.value = res.data.total // 重置筛选条件 Object.keys(filters).forEach(key => delete filters[key]) } catch (error) { console.error(error) ElMessage.error('获取数据失败') } } // 查询按钮点击事件 const handleQuery = () => { queryParams.pageNum = 1 fetchData() } // 重置按钮点击事件 const handleReset = () => { queryParams.keyword = '' queryParams.pageNum = 1 // 重置筛选条件 Object.keys(filters).forEach(key => delete filters[key]) fetchData() } // 多选框选中数据 const handleSelectionChange = (selection) => { multipleSelection.value = selection } // 分页大小变化 const handleSizeChange = (val) => { queryParams.pageSize = val fetchData() } // 当前页变化 const handleCurrentChange = (val) => { queryParams.pageNum = val fetchData() } // 参训审核/取消审核按钮点击事件 const handleParticipate = () => { isAuditMode.value = !isAuditMode.value } // 审核通过按钮点击事件 const handleApprove = () => { if (multipleSelection.value.length === 0) { ElMessage.warning('请先选择需要审核的记录') return } const hasUnparticipated = multipleSelection.value.some(row => row.status !== '参加') if (hasUnparticipated) { ElMessage.warning('未参加培训,不能通过') return } batchUpdateStatus('通过') } // 审核不通过按钮点击事件 const handleReject = () => { if (multipleSelection.value.length === 0) { ElMessage.warning('请先选择需要审核的记录') return } batchUpdateStatus('不通过') } // 批量更新审核状态 const batchUpdateStatus = async (status) => { const selectedIds = multipleSelection.value.map(item => item.id) ElMessageBox.confirm(`确定要将选中记录审核为"${status}"吗?`, '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(async () => { try { await axios.put('/api/training/batchStatus', { ids: selectedIds, status }) ElMessage.success('审核成功') fetchData() } catch (error) { console.error(error) ElMessage.error('审核失败') } }).catch(() => { // 用户取消操作 }) } // 审核状态变化(单行更新) const handleStatusChange = async (row) => { try { await axios.put(`/api/training/status/${row.id}`, { status: row.status }) ElMessage.success('更新成功') } catch (error) { console.error(error) ElMessage.error('更新失败') fetchData() } } // 下载按钮点击事件 const handleDownload = () => { window.open('/api/training/download', '_blank') } // 返回上一页 const handleGoBack = () => { router.back() } // 联系管理员 const handleContactAdmin = () => { ElMessage.info('请联系系统管理员获取权限') } // 初始化数据 onMounted(() => { // 只有 SYSADMIN 权限才获取数据 if (form.value.usepermission === 'SYSADMIN') { fetchData() } else { console.log('当前用户无权限访问此页面,权限为:', form.value.usepermission) } }) </script> <style scoped> .search-area { margin-bottom: 10px; } .demo-form-inline { display: flex; justify-content: space-between; align-items: center; width: 100%; } .form-left .el-form-item { margin-right: 10px; } .form-right .el-form-item { margin-left: 10px; } .action-buttons { text-align: left; } .pagination { margin-top: 10px; text-align: right; } /* 当前筛选条件样式 */ .active-filters { margin-bottom: 15px; padding: 10px; background-color: #f8f9fa; border-radius: 4px; border-left: 4px solid #409EFF; } .filters-label { font-weight: bold; color: #606266; margin-right: 10px; } .filter-tag { margin-right: 8px; margin-bottom: 5px; } .clear-all { margin-left: 10px; color: #409EFF; } /* 筛选头部样式 */ .filter-header { display: flex; align-items: center; justify-content: space-between; cursor: pointer; padding: 8px 0; transition: all 0.3s ease; } .filter-header.filter-active { background-color: #ecf5ff; border-radius: 4px; padding: 8px 12px; margin: -8px -12px; } .filter-header .el-icon { color: #c0c4cc; font-size: 14px; transition: all 0.3s ease; } .filter-header:hover .el-icon { color: #409EFF; } .filter-icon-active { color: #409EFF !important; } /* 下拉菜单选中项样式 */ :deep(.dropdown-item-active) { background-color: #ecf5ff !important; color: #409EFF !important; } :deep(.dropdown-item-active:hover) { background-color: #d9ecff !important; } /* 无权限提示样式 */ .permission-denied { display: flex; justify-content: center; align-items: center; height: 60vh; padding: 20px; background-color: #f5f7fa; } .permission-denied .el-result { padding: 40px 30px; } /* 表格自适应优化 */ .table-area { overflow-x: auto; } .el-table { table-layout: auto !important; /* 关键:使用自动布局 */ min-width: 100%; /* 确保表格至少与容器同宽 */ } .el-table__body { width: auto !important; } .el-table-column { min-width: 60px; /* 设置列最小宽度,防止内容过少时列过窄 */ } </style> 中的分页功能 <el-pagination @size-change=“handleSizeChange” @current-change=“handleCurrentChange” :current-page=“queryParams.pageNum” :page-sizes=“[10, 20, 50]” :page-size=“queryParams.pageSize” layout=“total, sizes, prev, pager, next, jumper” :total=“filteredTotal”> 不生效,能帮我完善表格的分页功能是他生效吗,请帮我在此基础上生成一个改善后的完整的vue3代码
最新发布
12-05
下面的代码上传图片列表,将图片一行展示三个:<template> <div class="container"> <el-tabs type="border-card"> <el-tab-pane :label="title"> <el-form ref="form" :model="form" :rules="rules" label-width="120px"> <uploadForm label="介绍图片:" v-model="form.cover" name="cover" :rules="rules.cover" :disabled="Boolean(queryParams.type)" :limit="1"></uploadForm> <el-row> <el-col :span="12"> <el-form-item label="团购名称:" prop="name"> <el-input class="input" v-model="form.name" :disabled="Boolean(queryParams.type)" placeholder="请输入团购名称" /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="自动截止:" prop="isAutoEnd"> <el-switch v-model="form.isAutoEnd" :disabled="Boolean(queryParams.type)" :active-value="true" :inactive-value="false" /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="开始时间:" prop="startTime"> <el-date-picker clearable v-model="form.startTime" type="datetime" default-time="12:00:00" :disabled="Boolean(queryParams.type)" value-format="yyyy-MM-dd HH:mm:ss" placeholder="请选择活动开始时间"> </el-date-picker> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="截止时间:" prop="endTime"> <el-date-picker clearable v-model="form.endTime" type="datetime" default-time="12:00:00" value-format="yyyy-MM-dd HH:mm:ss" :disabled="Boolean(queryParams.type)" placeholder="请选择活动截止时间"> </el-date-picker> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="最大接龙人数" prop="maxJoinNum"> <el-input-number :disabled="Boolean(queryParams.type)" v-model="form.maxJoinNum" :precision="0" :step="1" :min="0"></el-input-number> </el-form-item> </el-col> <!-- <el-col :span="12"> <el-form-item label="最小成交金额" prop="minAmount"> <el-input-number :disabled="Boolean(queryParams.type)" v-model="form.minAmount" :precision="2" :step="0.1" :min="0"></el-input-number> </el-form-item> </el-col> --> <el-col :span="12"> <el-form-item label="提货地址:" prop="addressIds"> <el-select :disabled="Boolean(queryParams.type)" v-model="form.addressIds" filterable placeholder="请选择" multiple> <el-option v-for="item in addressoptions" :key="item.id" :label="item.addressName" :value="item.id"> </el-option> </el-select> </el-form-item> </el-col> <el-col :span="24"> <el-form-item label="团购内容" prop="detailInfo"> <UEditor v-model="form.detailInfo" ref="ueditor" :config="myConfig" :disabled="Boolean(queryParams.type)" /> </el-form-item> <!-- <el-form-item label="团购内容:" prop="detailInfo"> <el-input :disabled="Boolean(queryParams.type)" type="textarea" :rows="2" placeholder="请输入团购内容" :autosize="{ minRows: 4, maxRows: 8 }" v-model="form.detailInfo"></el-input> </el-form-item> --> </el-col> </el-row> <el-form-item label="其它信息:"> <el-checkbox-group v-model="form.selectedItemsOther" :disabled="Boolean(queryParams.type)"> <el-checkbox label="isGetRealName">真实姓名</el-checkbox> <el-checkbox label="isGetPhone">手机号码</el-checkbox> </el-checkbox-group> </el-form-item> <el-form-item label="功能选择:"> <el-checkbox-group v-model="form.selectedItemsFunction" :disabled="Boolean(queryParams.type)"> <el-checkbox label="isHideList">发布最新接龙列表</el-checkbox> <el-checkbox label="isHideOrderAmount">接龙金额仅创建人可见</el-checkbox> <el-checkbox label="canCancel">禁止用户取消订单</el-checkbox> </el-checkbox-group> </el-form-item> <div> <el-form-item label="商品信息:" prop="products"> <el-table :data="form.products"> <el-table-column label="商品名称" align="center"> <template slot-scope="{row,$index}"> <div style="padding-bottom: 15px;"> <el-form-item :prop="`products.${$index}.name`" :rules="[{ required: true, message: '请输入团购名称', trigger: ['change', 'blur'] }]"> <el-input :disabled="Boolean(queryParams.type)" v-model="form.products[$index].name" placeholder="请输入团购名称"></el-input> </el-form-item> </div> </template> </el-table-column> <el-table-column label="商品价格" align="center"> <template slot-scope="{row,$index}"> <div style="padding-bottom: 15px;"> <el-form-item :prop="`products.${$index}.price`" :rules="[{ required: true, message: '请输入商品价格', trigger: ['change', 'blur'] }]"> <el-input-number :precision="2" :step="0.1" :min="0" :disabled="Boolean(queryParams.type)" v-model="form.products[$index].price"></el-input-number> </el-form-item> </div> </template> </el-table-column> <el-table-column label="商品数量" align="center"> <template slot-scope="{row,$index}"> <div style="padding-bottom: 15px;"> <el-form-item :prop="`products.${$index}.totalNum`" :rules="[{ required: true, message: '请输入商品数量', trigger: ['change', 'blur'] }]"> <el-input-number :precision="0" :step="1" :min="1" :disabled="Boolean(queryParams.type)" v-model="form.products[$index].totalNum"></el-input-number> </el-form-item> </div> </template> </el-table-column> <el-table-column label="每单限制购买量" align="center"> <template slot-scope="{row,$index}"> <div style="padding-bottom: 15px;"> <el-form-item :prop="`products.${$index}.limitNum`" :rules="[{ required: true, message: '请输入每单限制购买量', trigger: ['change', 'blur'] }]"> <el-input-number :precision="0" :step="1" :min="1" :disabled="Boolean(queryParams.type)" v-model="form.products[$index].limitNum"></el-input-number> </el-form-item> </div> </template> </el-table-column> <el-table-column label="商品图片" align="center"> <template slot-scope="{row,$index}"> <div style="padding-bottom: 15px; "> <el-upload action :file-list="row.image" :prop="`products.${$index}.image`" :on-remove="(file, fileList) => handleRemoveMaterial(file, fileList, $index)" :http-request="(obj) => selectPicUploadMaterial(obj, $index)" list-type="picture-card" :disabled="Boolean(queryParams.type)" v-model="form.products[$index].image"> <i class="el-icon-plus avatar-uploader-icon"></i> </el-upload> </div> </template> </el-table-column> <el-table-column label="商品信息详情" align="center"> <template slot-scope="{row,$index}"> <div style="padding-bottom: 15px;"> <!-- <el-form-item :prop="`products.${$index}.productDetailInfo`" :rules="[{ required: true, message: '请输入商品信息详情', trigger: ['change', 'blur'] }]"> <UEditor v-model="form.products[$index].productDetailInfo" ref="ueditor" :config="myConfig1" :disabled="Boolean(queryParams.type)" /> </el-form-item> --> <el-form-item prop="`products.${$index}.detail`"> <el-input :disabled="Boolean(queryParams.type)" type="textarea" :rows="2" placeholder="请输入商品信息详情" :autosize="{ minRows: 4, maxRows: 8 }" v-model="form.products[$index].detail"></el-input> </el-form-item> </div> </template> </el-table-column> <!-- <el-table-column label="商品图片" align="center"> <template slot-scope="{row,$index}"> <div style="padding-bottom: 15px;"> <uploadForm label="" v-model="form.products[$index].image" :name="`products.${$index}.image`" :rules="[ { required: true, message: '请选择商品图片', trigger: ['change', 'blur'] } ]" :disabled="Boolean(queryParams.type)" :limit="3"></uploadForm> </div> </template> </el-table-column> --> <el-table-column v-if="!queryParams.type" label="操作" align="center" class-name="small-padding fixed-width" width="180"> <template slot-scope="scope"> <el-button @click="addproduct()"> 添加</el-button> <el-button type="danger" icon="el-icon-delete" :disabled="form.products.length <= 1" @click="removeRow(scope.$index)">删除</el-button> </template> </el-table-column> </el-table> </el-form-item> </div> </el-form> <!-- 修改/新增 --> <div class="dialog-footer"> <el-button v-if="!queryParams.type" type="primary" @click="submitForm">确 定</el-button> <el-button @click="handleBack">取 消</el-button> </div> </el-tab-pane> </el-tabs> </div> </template> <script> import { imgUrl } from '@/utils/request' import uploadForm from "@/components/uploadForm/index2.vue"; import { getISOTime, checkLongitudeValidator, checkPointIsNumber } from '@/utils/parsing' import { checkPhone } from '@/utils/validate' import mapView from '@/components/MapContainer/index.vue' import UEditor from '@/components/UEditor/ue' import { addGroupShop, editGroupBuy, getGroupBuyAddressPage, getGroupBuyDetail } from '@/api/solitaire/solitaire' import { uploadPic } from '@/api/activity/activity' import { onMounted, beforeDestroy } from 'vue' import { reset } from 'echarts/lib/visual/seriesColor' export default { components: { UEditor, mapView, uploadForm, }, onMounted() { }, data() { return { myConfig1:{}, fileList: [], myConfig:{}, addressoptions: [], addressList: [], currentTime: new Date().toLocaleTimeString(), timer: null, // 第一个复选框组绑定 // 第二个复选框组绑定 selectedItemsFunction: [], checkList: ['选中且禁用', '复选框 A'], checked: true, // 单个复选框的绑定 dataList: [], title: "新增接龙", // 封面图片 selectImgUrl: '', queryParams: {}, currentImgIndex: 0, // 封面图片类型选择 imgDialogVisible: false, // 表单数据 form: { selectedItemsOther: [], selectedItemsFunction: [], addressIds: [], canCancel: 0, cover: [], detailInfo: null, endTime: null, id: 0, isAutoEnd: 0, isHideList: false, isHideOrderAmount: false, isJoin: 0, maxJoinNum: null, minAmount: null, name: "", products: [ { detail: null, id: 0, image: [], limitNum: 0, name: "", parentId: 0, price: 0, soldNum: 0, totalNum: 0, } ], realEndTime: "", startTime: "", status: 0, }, // 表单校验 rules: { addressIds: [ { required: true, message: '请选择提货地址', trigger: ['change', 'blur'] } ], cover: [ { required: true, message: '请选择介绍图片', trigger: ['change', 'blur'] } ], name: [ { required: true, message: '请输入团购名称', trigger: 'change' } ], othermessage: [ { type: 'array', required: true, message: '请选择其它信息', trigger: 'change' } ], selectability: [ { type: 'array', required: true, message: '请选择功能', trigger: 'change' }, ], shopmessage: [ { required: true, message: '请输入商品信息', trigger: 'change' }, ], detailInfo: [ { required: true, message: '请输入团购内容', trigger: ['change', 'blur'] } ], maxJoinNum: [ { required: true, message: '请输入最大接龙人数', trigger: 'change' }, ], minAmount: [ { required: true, message: '最小成交金额不能为空', trigger: 'change' } ], endTime: [ { required: true, message: '结束时间必须选择', trigger: 'change' } ], startTime: [ { required: true, message: '开始时间不能为空', trigger: 'change' } ], description: [ { required: true, message: '活动开始内容不能为空', trigger: 'change' } ], address: [ { required: true, message: '地点不能为空', trigger: 'change' } ], conditionRequire: [ { required: true, message: '请输入条件说明', trigger: 'change' } ], // signStartDatetime: [ // { required: true, message: '报名开始时间必须选择', trigger: 'change' } // ], signEndDatetime: [ { required: true, message: '活动截止时间必须选择', trigger: 'change' } ], jobUserVOLists: [ { type: 'array', required: true, message: '请添加岗位需求', trigger: 'change' } ], }, // 图片前缀 cover: imgUrl, // //分页 column: { pageSize: null, pageNum: null }, // 队伍列表 // 岗位表单校验 jobRules: { jobName: [ { required: true, message: '请输入岗位名称', trigger: 'change' } ], jobCount: [ { required: true, message: '请输入岗位人数', trigger: 'change' } ], workHour: [ { required: true, message: '请输入工时', trigger: 'change' } ], pointPercent: [ { required: true, message: '请输入积分(每人每小时)', trigger: 'change' }, { validator: checkPointIsNumber, message: '积分必须为数字' } ], checkInTime: [ { required: true, message: '请输入签到时间', trigger: 'change' } ], checkOutTime: [ { required: true, message: '请输入签退时间', trigger: 'change' } ], checkLocation: [ { required: true, message: '请选择签到地点', trigger: 'change' } ] }, } }, created() { this.getAddressList() this.queryParams = this.$route.query; if (this.queryParams.id) { // 编辑 this.title = '修改接龙' console.log(Boolean(this.queryParams.type),'59') // this.isdisabled = true; getGroupBuyDetail(this.queryParams.id).then(res => { this.form = { ...res, cover: [{ url: res.cover }], isAutoEnd: res.isAutoEnd === 1 ? true : false, addressIds: res.addresses.map(n => (n.id)), selectedItemsOther: [], selectedItemsFunction: [], products: res.products.map((n) => { let imageArray = [] if (n.image) { const imageUrls = n.image.split(','); imageArray = imageUrls.map(url => ({ url })); } console.log(imageArray,'988') return { ...n, image: imageArray } // const imageUrls = n.image.split(','); // return { // ...n, // image: imageUrls.map(url => ({ url })) // } }) } console.log(this.form.isAutoEnd,'0000') if (res.isGetRealName === 1) { this.form.selectedItemsOther.push('isGetRealName') } if (res.isGetPhone === 1) { this.form.selectedItemsOther.push('isGetPhone') } if (res.isHideList ===0) { this.form.selectedItemsFunction.push('isHideList') } if (res.isHideOrderAmount === 1) { this.form.selectedItemsFunction.push('isHideOrderAmount') } if (res.canCancel === 1) { this.form.selectedItemsFunction.push('canCancel') } this.$nextTick(() => { if (this.$refs.ueditor) { this.$refs.ueditor.setContent(res.detailInfo); } }); console.log(this.form,'-----') }) } }, methods: { handleRemoveMaterial(file, fileList, index) { // 找到要删除的图片在商品图片数组中的索引 const fileIndex = this.form.products[index].image.findIndex(item => item.url === file.url); if (fileIndex > -1) { // 从商品图片数组中移除该图片 this.form.products[index].image.splice(fileIndex, 1); } // 更新 fileList const newFileList = fileList.filter(item => item.url !== file.url); this.form.products[index].image = newFileList; }, selectPicUploadMaterial(obj, index) { let fd = new FormData(); fd.append('file', obj.file); uploadPic(fd, { modularName: 'ACTIVITY' }).then(res => { console.log('上传图片返回的数据',res); if (res ) { const product = this.form.products[index]; if (!product.image) { product.image = []; } product.image.push({ url: res, uid: Date.now() }); } else { console.error('上传图片失败,未获取到有效的 url', res); } }).catch(error => { console.error('上传图片请求失败', error); }); }, onMounted() { }, getAddressList() { getGroupBuyAddressPage().then(res => { console.log(res,'099') this.addressoptions = res.pageData }) }, beforeDestroy() { clearInterval(this.timer); }, addproduct() { this.form.products.push({ /* 初始化新商品 */ }); this.$nextTick(() => { this.$refs.form.validateField('products'); // 触发products字段校验 }); }, removeRow(index) { // 添加长度检查 if (this.form.products.length <= 1) { this.$message.warning('至少需要保留一个商品'); return; } this.form.products.splice(index, 1); this.$nextTick(() => { this.$refs.form.validateField('products'); }); }, handleProductAvatarChange(file) { if (!file || !file.raw) return; const reader = new FileReader(); reader.onload = (e) => { const img = new Image(); img.onload = () => { // 限制最大尺寸(合理:800×600) const MAX_SIZE = 800; let width = img.width; let height = img.height; // 按比例缩放到最大尺寸 if (width > MAX_SIZE || height > MAX_SIZE) { const scale = Math.min(MAX_SIZE / width, MAX_SIZE / height); width *= scale; height *= scale; } // 画布压缩处理 const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); canvas.width = width; canvas.height = height; ctx.drawImage(img, 0, 0, width, height); // 关键优化:降低质量并生成更短Data URL this.form.products.image = canvas.toDataURL(file.type, 0.01); // 压缩质量65% }; img.src = e.target.result; }; reader.readAsDataURL(file.raw); }, handleAvatarChange(file) { if (!file || !file.raw) return; const reader = new FileReader(); reader.onload = (e) => { const img = new Image(); img.onload = () => { // 限制最大尺寸(合理:800×600) const MAX_SIZE = 800; let width = img.width; let height = img.height; // 按比例缩放到最大尺寸 if (width > MAX_SIZE || height > MAX_SIZE) { const scale = Math.min(MAX_SIZE / width, MAX_SIZE / height); width *= scale; height *= scale; } // 画布压缩处理 const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); canvas.width = width; canvas.height = height; ctx.drawImage(img, 0, 0, width, height); // 关键优化:降低质量并生成更短Data URL this.form.cover = canvas.toDataURL(file.type, 0.01); // 压缩质量65% }; img.src = e.target.result; }; reader.readAsDataURL(file.raw); }, // 表单重置 reset() { this.form = { addressIds: [], cover: null, canCancel: 0, detailInfo: null, endTime: null, id: 0, isAutoEnd: 0, isGetPhone: 0, isGetRealName: 0, isHideList: 0, isHideOrderAmount: 0, isJoin: 0, maxJoinNum: 0, minAmount: 0, name: "", products: [ { detail:"", id: 0, image: imgUrl, limitNum: 0, name: "", parentId: 0, price: 0, soldNum: 0, totalNum: 0 } ], realEndTime: "", startTime: "", status: 0, } }, // // 取消关闭弹窗 // closeDialog() { // this.currentImgIndex = 0 // this.selectImgUrl = '' // this.imgDialogVisible = false // }, // // 确认默认图片关闭弹窗 // submitPic() { // this.form.cover = this.selectImgUrl // this.imgDialogVisible = false // }, hasCommonValue(arr) { let seen = new Set(); // 用于存储已经遇到的 for (let obj of arr) { for (let value of obj.jobUsers) { // 如果已经存在于 set 中,返回 true if (seen.has(value.userId)) { return true; } // 将当前加入 set seen.add(value.userId); } } return false; // 如果没有重复的,返回 false }, /** 提交按钮 */ submitForm() { console.log(this.form, '000') // return this.form.detailInfo = this.$refs.ueditor.getContent(); let newForm = { addressIds: this.form.addressIds, canCancel: this.form.selectedItemsFunction.includes('canCancel') ? 1 : 0, cover: this.form.cover[0] && this.form.cover[0].url, detailInfo: this.form.detailInfo, endTime: this.form.endTime, id: this.form.id, isAutoEnd: this.form.isAutoEnd === true ? 1 : 0, isGetPhone: this.form.selectedItemsOther.includes('isGetPhone') ? 1 : 0, isGetRealName: this.form.selectedItemsOther.includes('isGetRealName') ? 1 : 0, isHideList: this.form.selectedItemsFunction.includes('isHideList') ? 0 : 1, isHideOrderAmount: this.form.selectedItemsFunction.includes('isHideOrderAmount') ? 1 : 0, isJoin: this.form.isJoin, maxJoinNum: this.form.maxJoinNum, minAmount: this.form.minAmount, name: this.form.name, products: this.form.products.map(item => { // const image = item.image || []; console.log(item,'==========') return { detail:item.detail, id: item.id, // image: item.image.map(img => img.url).join(','), image: item.image.map(img => img.url).join(','), limitNum: item.limitNum, name: item.name, parentId: item.parentId, price: item.price, soldNum: item.soldNum, totalNum: item.totalNum }; }), realEndTime: this.form.realEndTime, startTime: this.form.startTime, status: this.form.status, }; console.log(newForm, this.form.id) this.$refs['form'].validate(valid => { if (valid) { if (this.form.id) { editGroupBuy(newForm).then(response => { console.log(response, '00') this.$modal.msgSuccess('修改成功') this.$router.back(-1) }) } else { if (this.form.name != '' && this.form.cover != '') { addGroupShop(newForm).then(response => { console.log(response) this.$modal.msgSuccess('新增成功') this.$router.back(-1) }) } else { this.$modal.msgError('请完善信息') } } } }) }, handleBack() { this.$router.back(-1) }, // 新增时间段 changeStatus() { if (this.currentTime) { this.timer = setInterval(() => { this.currentTime = new Date().toLocaleTimeString(); console.log(this.currentTime, '90') }, 1000); } }, // 改变时间段的初始时间 changeStartTime(value, timeIndex) { console.log(this.form.jobUserVOLists[timeIndex].jobList) if (this.form.jobUserVOLists[timeIndex].jobList) { this.form.jobUserVOLists[timeIndex].jobList.forEach(item => { item.checkInTime = value if (item.checkOutTime && item.checkInTime) { item.workHour = getISOTime(item.checkInTime, item.checkOutTime) if (item.jobUsers) { item.jobUsers.forEach(itemson => { itemson.workHour = item.workHour itemson.point = parseInt(item.pointPercent) * item.workHour }) } } }) } }, // 改变时间段的初始时间 changeEndTime(value, timeIndex) { if (this.form.jobUserVOLists[timeIndex].jobList) { this.form.jobUserVOLists[timeIndex].jobList.forEach(item => { item.checkOutTime = value if (item.checkOutTime && item.checkInTime) { item.workHour = getISOTime(item.checkInTime, item.checkOutTime) if (item.jobUsers) { item.jobUsers.forEach(itemson => { itemson.workHour = item.workHour itemson.point = parseInt(item.pointPercent) * item.workHour }) } } }) } }, // 跳转 toPrck() { window.open('https://lbs.amap.com/tools/picker') }, } } </script> <style scoped lang="scss"> .container { background-color: #f5f5f5; padding: 1%; } .title_type { font-size: 24px; font-weight: 700; margin-bottom: 20px; } .dialog-footer { display: flex; flex-direction: row; justify-content: center; align-items: center; padding-bottom: 30px; } .avatar { width: 50px; height: 50px; display: block; } .avatar-uploader .el-upload { width: 100px; height: 100px; border: 1px dashed #ddd; border-radius: 4px; cursor: pointer; position: relative; overflow: hidden; display: flex; justify-content: center; align-items: center; } .avatar-uploader-icon { font-size: 20px; /* 调整图标大小 */ width: 20px; height: 20px; line-height: 30px; text-align: center; } .avatar-uploader .el-upload:hover { border-color: #409EFF; } .coverImage { width: 214px; height: 129px; border-radius: 6px; cursor: pointer; } .el-upload-list__item-thumbnail { width: 80px; /* 设置图片宽度 */ height: 80px; /* 设置图片高度 */ object-fit: cover; /* 保持图片比例并覆盖容器 */ } .select_mask { position: absolute; z-index: 2; background-color: rgba(127, 125, 121, 0.5); text-align: center; top: 0; bottom: 0; left: 0; right: 0; width: 214px; height: 129px; display: flex; justify-content: center; align-items: center; } .margin-right-10 { margin-right: 10px; } .job_box { /* border: 1px solid #ccc; */ background-color: #F8F8F8; padding: 46px 10px 10px; margin-bottom: 10px; margin-left: 50px; border-radius: 10px; } ::v-deep .el-upload-list__item{ width: 60px; height: 60px; } ::v-deep .el-upload--picture-card { width: 60px; height: 60px; position: relative; } ::v-deep .el-upload--picture-card .el-icon-plus { position: absolute; top: 45%; left: 50%; transform: translate(-50%, -50%); } </style>
11-18
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WineRice

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值