From a56bc3ed9f2034b9c1ffbb76885cdd0530c13dfe Mon Sep 17 00:00:00 2001 From: Jevin Date: Tue, 8 Jul 2025 13:57:28 +0800 Subject: [PATCH 1/2] =?UTF-8?q?fix(table):=20=E6=B8=85=E7=A9=BAdataSource?= =?UTF-8?q?=E4=B8=8EselectedKeys=E5=90=8C=E6=97=B6=E8=BF=9B=E8=A1=8C?= =?UTF-8?q?=EF=BC=8CselectedKeys=E6=B8=85=E7=A9=BA=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../component/table/__tests__/table.test.tsx | 84 ++++++++++++++++++- .../component/table/hooks/useTableSelected.ts | 41 +++++---- packages/component/utils/arrayUtil.ts | 38 ++++----- 3 files changed, 116 insertions(+), 47 deletions(-) diff --git a/packages/component/component/table/__tests__/table.test.tsx b/packages/component/component/table/__tests__/table.test.tsx index d52917be..e12f8987 100644 --- a/packages/component/component/table/__tests__/table.test.tsx +++ b/packages/component/component/table/__tests__/table.test.tsx @@ -1,10 +1,10 @@ import { DOMWrapper, type VueWrapper, mount } from "@vue/test-utils"; import LayTable from "../index.vue"; import LayCheckboxV2 from "@layui/component/component/checkboxV2/index.vue"; -import Button from '@layui/component/component/button/index.vue' +import LayButton from '@layui/component/component/button/index.vue' import { describe, expect, test, vi } from "vitest"; -import {h, nextTick, reactive, ref} from "vue"; +import {h, nextTick, reactive, ref, watch} from "vue"; import { sleep } from "../../../test-utils"; describe("LayTable", () => { @@ -533,7 +533,7 @@ describe("LayTable", () => { const defaultToolbars = [ "filter", { - render: () => h(Button, { + render: () => h(LayButton, { onClick: () => { value++; }, @@ -942,4 +942,82 @@ describe("LayTable", () => { expect(_class).toMatch(/layui-table-fixed-left-last/) }); + + // https://gitee.com/layui-vue/layui-vue/issues/ICKILA + test("selectedKeys制空未生效", async () => { + const columns = reactive([ + { type: "checkbox", title: "复选" }, + { title: "用户", width: "80px", key: "name" }, + ]); + + const dataSource = ref([]); + const selectedKeys = ref([]); + + + watch([dataSource], () => { + selectedKeys.value = [] + }); + + function generateData1() { + dataSource.value = [ + { id: "3", name: "张三3", city: "城市-3", sex: "男", age: "20", remark: "屈指古今多少事,都只是、镜中春", score: 100, sign: "已签到", joinTime: "2022-02-09" }, + { id: "4", name: "张三4", city: "城市-4", sex: "男", age: "20", remark: "屈指古今多少事,都只是、镜中春", score: 100, sign: "已签到", joinTime: "2022-02-09" }, + { id: "5", name: "张三5", city: "城市-5", sex: "男", age: "20", remark: "屈指古今多少事,都只是、镜中春", score: 100, sign: "已签到", joinTime: "2022-02-09" } + ]; + } + + function generateData2() { + dataSource.value = [ + { id: "9", name: "张三9", city: "城市-9", sex: "男", age: "20", remark: "屈指古今多少事,都只是、镜中春", score: 100, sign: "已签到", joinTime: "2022-02-09" }, + { id: "10", name: "张三10", city: "城市-10", sex: "男", age: "18", remark: "屈指古今多少事,都只是、镜中春", score: 100, sign: "已签到", joinTime: "2022-02-09" }, + { id: "11", name: "张三11", city: "城市-11", sex: "男", age: "18", remark: "屈指古今多少事,都只是、镜中春", score: 100, sign: "已签到", joinTime: "2022-02-09" }, + { id: "12", name: "张三12", city: "城市-12", sex: "男", age: "20", remark: "屈指古今多少事,都只是、镜中春", score: 100, sign: "已签到", joinTime: "2022-02-09" }, + ]; + } + + + + const wrapper = mount({ + setup() { + return () => ( +
+ + 数据1 + + + 数据2 + + +
+ ); + }, + }); + + await nextTick() + + const btn1 = wrapper.find('.custom-btn1') + const btn2 = wrapper.find('.custom-btn2') + + await btn1.trigger('click') + + const trs1 = wrapper.findAll('.layui-table-body .layui-table tbody tr') + expect(trs1.length).toBe(3) + + await trs1[0].findComponent('.layui-checkbox').trigger('click') + expect(selectedKeys.value.length).toBe(1) + + await trs1[1].findComponent('.layui-checkbox').trigger('click') + expect(selectedKeys.value.length).toBe(2) + + await btn2.trigger('click') + const trs2 = wrapper.findAll('.layui-table-body .layui-table tbody tr') + expect(trs2.length).toBe(4) + + expect(selectedKeys.value.length).toBe(0) + + }); }); diff --git a/packages/component/component/table/hooks/useTableSelected.ts b/packages/component/component/table/hooks/useTableSelected.ts index 0209dce0..b544fbb8 100644 --- a/packages/component/component/table/hooks/useTableSelected.ts +++ b/packages/component/component/table/hooks/useTableSelected.ts @@ -1,5 +1,5 @@ import type { RequiredTableProps, TableEmit } from "../typing"; -import { isValueArray, loopForEach } from "@layui/component/utils"; +import { arrayEverySame, isValueArray, loopForEach } from "@layui/component/utils"; import { computed, reactive, ref, toRaw, watch } from "vue"; @@ -24,14 +24,9 @@ export function useTableSelected(props: RequiredTableProps, emit: TableEmit) { emit("update:selectedKey", key); } - /** - * Multiple checkbox - */ - const allMSelected = ref(false); - const someMSelected = ref(false); const tableMSelectedKeys = reactive< NonNullable - >([]); + >(props.selectedKeys); const allKeys = computed(() => { const keys: RequiredTableProps["selectedKeys"] = []; @@ -59,29 +54,33 @@ export function useTableSelected(props: RequiredTableProps, emit: TableEmit) { ); }, { - immediate: true, deep: true, }, ); - watch( - () => [tableMSelectedKeys, allKeys.value], - ([tableMultipleSelectedKeysValue, allKeysValue]) => { - allMSelected.value = allKeysValue.length > 0 && allKeysValue.every(key => - tableMultipleSelectedKeysValue.includes(key), - ); - someMSelected.value = allKeysValue.length > 0 && allKeysValue.some(key => - tableMultipleSelectedKeysValue.includes(key), - ); + /** + * Multiple checkbox + */ + const allMSelected = computed(() => { + return allKeys.value.length > 0 && allKeys.value.every(key => + tableMSelectedKeys.includes(key), + ); + }); - if ( - tableMultipleSelectedKeysValue.length !== props.selectedKeys?.length - ) { + const someMSelected = computed(() => { + return allKeys.value.length > 0 && allKeys.value.some(key => + tableMSelectedKeys.includes(key), + ); + }); + + watch( + tableMSelectedKeys, + (tableMultipleSelectedKeysValue) => { + if (!arrayEverySame(tableMultipleSelectedKeysValue, props.selectedKeys)) { emit("update:selectedKeys", [...tableMultipleSelectedKeysValue]); } }, { - immediate: true, deep: true, }, ); diff --git a/packages/component/utils/arrayUtil.ts b/packages/component/utils/arrayUtil.ts index 54bf6582..a6a4389e 100644 --- a/packages/component/utils/arrayUtil.ts +++ b/packages/component/utils/arrayUtil.ts @@ -1,26 +1,12 @@ import { isFunction, isNumber } from "./type"; -export const check = (arr: any[], value: any) => { - return arr.indexOf(value) > -1; -}; - -/** - * 计算数组差异 - * - * @param arr1 数组 - * @param arr2 数组 - */ -function diff(arr1: any[], arr2: any[]) { - let newArr = []; - arr1 = Array.from(new Set(arr1)); // 去重 - arr2 = Array.from(new Set(arr2)); // 去重 - newArr = arr1.concat(arr2); - return newArr.filter((x) => !(arr1.includes(x) && arr2.includes(x))); +export function check(arr: any[], value: any) { + return arr.includes(value); } -export const isValueNull = (v: any) => { +export function isValueNull(v: any) { return Array.isArray(v) ? !v.length : !v; -}; +} export function isArray(val: any): val is Array { return val && Array.isArray(val); @@ -58,9 +44,10 @@ export function loopForEach( array: any[] | undefined, children: string | loopForEachCallback, callback: loopForEachCallback, - parent?: any + parent?: any, ) { - if (!isValueArray(array)) return; + if (!isValueArray(array)) + return; let _children: string; let _callback: callback[]; @@ -70,12 +57,13 @@ export function loopForEach( _children = "children"; _callback = isFunction(children) ? [children] : children; _parent = callback; - } else { + } + else { _children = children; _callback = isFunction(callback) ? [callback] : callback; } - if (!isValueArray(_callback) || _callback.some((cb) => !isFunction(cb))) + if (!isValueArray(_callback) || _callback.some(cb => !isFunction(cb))) return; for (let index = 0; index < array.length; index++) { @@ -106,7 +94,7 @@ export function loopSomeLevelALLChildren( export function loopSomeLevelALLChildren( lists: any[], childrenKey: string | number, - level = 1 + level = 1, ): any[] { let _childrenKey: string; let _level: number = level; @@ -134,3 +122,7 @@ export function loopSomeLevelALLChildren( return result; } + +export function arrayEverySame(arr1: T, arr2: T): boolean { + return arr1.every(i => arr2.includes(i)) && arr2.every(i => arr1.includes(i)); +} From 2081922f5afbc80dcd7aae2179b097ae0155d716 Mon Sep 17 00:00:00 2001 From: Jevin Date: Tue, 8 Jul 2025 16:35:00 +0800 Subject: [PATCH 2/2] chore: updat test --- .../component/table/__tests__/table.test.tsx | 57 +++++++++---------- 1 file changed, 27 insertions(+), 30 deletions(-) diff --git a/packages/component/component/table/__tests__/table.test.tsx b/packages/component/component/table/__tests__/table.test.tsx index e12f8987..11d5a5ea 100644 --- a/packages/component/component/table/__tests__/table.test.tsx +++ b/packages/component/component/table/__tests__/table.test.tsx @@ -945,40 +945,38 @@ describe("LayTable", () => { // https://gitee.com/layui-vue/layui-vue/issues/ICKILA test("selectedKeys制空未生效", async () => { - const columns = reactive([ - { type: "checkbox", title: "复选" }, - { title: "用户", width: "80px", key: "name" }, - ]); - const dataSource = ref([]); const selectedKeys = ref([]); - - watch([dataSource], () => { - selectedKeys.value = [] - }); - - function generateData1() { - dataSource.value = [ - { id: "3", name: "张三3", city: "城市-3", sex: "男", age: "20", remark: "屈指古今多少事,都只是、镜中春", score: 100, sign: "已签到", joinTime: "2022-02-09" }, - { id: "4", name: "张三4", city: "城市-4", sex: "男", age: "20", remark: "屈指古今多少事,都只是、镜中春", score: 100, sign: "已签到", joinTime: "2022-02-09" }, - { id: "5", name: "张三5", city: "城市-5", sex: "男", age: "20", remark: "屈指古今多少事,都只是、镜中春", score: 100, sign: "已签到", joinTime: "2022-02-09" } - ]; - } - - function generateData2() { - dataSource.value = [ - { id: "9", name: "张三9", city: "城市-9", sex: "男", age: "20", remark: "屈指古今多少事,都只是、镜中春", score: 100, sign: "已签到", joinTime: "2022-02-09" }, - { id: "10", name: "张三10", city: "城市-10", sex: "男", age: "18", remark: "屈指古今多少事,都只是、镜中春", score: 100, sign: "已签到", joinTime: "2022-02-09" }, - { id: "11", name: "张三11", city: "城市-11", sex: "男", age: "18", remark: "屈指古今多少事,都只是、镜中春", score: 100, sign: "已签到", joinTime: "2022-02-09" }, - { id: "12", name: "张三12", city: "城市-12", sex: "男", age: "20", remark: "屈指古今多少事,都只是、镜中春", score: 100, sign: "已签到", joinTime: "2022-02-09" }, - ]; - } - - - const wrapper = mount({ setup() { + const columns = reactive([ + { type: "checkbox", title: "复选" }, + { title: "用户", width: "80px", key: "name" }, + ]); + const dataSource = ref([]); + + function generateData1() { + dataSource.value = [ + { id: "3", name: "张三3", city: "城市-3", sex: "男", age: "20", remark: "屈指古今多少事,都只是、镜中春", score: 100, sign: "已签到", joinTime: "2022-02-09" }, + { id: "4", name: "张三4", city: "城市-4", sex: "男", age: "20", remark: "屈指古今多少事,都只是、镜中春", score: 100, sign: "已签到", joinTime: "2022-02-09" }, + { id: "5", name: "张三5", city: "城市-5", sex: "男", age: "20", remark: "屈指古今多少事,都只是、镜中春", score: 100, sign: "已签到", joinTime: "2022-02-09" } + ]; + } + + function generateData2() { + dataSource.value = [ + { id: "9", name: "张三9", city: "城市-9", sex: "男", age: "20", remark: "屈指古今多少事,都只是、镜中春", score: 100, sign: "已签到", joinTime: "2022-02-09" }, + { id: "10", name: "张三10", city: "城市-10", sex: "男", age: "18", remark: "屈指古今多少事,都只是、镜中春", score: 100, sign: "已签到", joinTime: "2022-02-09" }, + { id: "11", name: "张三11", city: "城市-11", sex: "男", age: "18", remark: "屈指古今多少事,都只是、镜中春", score: 100, sign: "已签到", joinTime: "2022-02-09" }, + { id: "12", name: "张三12", city: "城市-12", sex: "男", age: "20", remark: "屈指古今多少事,都只是、镜中春", score: 100, sign: "已签到", joinTime: "2022-02-09" }, + ]; + } + + watch([dataSource], () => { + selectedKeys.value = [] + }); + return () => (
@@ -1018,6 +1016,5 @@ describe("LayTable", () => { expect(trs2.length).toBe(4) expect(selectedKeys.value.length).toBe(0) - }); }); pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy