項目場景: 基於electron + Vue + node.js + express + mysql + evanpatchouli-mysql + Ant-Design-Vue,編寫一款屬於自己的輕量級MySQL資料庫界面工具。 問題列表 如何動態渲染高度自定義的Ant Design Table? ...
項目場景:
基於electron + Vue + node.js + express + mysql + evanpatchouli-mysql + Ant-Design-Vue,編寫一款屬於自己的輕量級MySQL資料庫界面工具。
問題列表
- 如何動態渲染高度自定義的Ant Design Table?
- Ant Design Table 表頭固定,內部Popover意外遮擋
問題描述
問題1
作為一款資料庫界面工具,需要動態地獲得資料庫和表的信息,因此要渲染的表結構經常在變。
Ant Design Vue的官方手冊給出的示例里,全部採用:datasource綁定數據源,:columns綁定表結構,如果想自定義column的內容,就往標簽內嵌插槽<template>
以下是官方的template模板
<a-table :data-source="data">
<a-table-column key="age" title="Age" data-index="age" />
<a-table-column key="address" title="Address" data-index="address" />
<a-table-column key="tags" title="Tags" data-index="tags">
<template #default="{ text: tags }">
<span>
<a-tag v-for="tag in tags" :key="tag" color="blue">{{ tag }}</a-tag>
</span>
</template>
</a-table-column>
<a-table-column key="action" title="Action">
<template #default="{ record }">
<span>
<a>Action 一 {{ record.firstName }}</a>
<a-divider type="vertical" />
<a>Delete</a>
</span>
</template>
</a-table-column>
</a-table>
我複製了這個模板用到我的表格中,並且自定義了一個懸浮觸發的Popover,這就存在一個問題:模板里,<a-table>
內寫了自定義的<a-table-column>
,表頭是在column標簽上綁定title,但title不支持像:title這樣的動態綁定,只能綁定一個死的字元串。
寫死的表頭並不符合我動態渲染不同表格的需求,刪掉寫死的表頭,則不會渲染表頭;我嘗試為<a-table>
定義了columns,表頭是有了,但我自己寫<a-table-column>
又會被預設樣式覆蓋,單純的渲染了源數據。
原因分析:
無論有沒有綁定:columns時,渲染規則是一定的。為此,我們需要弄清楚不同情況下參數的映射關係,才能正確的渲染我們想要的效果。
解決方案1:
按照上面那個模板改:
不綁定columns,手寫ant-table-column,v-for綁定表結構對column進行列表渲染,並綁定:dataindex為欄位名去拿到數據,內置兩個插槽對應表頭和內容,#title和#default
<a-table
:dataSource="users"
:pagination="{ pageSize: 9 }"
:scroll="{ x: 'max-content', y: clientHeight }"
>
<a-table-column
v-for="item in userStruct"
:key="item.Field"
:data-index="item.Field"
@resizeColumn="handleResizeColumn"
>
<template #title
><span
style="
background: var(--text-backcolor);
color: var(--most-backlolor);
"
>{{ item.Field }}</span
>
</template>
<template #default="{ text: content }">
<a-popover
id="ziduanInfo"
title="欄位信息"
placement="right"
trigger="hover"
:getPopupContainer="
(triggerNode) => {
return triggerNode.parentNode;
}
"
>
<template #content>
<p>類型: {{ item.Type }}</p>
<p>鍵型: {{ item.Key }}</p>
<p>非空: {{ item.Null }}</p>
<p>字元集: {{ item.Collation }}</p>
<p>預設值: {{ item.Default }}</p>
<p>許可權: {{ item.Privileges }}</p>
<p>其他: {{ item.Extra }}</p>
<p>描述: {{ item.Comment }}</p>
</template>
<span class="table-cell-content">{{ content }}</span>
</a-popover>
</template>
</a-table-column>
</a-table>
解決方案2:
不用官方給的這個示例,換一種插槽的方式
不寫ant-table-column,在ant-table上綁定columns
內置兩個插槽對應表頭和內容,#headerCell和#bodyCell
內容依舊是用v-for進行渲染
<a-table :dataSource="users" :columns="columns">
<template #headerCell="{ column }">
<template v-if="column.key === 'id'">
<span>
<smile-outlined />
<a-button>{{ column.key }}</a-button>
</span>
</template>
</template>
<template #bodyCell="{ column, record }">
<template v-for="(item, index) in userConstruct" :key="index">
<a>
<a-button>{{ record[index] }}</a-button>
</a>
</template>
</template>
</a-table>
問題2
我的應用做了響應式界面,當electron視窗高度減小時,ant-table可見高度也隨之減小,為此我設置了它的:scroll,為其動態指定了一個監聽視窗的變數作為高度(y)。
我使用問題一的方案一中的代碼時,當我的數據只有寥寥幾條或者視窗很扁的時候,滑鼠懸浮欄位浮現的popover被限制在表可見高度內,無法完全顯示。
為瞭解決這個問題,我先嘗試css穿透ant-table,設置overflow為visible,無效。又嘗試將xss穿透popover,設置其z-index為更高值,無效。
原因分析
ant-popover在渲染時,預設是掛載到最大的父容器body上。在我複製下來的示例代碼中,指定了其掛載的容器為出發事件所在的容器-即ant-table,由於ant-table被我設置了高度,popover若高度比表格更高,溢出部分只能滑動父容器(ant-table)查看。
解決方案
刪除ant-popover標簽內綁定的掛載容器傳值,或者為其指定一個合適的掛載容器。
題外話
這是我第一次使用ant-design,感覺上手不是很快,還在學習中,如有講的不對的地方還請見諒。