(table): 新增 type 属性 radio 值 与 selectedKey 属性, 用于支持单选

This commit is contained in:
就眠儀式 2022-07-18 16:31:58 +08:00
parent 49e2d25d6d
commit e0c2664bdf
4 changed files with 149 additions and 6 deletions

View File

@ -19,6 +19,7 @@ export interface LayTableRowProps {
expandSpace: boolean; expandSpace: boolean;
expandIndex: number; expandIndex: number;
selectedKeys: Recordable[]; selectedKeys: Recordable[];
selectedKey: any;
tableColumnKeys: Recordable[]; tableColumnKeys: Recordable[];
childrenColumnName?: string; childrenColumnName?: string;
columns: Recordable[]; columns: Recordable[];
@ -37,6 +38,7 @@ const emit = defineEmits([
"row-double", "row-double",
"contextmenu", "contextmenu",
"update:selectedKeys", "update:selectedKeys",
"update:selectedKey",
]); ]);
const props = withDefaults(defineProps<LayTableRowProps>(), { const props = withDefaults(defineProps<LayTableRowProps>(), {
@ -55,6 +57,15 @@ const tableSelectedKeys: WritableComputedRef<Recordable[]> = computed({
}, },
}); });
const tableSelectedKey: WritableComputedRef<Recordable[]> = computed({
get() {
return props.selectedKey;
},
set(val) {
emit("update:selectedKey", val);
},
});
const isExpand = ref(false); const isExpand = ref(false);
const slotsData = ref<string[]>([]); const slotsData = ref<string[]>([]);
@ -182,6 +193,57 @@ const renderFixedClassName = (column: any, columnIndex: number) => {
<template v-for="(column, columnIndex) in columns" :key="columnIndex"> <template v-for="(column, columnIndex) in columns" :key="columnIndex">
<!-- 展示否 --> <!-- 展示否 -->
<template v-if="tableColumnKeys.includes(column.key)"> <template v-if="tableColumnKeys.includes(column.key)">
<template v-if="column.type == 'radio'">
<td
class="layui-table-cell"
:style="[
{
textAlign: column.align,
whiteSpace: column.ellipsisTooltip ? 'nowrap' : 'normal',
},
renderFixedStyle(column, columnIndex),
renderCellStyle(data, column, index, columnIndex),
]"
:class="[
renderFixedClassName(column, columnIndex),
renderCellClassName(data, column, index, columnIndex),
column.fixed ? `layui-table-fixed-${column.fixed}` : '',
]"
>
<!-- 树表占位与缩进 -->
<span
v-if="expandSpace && columnIndex === expandIndex"
:style="{ 'margin-right': currentIndentSize + 'px' }"
></span>
<span
v-if="
expandSpace &&
!data[childrenColumnName] &&
!slot.expand &&
columnIndex === expandIndex
"
class="layui-table-cell-expand-icon-spaced"
></span>
<lay-icon
v-if="
(slot.expand || data[childrenColumnName]) &&
columnIndex === expandIndex
"
class="layui-table-cell-expand-icon"
:type="expandIconType"
@click="handleExpand"
></lay-icon>
<lay-radio
v-model="tableSelectedKey"
:value="data[id]"
/>
</td>
</template>
<template v-if="column.type == 'checkbox'"> <template v-if="column.type == 'checkbox'">
<td <td
class="layui-table-cell" class="layui-table-cell"

View File

@ -14,6 +14,8 @@ import {
onMounted, onMounted,
onUpdated, onUpdated,
StyleValue, StyleValue,
WritableComputedRef,
computed,
} from "vue"; } from "vue";
import { v4 as uuidv4 } from "../../utils/guidUtil"; import { v4 as uuidv4 } from "../../utils/guidUtil";
import { Recordable } from "../../types"; import { Recordable } from "../../types";
@ -31,13 +33,14 @@ export interface LayTableProps {
columns: Recordable[]; columns: Recordable[];
dataSource: Recordable[]; dataSource: Recordable[];
defaultToolbar?: boolean; defaultToolbar?: boolean;
selectedKey?: any;
selectedKeys?: Recordable[]; selectedKeys?: Recordable[];
indentSize?: number; indentSize?: number;
childrenColumnName?: string; childrenColumnName?: string;
height?: number; height?: number;
maxHeight?: string; maxHeight?: string;
even?: boolean; even?: boolean;
expandIndex: number; expandIndex?: number;
rowClassName?: string | Function; rowClassName?: string | Function;
cellClassName?: string | Function; cellClassName?: string | Function;
rowStyle?: string | Function; rowStyle?: string | Function;
@ -67,6 +70,7 @@ const emit = defineEmits([
"change", "change",
"row-double", "row-double",
"update:selectedKeys", "update:selectedKeys",
"update:selectedKey",
"contextmenu", "contextmenu",
]); ]);
@ -86,6 +90,15 @@ const tableColumnKeys = ref(
}) })
); );
const tableSelectedKey: WritableComputedRef<Recordable[]> = computed({
get() {
return props.selectedKey;
},
set(val) {
emit("update:selectedKey", val);
},
});
watch( watch(
() => props.dataSource, () => props.dataSource,
() => { () => {
@ -484,6 +497,7 @@ const renderFixedClassName = (column: any, columnIndex: number) => {
@row-double="rowDoubleClick" @row-double="rowDoubleClick"
@contextmenu="contextmenu" @contextmenu="contextmenu"
v-model:selectedKeys="tableSelectedKeys" v-model:selectedKeys="tableSelectedKeys"
v-model:selectedKey="tableSelectedKey"
> >
<template v-for="name in slotsData" #[name]="{ data }"> <template v-for="name in slotsData" #[name]="{ data }">
<slot :name="name" :data="data"></slot> <slot :name="name" :data="data"></slot>

View File

@ -616,7 +616,7 @@ export default {
::: title 开启序号 ::: title 开启序号
::: :::
::: demo 通过 `fixed` 属性实现列固定, 可选值为 `left``right` ::: demo 通过 `columns` 配置 `type:'number'` 开启序号列
<template> <template>
<lay-table :columns="columns21" :dataSource="dataSource21"></lay-table> <lay-table :columns="columns21" :dataSource="dataSource21"></lay-table>
@ -680,7 +680,7 @@ export default {
::: title 开启多选 ::: title 开启多选
::: :::
::: demo 通过 `fixed` 属性实现列固定, 可选值为 `left``right` ::: demo 通过 `columns` 配置 `type:'checkbox'` 开启单选列
<template> <template>
<lay-table :columns="columns23" :dataSource="dataSource23"></lay-table> <lay-table :columns="columns23" :dataSource="dataSource23"></lay-table>
@ -746,6 +746,73 @@ export default {
::: :::
::: title 开启单选
:::
::: demo 通过 `columns` 配置 `type:'radio'` 开启单选列。
<template>
<lay-table :columns="columns24" :dataSource="dataSource24" v-model:selectedKey="selectedKey24"></lay-table>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const columns24 = [
{
title: "ID",
width: "30px",
type: "radio",
align: "center"
},
{
title:"账户",
width:"200px",
key:"username"
},{
title:"密码",
width: "300px",
key:"password"
},{
title:"性别",
width: "300px",
key:"sex"
},{
title:"年龄",
width: "300px",
key:"age"
},{
title:"备注",
width: "180px",
key:"remark",
ellipsisTooltip: true
}
]
const selectedKey24 = ref("2");
const dataSource24 = [
{id:"1",username:"root", password:"root",sex:"男", age:"18", remark: 'layui - vue谐音类 UI) '},
{id:"2",username:"root", password:"root",sex:"男", age:"18", remark: 'layui - vue谐音类 UI) '},
{id:"3",username:"woow", password:"woow",sex:"男", age:"20", remark: 'layui - vue谐音类 UI) '},
{id:"4",username:"woow", password:"woow",sex:"男", age:"20", remark: 'layui - vue谐音类 UI) '},
{id:"5",username:"woow", password:"woow",sex:"男", age:"20", remark: 'layui - vue谐音类 UI) '}
]
return {
columns24,
dataSource24,
selectedKey24,
}
}
}
</script>
:::
::: title 刷新数据 ::: title 刷新数据
::: :::
@ -796,7 +863,7 @@ export default {
]) ])
const changeDataSource22 = () => { const changeDataSource22 = () => {
dataSource21.value = [{username:"update", password:"update",sex:"boy", age:"18", remark: '更新数据 '}] dataSource22.value = [{username:"update", password:"update",sex:"boy", age:"18", remark: '更新数据 '}]
} }
return { return {

View File

@ -32,7 +32,7 @@
> >
<span <span
>{{ t("home.download") }}<em class="site-showdowns" >{{ t("home.download") }}<em class="site-showdowns"
>14,684</em >16,297</em
></span ></span
> >
</div> </div>
@ -43,7 +43,7 @@
rel="nofollow" rel="nofollow"
class="site-star" class="site-star"
> >
<i class="layui-icon"></i> Star <cite id="getStars">1296</cite> <i class="layui-icon"></i> Star <cite id="getStars">1326</cite>
</a> </a>
<a <a
href="https://gitee.com/layui-vue" href="https://gitee.com/layui-vue"