vue3 elementui 表格组件,过滤多选回显问题?

各位老师好, 我遇到的问题描述一下:

1 在表格组件上添加搜索
2 过滤表格组件后,选择表格内容保存后之前表格所选的内容丢失
3 清除过滤字符后,表格不能回显过滤之前已经选择的条目,

下面我的组件里面的代码,请老师们指导,感谢感谢:

<template>
    <el-input v-model="searchRole" placeholder="输入角色名搜索" clearable />
    <el-table ref="multipleTableRef" :data="tableData" style="width: 100%" @selection-change="handleSelectionChange">
        <el-table-column type="selection" width="55" />
        <el-table-column prop="roleName" label="名称" />
        <el-table-column prop="sourceName" label="来源" />
    </el-table>
</template>

<script lang="ts" setup>
import { onMounted, ref, watch, computed } from 'vue'
import { ElTable } from 'element-plus'
import { cloneDeep } from 'lodash'
import { fetchRoleList } from '@/apis/account/role'
import { fetchAccountRoles, updateAccountRoles } from '@/apis/account/account'

const props = defineProps({
    accountId: String
})

const searchRole = ref('')
const tableData = computed(() => {
    if (roleList.value.length) {
        return roleList.value.filter(data => !searchRole.value || data.roleName.toLowerCase().includes(searchRole.value.toLowerCase()))
    }
    return []
})

const multipleTableRef = ref<InstanceType<typeof ElTable>>()
const multipleSelection = ref([])
const handleSelectionChange = val => {
    multipleSelection.value = val
    console.log("multipleSelection.value",multipleSelection.value)
}
const remDuplicateObj = arr => {
    let newArr = []
    let obj = {}
    for (let i = 0; i < arr.length; i++) {
        if (!obj[arr[i].id]) {
            newArr.push(arr[i])
            obj[arr[i].id] = true
        }
    }
    return newArr
}

const roleList = ref([])
async function getRoles() {
    const res = await fetchRoleList(null)
    if (!res) return
    roleList.value = res.content
    getAccountRoles()
}

const accountRoles = ref([])
async function getAccountRoles() {
    const res = await fetchAccountRoles(props.accountId)
    if (!res) return
    accountRoles.value = cloneDeep(res.content)
    toggleSelection(res.content)
}

const toggleSelection = rows => {
    if (!rows) return
    // if (!multipleSelection.value) return
    const roleNames = rows.map(val => val.roleName)
    // const roleNames = multipleSelection.value.map(val => val.roleName)
    if (roleNames) {
        roleList.value.forEach(row => {
            if (roleNames.includes(row.roleName)) {
                // TODO: improvement typing when refactor table
                // eslint-disable-next-line @typescript-eslint/ban-ts-comment
                multipleTableRef.value!.toggleRowSelection(row, true)
            }
        })
    } else {
        multipleTableRef.value!.clearSelection()
    }
}

const submitRoles = async () => {
    return new Promise<void>(async (resolve, reject) => {
        try {
            const data = {
                roles: multipleSelection.value.map(val => val.roleName)
            }
            await updateAccountRoles(props.accountId, data)
            emit('changed', false)
            getAccountRoles()
            resolve()
        } catch (error) {
            reject()
        }
    })
}

const emit = defineEmits(['changed'])
watch(
    [() => multipleSelection.value],
    () => {
        const newRoles = multipleSelection.value.map(v => v.roleName)
        const oldRoles = accountRoles.value.map(v => v.roleName)
        const hasChanged = JSON.stringify(newRoles) !== JSON.stringify(oldRoles)
        emit('changed', hasChanged)
    },
    {
        deep: true
    }
)

onMounted(() => {
    getRoles()
})

defineExpose({
    submitRoles
})
</script>
阅读 2.3k
3 个回答

不要用selection-change事件,那个在数据变更时会清空,改用select事件,然后在变更时在nextTick中把上一次选中的accountRoles传入toggleSelection调用

每次获取表格数据后 使用toggleRowSelection初始化已经勾选的

<template>
  <el-input v-model="searchRole" placeholder="输入角色名搜索" clearable />
  <el-table
    ref="multipleTableRef"
    :data="tableData"
    style="width: 100%"
    @selection-change="handleSelectionChange"
  >
    <el-table-column type="selection" width="55" />
    <el-table-column prop="roleName" label="名称" />
    <el-table-column prop="sourceName" label="来源" />
  </el-table>
</template>

<script lang="ts" setup>
import { onMounted, ref, watch, computed } from "vue";
import { ElTable } from "element-plus";
import { cloneDeep } from "lodash";
import { fetchRoleList } from "@/apis/account/role";
import { fetchAccountRoles, updateAccountRoles } from "@/apis/account/account";

const props = defineProps({
  accountId: String,
});

const searchRole = ref("");
const selectedRows = ref([]);
const tableData = computed(() => {
  if (roleList.value.length) {
    return roleList.value.filter(
      (data) =>
        !searchRole.value ||
        data.roleName
          .toLowerCase()
          .includes(searchRole.value.toLowerCase())
    );
  }
  return [];
});

const multipleTableRef = ref();

const handleSelectionChange = (val) => {
  selectedRows.value = val;
};

watch(searchRole, () => {
  const selectedRowKeys = selectedRows.value.map((row) => row.id);
  const rowsToSelect = tableData.value.filter((row) =>
    selectedRowKeys.includes(row.id)
  );
  multipleTableRef.value.clearSelection();
  rowsToSelect.forEach((row) => {
    multipleTableRef.value.toggleRowSelection(row, true);
  });
});
</script>
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏