您好,登錄后才能下訂單哦!
本篇內容介紹了“vue3 table組件怎么使用”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
首先開發table組件之前,先想好要用什么樣式的api,因為筆者在生產工作中用的都是element,所以前面幾個組件風格和element類似,但是這次不打算用element的風格了,打算換一種,直接展示:
我們期望用戶這樣使用:
<script setup> const dataList = [ { id: 1, name: '《JavaEE企業應用實戰》', author: 'dev1ce', price: '10.22', desc: '書中最后講解的項目案例,涵蓋從前期設計到最終實施的整個過程,對全書知識點進行串聯和鞏固,使讀者融會貫通,掌握Java Web開發的精髓。' }, { id: 2, name: '《代碼整潔之道》', author: 'R0bert', price: '10.22', desc: '整潔代碼并非遵循一組規則編寫的。不可能因為學習一套金規玉律就成為軟件大師。專業精神和手工藝來自于推動規則形成的價值。' }, { id: 3, name: '《ECMAScript 6 入門教程》', author: 'y1feng', price: '10.22', desc: '本書是一本開源的 JavaScript 語言教程,全面介紹 ECMAScript 6 新引入的語法特性。' }, ] const columnsList = [ { title: '書名', key: 'name' }, { title: '作者', key: 'author' }, { title: '價格', key: 'price' }, { title: '簡介', key: 'desc' } ] </script> <template> <sanorin-table :columns="columnsList" :data="dataList"/> </template>
依照這個寫出以下代碼
<script setup> import { ref, computed } from 'vue' import { useProp, useNeumorphism } from '../mixin/neumorphism' const props = defineProps({ ...useProp, ...{ data: { // dataList type: Array, default: () => [], }, columns: { // columnsList type: Array, default: () => [], }, } }) const { baseStyleObject } = useNeumorphism(props) let styleObject = computed(() => ({ // '--font-size': `${props.size-26}px`, '--line-height': `${props.size-20}px`, '--limit-size': `${props.size-28}px` })) </script> <template> <div :> <table > <thead> <tr class="neumorphism"> <!-- 表頭循環 --> <th v-for="col in columns" :key="col.key">{{col.title}}</th> </tr> </thead> <tbody> <!-- 表體循環 --> <tr class="neumorphism" v-for="row in data" :key="row.id"> <td v-for="col in columns" :key="col.key"> <span> {{row[col.key]}} </span> </td> </tr> </tbody> </table> </div> </template> <script> export default { name: 'sanorin-table', } </script> <style scoped> @import "../../style/index.css"; @import "../../style/neumorphism.css"; table { width: 100%; /* border-collapse: collapse; */ empty-cells: show; border-collapse:separate; border-spacing:0px 10px; } table td, table th { color: var(--text-color); padding: 8px 16px 8px 16px; text-align: left; } table th { color: var(--text-back-color) !important; font-weight: 600; white-space: nowrap; } table tr{ margin-top: 20px; } </style>
最后出來的效果就是:
然后實現了這個后我們開始做后面的,先從固定表頭開始。
這里先采用第一種,以后不能滿足需求了再改成后面的方法。
效果和代碼如下:
<script setup> import { ref, computed } from 'vue' import { useProp, useNeumorphism } from '../mixin/neumorphism' const props = defineProps({ ...useProp, ...{ data: { // dataList type: Array, default: () => [], }, columns: { // columnsList type: Array, default: () => [], }, } }) const { baseStyleObject } = useNeumorphism(props) let styleObject = computed(() => ({ })) </script> <template> <div class="san-table scrollbar" :> <table> <thead> <tr class="neumorphism"> <!-- 表頭循環 --> <th v-for="col in columns" :key="col.key">{{col.title}}</th> </tr> </thead> <tbody> <!-- 表體循環 --> <tr class="neumorphism" v-for="row in data" :key="row.id"> <td v-for="col in columns" :key="col.key"> <span> {{row[col.key]}} </span> </td> </tr> </tbody> </table> </div> </template> <script> export default { name: 'sanorin-table', } </script> <style scoped> @import "../../style/index.css"; @import "../../style/neumorphism.css"; .san-table{ padding: 0px 20px 20px 20px; height: 200px; position: relative; width: 700px; overflow: auto; } table { width: 100%; table-layout: fixed; empty-cells: show; border-collapse:separate; border-spacing:0px 10px; } thead { position: sticky; top: 10px; } thead:before{ position: absolute; content: ''; width: calc(100% + var(--shadow-blur) * 2); transform: translate(calc(var(--shadow-blur) * -1) , -10px); height: 20px; background-color: var(--main-color); z-index: -1; } table td, table th { color: var(--text-color); padding: 8px 16px 8px 16px; text-align: left; } table th { color: var(--text-back-color) !important; font-weight: 600; white-space: nowrap; } </style>
可以為 Table 設置一個高度。(height)
當數據量動態變化時,可以為 Table 設置一個最大高度。(maxHeight) 通過設置max-height屬性為 Table 指定最大高度。此時若表格所需的高度大于最大高度,則會顯示一個滾動條。
只要在sanorin-table元素中定義了height或者maxHeight屬性,即可實現固定表頭的表格,而不需要額外的代碼。
代碼如下:
<script setup> import { ref, computed, reactive } from 'vue' import { useProp, useNeumorphism } from '../mixin/neumorphism' const props = defineProps({ ...useProp, ...{ data: { // dataList type: Array, default: () => [], }, columns: { // columnsList type: Array, default: () => [], }, height: { type: Number, }, maxHeight: { type: Number, } } }) // 高度設置 let tableHeightStyleObj = computed(() => { let styleObj = ((e) => { if (e.maxHeight) return { maxHeight: e.maxHeight + 'px' } if (e.height) return { height: e.height + 'px' } return {} })({...props}) return styleObj }) const { baseStyleObject } = useNeumorphism(props) let styleObject = computed(() => ({ ...tableHeightStyleObj.value })) </script> <template> <div class="san-table scrollbar" :> <table> <colgroup> <col v-for="(col, index) in columns" :key="index"> </colgroup> <thead> <tr class="neumorphism"> <th v-for="col in columns" :key="col.key"> {{col.title}} </th> </tr> </thead> <tbody> <tr class="neumorphism" v-for="row in data" :key="row.id"> <td v-for="col in columns" :key="col.key"> {{row[col.key]}} </td> </tr> </tbody> </table> </div> </template> <script> export default { name: 'sanorin-table', } </script> <style scoped> @import "../../style/index.css"; @import "../../style/neumorphism.css"; .san-table{ padding: 0px 20px 20px 20px; position: relative; width: 700px; overflow: auto; } table { width: 100%; table-layout: fixed; empty-cells: show; border-collapse:separate; border-spacing:0px 10px; } thead { position: sticky; top: 10px; } thead:before{ position: absolute; content: ''; width: calc(100% + var(--shadow-blur) * 2); transform: translate(calc(var(--shadow-blur) * -1) , -10px); height: 20px; background-color: var(--main-color); z-index: -1; } table td, table th { color: var(--text-color); padding: 8px 16px 8px 16px; text-align: left; } table th { color: var(--text-back-color) !important; font-weight: 600; white-space: nowrap; } </style>
接下來加入寬度控制,希望在columns 傳入的數組對象內加入寬度,示例如下:
const columnsList = [ { title: '書名', key: 'name', width: 100, }, { title: '作者', key: 'author', width: 100, }, { title: '價格', key: 'price', width: 100, }, { title: '簡介', key: 'desc', minWidth: 350, } ]
希望達到以下效果
1、含有width的列,寬度固定,不隨瀏覽器寬度變化而變化
2、含有minWidth的列,在大于設定值時,自動填充 table 剩余寬度,小于設定值時,固定該寬度
3、不包含width和minWidth的列,自動填充 table 剩余寬度
根據我們的需求,我們需要單獨控制每一列的寬度展示,并在瀏覽器寬度變化時實時的重新計算并且重新渲染列。
首先定義出一個方法,用來計算每一列在當前情況下所要的寬度,再綁定要dom上。然后,每次表格變化/瀏覽器寬度變化時候就能實時響應改變Table的寬度了。
const initColumns = () => { // 計算每一列在當前情況下所要的寬度 } watch(() => props.columns, () => { initColumns() }); onMounted(() => { nextTick(() => { initColumns(); on(window, 'resize', throttle(() => initColumns(), 400)); }); }); onBeforeUnmount(() => off(window, 'resize', () => initColumns()));
全部代碼:
<script setup> import { ref, computed, watch, onMounted, onBeforeUnmount, nextTick } from 'vue' import { on, off } from '../../utils/listener' import { throttle } from "../../utils/debounce&throttle" import { useProp, useNeumorphism } from '../mixin/neumorphism' const table = ref() // 與html中ref=""對應,定位dom元素 const props = defineProps({ ...useProp, ...{ data: { // dataList type: Array, default: () => [], }, columns: { // columnsList type: Array, default: () => [], }, height: { // height type: Number, }, maxHeight: { // 流體高度 type: Number, }, minUnsetWidth: { // 未設置寬度時最小寬度 type: Number, default: 80 } } }) // 高度設置 let tableHeightStyleObj = computed(() => { let styleObj = ((e) => { if (e.maxHeight) return { maxHeight: e.maxHeight + 'px' } if (e.height) return { height: e.height + 'px' } return {} })({...props}) return styleObj }) // 列寬設置 let col = ref([]) const { columns, minUnsetWidth } = props const _min_column_width = minUnsetWidth // 未設置寬度時最小寬度 const initColumns = () => { col.value = (() => { let _total_width = table.value.offsetWidth // 表格dom元素總寬度 let _needed_minWidth = columns.reduce((t, v) => { // 需要的最小寬度 t += v.width || v.minWidth || _min_column_width return t }, 0) // 需要的最小寬度比總寬度大,則取minWidth即可 if (_needed_minWidth >= _total_width) return columns.reduce((t, v) => { let n = v.width || v.minWidth || _min_column_width t = [...t, n] return t }, []) // 需要的最小寬度比總寬度大,則要把minWidth加權,權重為(未分配的寬度 / minWidth之和) let _unassigned_width = columns.reduce((t, v) => { t += v.minWidth || 0 return t }, 0) let _assigned_width = _needed_minWidth - _unassigned_width let _width_power = (_total_width - _assigned_width) / _unassigned_width return columns.reduce((t, v) => { let n = v.width || (v.minWidth ? (_width_power * v.minWidth).toFixed(2) : _min_column_width) t = [...t, n] return t }, []) })() } watch(() => props.columns, () => { initColumns() }) const throttleInitColumns = () => throttle(() => initColumns(), 400) onMounted(() => { nextTick(() => { initColumns() on(window, 'resize', throttleInitColumns) }) }) onBeforeUnmount(() => off(window, 'resize', throttleInitColumns)) const { baseStyleObject } = useNeumorphism(props) let styleObject = computed(() => ({ ...tableHeightStyleObj.value })) </script> <template> <div class="san-table scrollbar" :> <table ref="table"> <colgroup> <col v-for="(item, index) in col" :key="index" :width="`${item}px`"> </colgroup> <thead> <tr class="neumorphism"> <th v-for="col in columns" :key="col.key"> {{col.title}} </th> </tr> </thead> <tbody> <tr class="neumorphism" v-for="row in data" :key="row.id"> <td v-for="col in columns" :key="col.key"> {{row[col.key]}} </td> </tr> </tbody> </table> </div> </template> <script> export default { name: 'sanorin-table', } </script> <style scoped> @import "../../style/index.css"; @import "../../style/neumorphism.css"; .san-table{ padding: 0px 20px 20px 20px; position: relative; overflow: auto; } table { width: 100%; table-layout: fixed; empty-cells: show; border-collapse:separate; border-spacing:0px 10px; } thead { position: sticky; top: 10px; } thead:before{ position: absolute; content: ''; width: calc(100% + var(--shadow-blur) * 2); transform: translate(calc(var(--shadow-blur) * -1) , -10px); height: 20px; background-color: var(--main-color); z-index: -1; } table td, table th { color: var(--text-color); padding: 8px 16px 8px 16px; text-align: left; word-break:break-all; } table th { color: var(--text-back-color) !important; font-weight: 600; white-space: nowrap; } </style>
其中用到的兩個js,防抖節流和注冊監聽這里也放下吧
/* 防抖節流函數 */ let timeout = null // 創建一個標記用來存放定時器的返回值 let count = 0; export function debounce(fn, wait = 1000, immediate = false) { return function () { const args = arguments; if (immediate) { if (count == 0) { fn.apply(this, arguments) count++; } else { if (timeout) { clearTimeout(timeout) // 每當用戶輸入的時候把前一個 setTimeout clear 掉 } timeout = setTimeout(() => { fn.apply(this, arguments) }, wait) } } else { if (timeout) { clearTimeout(timeout) // 每當用戶輸入的時候把前一個 setTimeout clear 掉 } timeout = setTimeout(() => { fn.apply(this, arguments) }, wait) } }() } let canRun = true; let count1 = 0; export function throttle(fn, wait = 1000, immediate = true) { return function () { if (immediate) { if (count1 == 0) { fn.apply(this, arguments); count1++; } else { if (canRun) { canRun = false setTimeout(function () { fn.apply(this, arguments) canRun = true }, wait); } } } else { if (!canRun) return canRun = false setTimeout(function () { fn.apply(this, arguments) canRun = true }, wait); } }() }
/** * 綁定事件 on(element, event, handler) */ export const on = (element, event, handler) => { if (document.addEventListener) { if (element && event && handler) { element.addEventListener(event, handler, false) } } } /** * 解綁事件 off(element, event, handler) */ export const off = (element, event, handler) => { if (document.removeEventListener) { if (element && event) { element.removeEventListener(event, handler, false) } } }
“vue3 table組件怎么使用”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。