DeepSeek 助力 Vue3 开发:打造丝滑的表格(Table)之功能优化,添加列宽调整功能Table12
前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏+关注哦 💕
目录
- DeepSeek 助力 Vue3 开发:打造丝滑的表格(Table)之功能优化,添加列宽调整功能Table12
-
- 📚页面效果
- 📚指令输入
- 📚think
-
- 📘组件代码
-
- 🔖功能增强说明:
- 🔖注意事项:
- 📚代码测试
- 📚测试代码正常跑通,附其他基本代码
-
- 📘编写路由 src\router\index.js
- 📘编写展示入口 src\App.vue
- 📚页面效果
- 📚展望
📚📗📕📘📖🕮💡📝🗂️✍️🛠️💻🚀🎉🏗️🌐🖼️🔗📊👉🔖⚠️🌟🔐⬇️·正文开始
⬇️·🎥😊🎓📩😺🌈🤝🤖📜📋🔍✅🧰❓📄📢📈 🙋0️⃣1️⃣2️⃣3️⃣4️⃣5️⃣6️⃣7️⃣8️⃣9️⃣🔟🆗*️⃣#️⃣
DeepSeek 助力 Vue3 开发:打造丝滑的表格(Table)之功能优化,添加列宽调整功能Table12
📚页面效果
📚指令输入
在“加载状态指示器”功能不变的情况下,添加新功能“支持列宽调整”,并写出完整代码
📚think
好的,我现在需要帮助用户在现有的Vue3表格组件中添加“支持列宽调整”的功能,同时保留已有的“加载状态指示器”功能。用户已经提供了之前的代码,我需要先理解现有代码的结构和功能,然后找到合适的位置添加列宽调整的逻辑。
首先,回顾之前的代码,用户已经实现了一个功能丰富的表格组件,包括数据展示、分页、排序、行选择、搜索、空状态提示以及加载状态指示器。现在需要添加列宽调整功能,允许用户通过拖拽列头的分隔线来调整列的宽度。
接下来,我需要考虑如何在Vue3的组合式API中实现这一功能。列宽调整通常涉及以下几个步骤:
- 检测用户拖拽事件:在列头的右侧添加一个可拖拽的区域,监听鼠标按下事件开始调整。
- 计算宽度变化:在鼠标移动时,计算新的列宽,并更新列的样式。
- 更新列配置:将调整后的列宽同步到父组件,可能需要使用
emit
事件来传递新的列配置。
- 样式调整:确保拖拽手柄的样式和交互反馈(如光标变化、辅助线)正确显示。
接下来,我需要检查现有代码的结构,找到合适的位置插入这些逻辑。观察到在模板中,列头是通过
th
元素渲染的,每个th
对应一个列。因此,应该在每个th
元素中添加拖拽手柄,并绑定相关的事件处理函数。
在脚本部分,需要引入新的响应式变量来跟踪拖拽状态,如
isResizing
、resizingIndex
、startX
、startWidth
等。此外,还需要在onMounted
和onBeforeUnmount
生命周期钩子中处理事件的绑定和解绑,以避免内存泄漏。
考虑到用户要求使用普通JavaScript而非TypeScript,需要确保代码中没有类型注解。同时,要确保新增的功能不会影响已有的加载状态指示器和其他功能,比如在加载时禁用拖拽功能。
在样式方面,需要为拖拽手柄添加CSS样式,如定位、光标形状、背景颜色等,并在拖拽过程中显示辅助线以提升用户体验。还需要处理拖拽时的用户选择行为,防止文本被选中影响操作。
最后,测试新增功能是否与现有功能兼容,例如在调整列宽时,分页、排序、行选择等是否正常工作,加载状态是否覆盖整个表格区域,包括新增的拖拽手柄。
现在,根据上述思考,整合代码。在模板中添加拖拽手柄元素,绑定鼠标事件;在脚本中实现事件处理逻辑;在样式中添加相关CSS。确保所有改动与现有代码无缝衔接,并处理可能的边界情况,如最小列宽限制、多列同时调整等。
📘组件代码
以下是整合加载状态和列宽调整功能的完整代码:
<!-- components/Table/Table.vue -->
<template>
<div
class="ds-table"
:class="[`table-size-${size}`, { 'table-stripe': stripe, 'table-border': border }]"
ref="tableContainer"
>
<!-- 加载遮罩层 -->
<div v-if="loading" class="loading-mask">
<div class="loading-content">
<slot name="loading">
<div class="default-loading">
<div class="loading-spinner"></div>
<div class="loading-text">{
{ loadingText }}</div>
</div>
</slot>
</div>
</div>
<!-- 搜索框 -->
<div v-if="showSearch" class="table-search">
<input
v-model="searchKeyword"
placeholder="搜索..."
@input="handleSearch"
class="search-input"
:disabled="loading"
/>
</div>
<!-- 表格容器 -->
<div class="table-container">
<table ref="tableEl">
<thead>
<tr>
<!-- 选择列 -->
<th
v-if="rowSelection"
:class="headerAlignClass"
class="selection-column"
:style="{ width: selectionColumnWidth }"
>
<div class="header-content">
<input
type="checkbox"
:checked="allSelected"
@change="toggleAllSelection"
:disabled="loading"
/>
</div>
<div
v-if="resizable"
class="resize-handle"
@mousedown.prevent="startResize('selection', $event)"
></div>
</th>
<!-- 数据列 -->
<th
v-for="(col, colIndex) in columns"
:key="col.dataIndex"
:class="[headerAlignClass, { sortable: sortable && col.sortable }]"
:style="{ width: col.width || 'auto' }"
>
<div class="header-content">
<slot :name="`header-${col.dataIndex}`" :column="col">
<span @click="handleSort(col)">
{
{ col.title }}
<span v-if="sortable && col.sortable" class="sort-icon">
{
{ sortedColumn.field === col.dataIndex ?
(sortedColumn.order === 'asc' ? '↑' : '↓') : '' }}
</span>
</span>
</slot>
</div>
<div
v-if="resizable"
class="resize-handle"
@mousedown.prevent="startResize(colIndex, $event)"
></div>
</th>
</tr>
</thead>
<tbody>
<!-- 空状态 -->
<tr v-if="showEmpty" class="empty-row">
<td :colspan="totalColumns">
<slot name="empty">
<div class="empty-content">
<svg class="empty-icon" viewBox="0 0 1024 1024">
<path d="M832 320H192v448h640V320z m-64 384H256V384h512v320z m64-416h-64v-64h64v64z m0-128H192v64h640v-64zM128 256h64v512H128z m704 512h64V256h-64v512z"/>
</svg>
<div class="empty-text">{
{ emptyText }}</div>
</div>
</slot>
</td>
</tr>
<!-- 数据行 -->
<template v-else>
<tr
v-for="(row, index) in processedData"
:key="rowKey ? row[rowKey] : index"
:class="{
'selected-row': isRowSelected(row),
'stripe-row': stripe && index % 2 === 0
}"
@click="handleRowClick(row)"
>
<!-- 选择列 -->
<td
v-if="rowSelection"
:class="cellAlignClass"
:style="{ width: selectionColumnWidth }"
>
<input
type="checkbox"
:checked="isRowSelected(row)"
@change="toggleRowSelection(row)"
:disabled="loading"
/>
</td>
<!-- 数据列 -->
<td
v-for="col in columns"
:key="col.dataIndex"
:class="cellAlignClass"
:style="{ width: col.width || 'auto' }"
>
<slot :name="`cell-${col.dataIndex}`" :row="row" :value="row[col.dataIndex]">
{
{ row[col.dataIndex] }}