Skip to content

Commit c723daf

Browse files
authored
Merge pull request #3698 from VisActor/develop
merge develop
2 parents 81563b7 + 4a018fd commit c723daf

4 files changed

Lines changed: 315 additions & 269 deletions

File tree

docs/assets/demo-vue/en/custom-layout/cell-dom-component.md

Lines changed: 60 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -9,40 +9,76 @@ link: custom_define/vue-dom-component
99

1010
# Cell Rendering DOM Components
1111

12-
In `vue-vtable`, it is possible to directly render DOM components within cells, allowing for the easy embedding of complex Vue components to achieve highly customized table display effects. Two forms are supported: **slot-based** and **directly passing into the `column` configuration**. Both methods require wrapping with the `Group` component.
12+
In `vue-vtable`, you can directly render DOM components within table cells, enabling seamless integration of complex Vue components for highly customizable table displays. Two approaches are supported: **slot-based** and **directly passing components into the `column` configuration**. Both methods require wrapping components with the `Group` component.
1313

14-
Detailed Explanation:
14+
**🛠️ Core configuration steps: Enable DOM component rendering**
1515

16-
**Key point 1. Enabling the Feature**
16+
To render DOM components in `vue-vtable`, follow these key steps:
1717

18-
In `vue-vtable`, rendering DOM components requires two key steps:
18+
- **Pass the `vue` property to the `Group` component**: This allows the `Group` component to recognize and process Vue components.
19+
- **Enable `customConfig.createReactContainer`**: This configuration creates a table container to ensure Vue components render correctly within the table.
1920

20-
- **Pass the `vue` property in the `Group` component**: This allows the `Group` component to recognize and handle Vue components.
21-
- **Enable `customConfig.createReactContainer`**: This configuration item is used to create a table container, ensuring that Vue components can be correctly rendered into the table container.
21+
**✨ Method 1: Slot-Based Rendering**
2222

23-
**Key point 2. Slot-Based Rendering**
23+
Slot-based rendering uses the `headerCustomLayout` and `customLayout` slots of the `ListColumn` component. Custom components must be wrapped in the `Group` component.
2424

25-
Slot-based rendering is achieved through the two slots `headerCustomLayout` and `customLayout` of the `ListColumn` component. Custom components need to be wrapped with the `Group` component.
25+
- **`headerCustomLayout`**: Customizes header cell rendering.
26+
- **`customLayout`**: Customizes body cell rendering.
2627

27-
- **`headerCustomLayout`**: Used for custom rendering of header cells.
28-
- **`customLayout`**: Used for custom rendering of body cells.
28+
**✨ Method 2: Direct Configuration-Based Rendering**
2929

30-
**Key point 3. Direct Configuration-Based Rendering**
30+
This method is similar to slot-based rendering but does not use slots. Instead, directly pass virtual nodes via the `element` property in the `column.headerCustomLayout` or `column.customLayout` configuration. The usage aligns with [Custom Components](../../guide/custom_define/custom_layout).
3131

32-
Direct configuration-based rendering is similar to slot-based rendering, with the difference being that you do not need to pass components through slots. Instead, you directly pass virtual nodes in the `element` property of the `column.headerCustomLayout` or `column.customLayout` configuration. The usage is largely the same as with [custom components](../../guide/custom_define/custom_layout).
32+
**⚠️ Notes**
3333

34-
## Code Demonstration
34+
- **Enabling Interactions**: If custom cells require mouse interactions, manually enable `pointer-events`. See the example below.
3535

36-
```javascript livedemo template=vtable-vue
37-
38-
// In the code demonstration, we show how to render custom Vue components within the table. Specifically, it includes:
36+
## Code Demo
3937

40-
// - **Gender Column**: Uses the `ArcoDesignVue.Tag` component to render gender information and dynamically changes the tag color based on the gender value.
41-
// - **Comment Column**: Uses the `ArcoDesignVue.Comment` component to render comment information, including like, collect, and reply action buttons.
38+
```javascript livedemo template=vtable-vue
39+
// In this demo, we show how to render custom Vue components in the table. Specifically:
40+
// - **Gender Column**: Renders gender headers using the `ArcoDesignVue.Tag` component.
41+
// - **Comment Column**: Renders comments with the `ArcoDesignVue.Comment` component, including action buttons for likes, favorites, and replies.
4242

4343
const app = createApp({
4444
template: `
45-
<vue-list-table :options="option" :records="records" ref="tableRef" />
45+
<vue-list-table :options="option" :records="records" ref="tableRef">
46+
<ListColumn field="name" title="Name" width="200" />
47+
<ListColumn field="age" title="Age" width="150" />
48+
<ListColumn field="city" title="City" width="150" />
49+
<ListColumn field="gender" title="Gender" width="100">
50+
<template #headerCustomLayout="{ width, height }">
51+
<Group :width="width" :height="height" display="flex" align-items="center" :vue="{}">
52+
<ATag color="green"> Gender </ATag>
53+
</Group>
54+
</template>
55+
</ListColumn>
56+
<ListColumn field="comment" title="Comment" width="300">
57+
<template #customLayout="{ width, height, record }">
58+
<Group :width="width" :height="height" display="flex" align-items="center" :vue="{}">
59+
<AComment author="Socrates" :content="record['comment']" datetime="1 hour">
60+
<template #actions>
61+
<span key="heart" style="cursor: pointer; pointer-events: auto">
62+
{{ 83 }}
63+
</span>
64+
<span key="star" style="cursor: pointer; pointer-events: auto">
65+
{{ 3 }}
66+
</span>
67+
<span key="reply" style="cursor: pointer; pointer-events: auto"> Reply </span>
68+
</template>
69+
<template #avatar>
70+
<AAvatar>
71+
<img
72+
alt="avatar"
73+
src="https://p1-arco.byteimg.com/tos-cn-i-uwbnlip3yd/3ee5f13fb09879ecb5185e440cef6eb9.png~tplv-uwbnlip3yd-webp.webp"
74+
/>
75+
</AAvatar>
76+
</template>
77+
</AComment>
78+
</Group>
79+
</template>
80+
</ListColumn>
81+
</vue-list-table>
4682
`,
4783
data() {
4884
return {
@@ -57,108 +93,6 @@ const app = createApp({
5793
{ gender: 'Female', name: 'Zhou Ba', age: 25, city: 'Chongqing' },
5894
{ gender: 'Male', name: 'Wu Jiu', age: 26, city: "Xi'an" }
5995
],
60-
columns: [
61-
{
62-
field: 'name',
63-
title: 'Name',
64-
width: 200
65-
},
66-
{ field: 'age', title: 'Age', width: 150 },
67-
{ field: 'city', title: 'City', width: 200 },
68-
{
69-
field: 'gender',
70-
title: 'Gender',
71-
width: 100,
72-
headerCustomLayout: args => {
73-
const { table, row, col, rect, value } = args;
74-
const { height, width } = rect ?? table.getCellRect(col, row);
75-
76-
const container = new VTable.CustomLayout.Group({
77-
height,
78-
width,
79-
display: 'flex',
80-
alignItems: 'center',
81-
vue: {
82-
element: h(ArcoDesignVue.Tag, { color: 'green' }, value),
83-
container: table.headerDomContainer
84-
}
85-
});
86-
return {
87-
rootContainer: container,
88-
renderDefault: false
89-
};
90-
},
91-
customLayout: args => {
92-
const { table, row, col, rect, value } = args;
93-
const { height, width } = rect ?? table.getCellRect(col, row);
94-
95-
const container = new VTable.CustomLayout.Group({
96-
height,
97-
width,
98-
display: 'flex',
99-
alignItems: 'center',
100-
vue: {
101-
element: h(ArcoDesignVue.Tag, { color: value === 'Female' ? 'magenta' : 'arcoblue' }, value),
102-
container: table.bodyDomContainer
103-
}
104-
});
105-
106-
return {
107-
rootContainer: container,
108-
renderDefault: false
109-
};
110-
}
111-
},
112-
{
113-
field: 'comment',
114-
title: 'Comment',
115-
width: 300,
116-
customLayout: args => {
117-
const { table, row, col, rect, value } = args;
118-
const { height, width } = rect ?? table.getCellRect(col, row);
119-
120-
const container = new VTable.CustomLayout.Group({
121-
height,
122-
width,
123-
display: 'flex',
124-
alignItems: 'center',
125-
vue: {
126-
element: h(
127-
ArcoDesignVue.Comment,
128-
{ author: 'Socrates', content: value, datetime: '1 hour' },
129-
{
130-
actions: () => [
131-
h('span', { key: 'heart', style: { cursor: 'pointer' } }, [h('span', 'Like')]),
132-
h('span', { key: 'star', style: { cursor: 'pointer' } }, [h('span', 'Collect')]),
133-
h('span', { key: 'reply', style: { cursor: 'pointer' } }, [h('span', 'Reply')])
134-
],
135-
avatar: () => [
136-
h(
137-
ArcoDesignVue.Avatar,
138-
{},
139-
{
140-
default: () => [
141-
h('img', {
142-
alt: 'avatar',
143-
src: 'https://p1-arco.byteimg.com/tos-cn-i-uwbnlip3yd/3ee5f13fb09879ecb5185e440cef6eb9.png~tplv-uwbnlip3yd-webp.webp'
144-
})
145-
]
146-
}
147-
)
148-
]
149-
}
150-
),
151-
container: table.bodyDomContainer
152-
}
153-
});
154-
155-
return {
156-
rootContainer: container,
157-
renderDefault: false
158-
};
159-
}
160-
}
161-
],
16296
defaultHeaderRowHeight: 40,
16397
defaultRowHeight: 80,
16498
customConfig: {
@@ -170,6 +104,11 @@ const app = createApp({
170104
});
171105

172106
app.component('vue-list-table', VueVTable.ListTable);
107+
app.component('ListColumn', VueVTable.ListColumn);
108+
app.component('Group', VueVTable.Group);
109+
app.component('ATag', ArcoDesignVue.Tag);
110+
app.component('AComment', ArcoDesignVue.Comment);
111+
app.component('AAvatar', ArcoDesignVue.Avatar);
173112

174113
app.mount(`#${CONTAINER_ID}`);
175114

0 commit comments

Comments
 (0)