tabs页签嵌套表格,切换表格保存数据不变并回勾

发布于:2025-06-13 ⋅ 阅读:(23) ⋅ 点赞:(0)

需求:点击左边的tab页签,请求右侧表格数据;如果返回的接口数据存在taskuser字段并不为null,那么按照这个字段去回勾数据。如果存在数据,但与后面所勾选的数据项不同,按照后面勾选的为主。

    <el-tabs tab-position="left" v-model="dialogInfo.activeTab" style="height: 350px" class="demo-tabs" @tab-change="tabChange">
      <el-tab-pane v-for="tab in dialogInfo.tabs" :key="tab.id" :label="tab.text" :name="tab.text">
        <div class="tableDiv">
          <el-table
            ref="refTableV"
            :data="tableConfig.tableData"
            :header-cell-style="{ background: '#F5F7FA', height: '30px' }"
            style="width: 100%; margin: 0 auto"
            height="100%"
            align="center"
            row-key="empName"
            stripe
            border
            @select="select"
          >
            <el-table-column type="selection" width="40" fixed label="操作" />
            <el-table-column fixed prop="userName" label="用户编号" width="120" align="center" />
            <el-table-column fixed prop="empName" label="用户姓名" min-width="150" align="center" />
            <el-table-column fixed prop="expiresdate" label="过期日期" min-width="150" align="center">
              <template v-slot="scope">
                <el-date-picker
                  v-if="dialogInfo.tabs[dialogInfo.activeTabIndex].allot?.empName === scope.row.empName"
                  v-model="scope.row.expiresdate"
                  type="date"
                  placeholder="选择日期"
                  size="small"
                  @change="handleDateChange(scope.row)"
                  value-format="YYYY-MM-DD"
                />
                <span v-else @click="changeLeader(scope.row)">{{ scope.row.expiresdate || '' }}</span>
              </template>
            </el-table-column>
            <el-table-column fixed prop="leaderNames" label="直接领导" min-width="150" align="center">
              <template v-slot="scope">
                <span v-if="scope.row.leaderNames && scope.row.leaderNames !== ''" size="small" @click="leaderSearch(scope.row)">
                  {{ scope.row.leaderNames || '选择领导' }}
                </span>
                <span v-else-if="dialogInfo.tabs[dialogInfo.activeTabIndex].allot?.empName === scope.row.empName">
                  <el-button size="small" @click="leaderSearch(scope.row)">{{ '选择领导' }}</el-button>
                </span>
              </template>
            </el-table-column>
          </el-table>
        </div>
      </el-tab-pane>
    </el-tabs>
const refTableV = ref(null) //表格
const refTree = ref(null)
const dialogInfo = reactive({
  tabs: [],
  dialogText: '任务分配',
  dialogFormVisible: false,
  activeTab: '',
  searchstrId: '',
  list: [],
  treeLearder: {},
  str: []
})

const tableConfig = reactive({
  allot: {},
  tableData: [],
  loading: false,
  page: 1,
  selectedData: [], // 存储当前勾选的数据项
  lastSelectedRow: {},
  paramsData: {},
  activeTabIndex: 0
})

 首先openInit 这个方法是我打开弹层的第一步,tabs数据是左侧的角色信息;我会给每一项的tab数据添加selectedData和allot 这个在后面取值会用到。

const openInit = (list) => {
  dialogInfo.str = []
  list.forEach((item) => dialogInfo.str.push(item.factory + ',' + item.materialscode))
  tableConfig.selectedData = [] // 存储当前勾选的数据项
  tableConfig.lastSelectedRow = {}
  tableConfig.allot = {}
  dialogInfo.list = JSON.parse(JSON.stringify(list))
  dialogInfo.treeLearder = {}
  getPropertyList({
    searchstr: {
      taskType: 'SPAREPARTSTASKROLE'
    }
  }).then((res) => {
    const tabs = res.data.rows || []
    dialogInfo.searchstrId = ''
    if (tabs.length > 0) {
      dialogInfo.searchstrId = tabs[0].id
      dialogInfo.activeTab = tabs[0].text
      tabs.forEach((row) => {
        row.selectedData = []
        row.allot = {}
      })
      dialogInfo.tabs = tabs
      dialogInfo.activeTabIndex = 0
      dialogInfo.dialogFormVisible = true
      getTable() // 获取表格数据
    }
  })
}

const getTable = () => {
  preTaskAssign({
    searchstr: {
      id: dialogInfo.searchstrId,
      eventcodes: dialogInfo.str.join(';')
    }
  }).then((res) => {
    const tableData = res.data.row?.teapSysUserEntityList || []
    const taskuser = res.data.row?.taskuser || ''

    refTableV.value[dialogInfo.activeTabIndex].clearSelection()
    const strLength = dialogInfo.str.length

    if (strLength === 1) {
      if (tableData && tableData.length > 0) {
        tableData.forEach((newRow) => {
          if (newRow.userName === taskuser) {
            dialogInfo.tabs[dialogInfo.activeTabIndex].selectedData = [newRow]
            dialogInfo.tabs[dialogInfo.activeTabIndex].allot = newRow
            nextTick(() => {
              refTableV.value[dialogInfo.activeTabIndex].toggleRowSelection(newRow, true)
            })
          }
        })
      }
    }
    tableConfig.tableData = tableData
  })
}

代码主要就是针对勾选数据 保存数据,切换tab页签 再次回来后数据的勾选处理 

const select = (selectedRows) => {
  // 获取当前 tab 的数据
  const currentTab = dialogInfo.tabs[dialogInfo.activeTabIndex]
  refTableV.value[dialogInfo.activeTabIndex].clearSelection()

  // 清空上一次选中的数据
  currentTab.selectedData = []
  currentTab.allot = {}

  // 更新当前 tab 的 selectedData 和 allot
  if (selectedRows.length === 1) {
    currentTab.selectedData = selectedRows
    currentTab.allot = selectedRows[0] // 如果有 allot 数据,更新为第一个选中的数据
    nextTick(() => {
      refTableV.value[dialogInfo.activeTabIndex].toggleRowSelection(currentTab.allot, true)
    })
  } else {
    ElMessage.warning('只能选择一条数据,请取消已勾选项后再进行选择')
  }

  // 更新当前 tab 的 selectedData 和 allot
  dialogInfo.tabs[dialogInfo.activeTabIndex] = currentTab
}

// 选择领导的弹层
const tabChange = (name) => {
  // 查找当前 tab 索引
  dialogInfo.activeTab = name
  dialogInfo.searchstrId = dialogInfo.tabs.find((item) => item.text === name).id

  let index = null
  dialogInfo.tabs.some((item, ind) => {
    if (item.text === name) {
      index = ind
      return true // 找到就停止遍历
    }
    return false
  })

  dialogInfo.activeTabIndex = index
  const currentTab = dialogInfo.tabs[index]

  // 保存当前勾选状态
  const { selectedData, allot } = currentTab

  // 在切换 tab 时,将勾选状态存储到 dialogInfo 中
  dialogInfo.tabs[index].selectedData = selectedData || []
  dialogInfo.tabs[index].allot = allot || {}

  // 重新加载当前 tab 的数据,保持选中状态
  preTaskAssign({
    searchstr: {
      id: dialogInfo.searchstrId,
      eventcodes: dialogInfo.str.join(';') // 外面行勾选的数据 工厂加物料编号传字符串
    }
  }).then((res) => {
    // 获取从接口返回的表格数据
    const tableDataList = res.data.row?.teapSysUserEntityList || []
    const taskuser = res.data.row?.taskuser || ''

    // 更新表格数据
    tableConfig.tableData = tableDataList
    refTableV.value[dialogInfo.activeTabIndex].clearSelection()

    // 使用一些逻辑优化遍历,找到合适的行就停止
    let isFound = false

    tableDataList.forEach((row) => {
      if (isFound) return // 如果已经找到匹配项,直接跳过后续行

      const selectedUserName = selectedData[0]?.userName

      if (taskuser) {
        if (selectedData.length === 0) {
          // 1. 如果有taskuser但是selectedData为空,依照taskuser去筛选数据
          if (row.userName === taskuser) {
            dialogInfo.tabs[dialogInfo.activeTabIndex].selectedData = [row]
            dialogInfo.tabs[dialogInfo.activeTabIndex].allot = row
            nextTick(() => {
              refTableV.value[dialogInfo.activeTabIndex].toggleRowSelection(row, true)
            })
            isFound = true // 标记为已找到匹配项,跳出循环
          }
        } else if (selectedUserName !== taskuser) {
          // 2. 如果同时存在,但是匹配不上,那么按照selectedData中的数据去筛选
          if (row.userName === selectedUserName) {
            dialogInfo.tabs[dialogInfo.activeTabIndex].selectedData = [row]
            dialogInfo.tabs[dialogInfo.activeTabIndex].allot = row
            nextTick(() => {
              refTableV.value[dialogInfo.activeTabIndex].toggleRowSelection(row, true)
            })
            isFound = true // 标记为已找到匹配项,跳出循环
          }
        } else if (selectedUserName === taskuser) {
          // 3. 如果同时存在,匹配的上,按照taskuser判断
          nextTick(() => {
            const selectedRow = dialogInfo.tabs[dialogInfo.activeTabIndex].selectedData[0]
            refTableV.value[dialogInfo.activeTabIndex].toggleRowSelection(selectedRow, true)
          })
          isFound = true // 标记为已找到匹配项,跳出循环
        }
      } else {
        // 4. taskuser不存在,按照selectedData去筛选
        if (row.userName === selectedUserName) {
          dialogInfo.tabs[dialogInfo.activeTabIndex].selectedData = [row]
          dialogInfo.tabs[dialogInfo.activeTabIndex].allot = row
          nextTick(() => {
            refTableV.value[dialogInfo.activeTabIndex].toggleRowSelection(row, true)
          })
          isFound = true // 标记为已找到匹配项,跳出循环
        }
      }
    })
  })
}

const leaderSearch = (row) => {
  // 查找与勾选行对应的数据
  const exObj = tableConfig.tableData.find((item) => item.userId === dialogInfo.tabs[dialogInfo.activeTabIndex].allot.userId)
  // 检查过期日期是否为空
  if (exObj.expiresdate === '' || exObj.expiresdate == null) return ElMessage.warning('请先设置时间')
  const str = dialogInfo.tabs[dialogInfo.activeTabIndex].id // 这个就是左边角色的id
  refTree.value.openInit(JSON.parse(JSON.stringify(row)), str)
}


网站公告

今日签到

点亮在社区的每一天
去签到