欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

vue3+elementplus基于el-table-v2封裝公用table組件詳細代碼

 更新時間:2023年12月13日 10:18:46   作者:_Jyann_  
在日常開發(fā)后端管理系統(tǒng)項目中,用于展示數(shù)據(jù)多會用表格進行展示,下面這篇文章主要給大家介紹了關(guān)于vue3+elementplus基于el-table-v2封裝公用table組件的相關(guān)資料,需要的朋友可以參考下

1.梳理出需要封裝的功能

主要是針對表格進行封裝,不包括查詢表單和操作按鈕。

梳理出系統(tǒng)中通用表格的功能項,即表格主體的所有功能,生成columns列頭數(shù)據(jù)、生成data表體數(shù)據(jù)、拖拉列寬、分頁、生成中文列名、自定義列寬width

效果如下:

2.封裝表格(表格+分頁)

<template>
    <slot></slot>
    <div class="table-v2">
        <el-auto-resizer always height="36">
            <!--行高 :row-height="36" -->
            <template #default="{ height, width }">
                <el-table-v2 :columns="columns" :scrollbar-always-on="true" :data="data" :width="width" :height="height"
                    :row-height="36" :row-key="data.id" fixed>
                </el-table-v2>
            </template>
        </el-auto-resizer>
        <!-- 分頁 -->
        <div class="pagination" v-if="showPage">
            <el-pagination background class="pagination" layout="prev, pager, next" :current-page="pageNum" :total="total"
                :page-size="pageSize" @prev-click="prevClick" @next-click="nextClick" @current-change="currentChange" />
        </div>
    </div>
</template>

父級引用:

 <!-- 表格 -->
    <t-table-v2 @handle-pagenation="handlePagenation"></t-table-v2>

3.將生成列名和表體數(shù)據(jù)、復(fù)選框、操作按鈕等方法封裝成類

import { unref } from 'vue'
import { ElCheckbox, TableV2FixedDir } from 'element-plus'

export default class GenerateTableData {
    // options: {columns:...,data:...}
    constructor(data) {
        this.data = data;
        this.column = this.createColumnsData();
        this.rowData = this.createRowsData();
    }

    /**
     * 通過tableData生成 columnsData
     * @returns 
     */
    createColumnsData = () => {
        let columnsData = [];
        if (this.data.length > 0) columnsData = Object.keys(this.data[0]);
        return columnsData;
    }

    /**
     * 通過tableData生成 rowsData
     * @returns 
     */
    createRowsData = () => {
        let rowData = [];
        this.data.map(item => {
            rowData.push(Object.values(item));
        });
        return rowData;
    }

    /**
     * 函數(shù)設(shè)置width屬性值
     * @param {*} columnIndex 
     */
    static calculateWidth = (columnIndex, columnWidth) => {
        let tempArr = [];
        if (typeof columnWidth === "number") {
            return columnWidth;
        } else if (typeof columnWidth === "object") {
            columnWidth.map((k, index) => {
                if (typeof k.columnsIndex === "object") {
                    k.columnsIndex.map(innerK => {
                        tempArr.push({ columnsIndex: innerK, width: k.width });
                    });
                } else {
                    tempArr.push(columnWidth[index]);
                }
            });
        }
        let width = 0;

        tempArr.map((k) => {
            switch (columnIndex) {
                case k.columnsIndex:
                    width = k.width;
                    break;
            }
        });

        return width;
    }

    /**
     * 將英文列名改為中文列名(id不顯示)
     * @param {*} columnIndex 
     */
    static transferColumnName = (columnIndex, cnColumnNameArr) => {
        return cnColumnNameArr[columnIndex];
    }

    /**
     * 隱藏列
     * @param {*} columnIndex 
     */
    static handleHiddenColumns = (columnIndex, hiddenIndex) => {
        return hiddenIndex.includes(columnIndex);
    }

    /**
     * 生成列名: cnColumnNameArr有值則使用中文名,無值使用原this.column值
     * @param {*} columnsArr 
     */
    generateColumns(cnColumnNameArr, hiddenIndex, columnWidth) {
            console.log(cnColumnNameArr, this.column);
            if (cnColumnNameArr) this.column = cnColumnNameArr;
            return this.column.map((item, columnIndex) => {
                return {
                    key: `${item}`,
                    dataKey: `${item}`,
                    title: `${item}`,
                    // 通過函數(shù)設(shè)置width值
                    hidden: hiddenIndex.length > 0 ? GenerateTableData.handleHiddenColumns(columnIndex, hiddenIndex) : false,
                    width: GenerateTableData.calculateWidth(columnIndex, columnWidth),
                    align: 'center',
                };
            })
        }
        // 生成列表數(shù)據(jù)
    generateData = (columns) => {
        return this.rowData.map((item, rowIndex) => {
            return columns.reduce(
                (rowData, column, columnIndex) => {
                    // item數(shù)組下標columnIndex-1開始(id不顯示),因為有checkbox復(fù)選框
                    rowData[column.dataKey] = item[columnIndex];
                    return item;
                },
                // 初始化元素為第一條數(shù)據(jù)(否則數(shù)據(jù)會獲取不到id)tempDataArr[0]
                this.rowData[rowIndex]
            )
        })
    }

    /**
     * 增加全選列且操作全選/全不選 ; 增加操作按鈕:修改,刪除
     * @param {*} columns 
     */
    static customizeColumns = (columns, data, selectedId, cellRendererFunc) => {
        // 全選按鈕:在數(shù)組頭部添加
        columns.unshift({
            key: 'selection',
            dataKey: 'selection',
            title: 'selection',
            width: 30,
            cellRenderer: ({ rowData }) => {
                // 綁定數(shù)據(jù)的id,然后row-key才能使用id
                rowData.id = rowData[0];
                const onChange = (value) => {
                    rowData.checked = value

                    if (rowData.checked) {
                        selectedId.push(rowData[0]);
                    } else {
                        let idIndex = selectedId.findIndex(item => item === rowData[0]);
                        selectedId.splice(idIndex, 1);
                    }
                    console.log("selectedId.value------------", selectedId);
                    return rowData.checked;
                }
                return ( <
                    ElCheckbox onChange = { onChange }
                    modelValue = { rowData.checked }
                    indeterminate = { false }
                    />
                )
            },

            headerCellRenderer: () => {
                const _data = unref(data)
                const onChange = (value) =>
                    (data = _data.map((row) => {
                        row.checked = value;
                        // 全選id設(shè)置
                        if (row.checked) {
                            selectedId.push(row[0]);
                        } else {
                            selectedId = [];
                        }
                        return row;
                    }))
                    // 全選
                const allSelected = _data.every((row) => row.checked)
                    // 非全選
                const containsChecked = _data.some((row) => row.checked)
                return ( <
                    ElCheckbox onChange = { onChange }
                    modelValue = { allSelected }
                    indeterminate = { containsChecked && !allSelected }
                    />
                )
            },
        });

        // 操作按鈕:在數(shù)組末尾添加
        cellRendererFunc && columns.push({
            key: 'operations',
            dataKey: 'operations',
            title: '操作',
            width: 300,
            align: 'center',
            // 編輯和刪除操作:綁定當(dāng)前id,使用的是JSX語法,方法調(diào)用onClick={ editResource } 傳參:onClick={ (event)=>editResource(rowData[0]) }
            cellRenderer: ({ rowData }) => cellRendererFunc(rowData)
        });
    };

    /**
     * 固定列:可以用這個方法也可以用elementplus自帶的(自帶的感覺還方便一些)
     */
    fixedColumns = (columns, fixedColumnIndex) => {
        fixedColumnIndex.length > 0 && fixedColumnIndex.map(column => {
            // 不設(shè)置為TableV2FixedDir.LEFT這種形式,可以直接寫true,默認left
            let tableV2Fixed = true;
            if (column.direction === "left") tableV2Fixed = TableV2FixedDir.LEFT;
            if (column.direction === "right") tableV2Fixed = TableV2FixedDir.RIGHT;
            columns[column.index].fixed = tableV2Fixed;
        });
    }
}

4.父類中調(diào)用類方法

// 數(shù)據(jù)所有列都一樣,所以取第一條數(shù)據(jù)列名作為表頭
    let cnColumnNameArr = ['編號', '資源名稱', '資源類型', '提交原因', '上個投產(chǎn)版本', '投產(chǎn)版本', '提交人', 'SIT'
        , '提交時間', '狀態(tài)', 'SIT部署時間', 'SIT測試完成時間', 'UAT部署時間', 'SIT部署完成', 'SIT已測試', 'UAT部署完成'];
    let hiddenIndex = [0,4];
    let columnWidth = [{columnsIndex:[0,4],width:0},
        {columnsIndex:1,width:146},
        {columnsIndex:2,width:80},
        {columnsIndex:3,width:300},
        {columnsIndex:5,width:76},
        {columnsIndex:[6,9],width:100},
        {columnsIndex:[8,10,11,12],width:160},
        {columnsIndex:[7,13,14,15],width:70},
        {columnsIndex:'default',width:58}];

        const generateTableData = new GenerateTableData(tableData.value);
        
        // 完全無值也需要顯示列名, cnColumnNameArr此處必須有值:cnColumnNameArr或者false(英文列名)
        cnColumnNameArr = tableData.value.length === 0? cnColumnNameArr : cnColumnNameArr;//length如果不為0是設(shè)置為false就會顯示英文列名
        columns.value = generateTableData.generateColumns(cnColumnNameArr,hiddenIndex,columnWidth);

        // 設(shè)置全選按鈕和操作按鈕
        data.value = code === 200 ? generateTableData.generateData(columns.value): [];

        GenerateTableData.customizeColumns(columns.value,data.value,selectedId.value,cellRenderer);
        if(code === 200){
           // 固定列
          columns.value[0].fixed = true
          columns.value[1].fixed = TableV2FixedDir.LEFT
          columns.value[2].fixed = TableV2FixedDir.LEFT
          columns.value[3].fixed = TableV2FixedDir.LEFT
        }

        resizeColumns(columns.value);

5.父子組件通信(provide/inject)

父組件:

// provide方式父子組件傳值
provide('columns', computed(()=>columns.value));
provide('data', computed(()=>data.value));
// 分頁
provide('showPage', computed(()=>true));
provide('pageNum', computed(()=>pageNum.value));
provide('total', computed(()=>total.value));
provide('pageSize', computed(()=>pageSize.value));
provide('pages', computed(()=>pages.value));
// 是否寬高自適應(yīng)
provide('selfAdaption', computed(()=>true));
provide('cellRenderer', computed(()=>cellRenderer));

子組件:

// 是否顯示分頁組件
const showPage = inject('showPage',false);
const columns = inject('columns',[]);
const data = inject('data',[]);

const pageNum = inject('pageNum',1);
const pages = inject('pages',0);
const total = inject('total',0);
const pageSize = inject('pageSize',16);

// 是否寬高自適應(yīng)
const selfAdaption = inject('selfAdaption',false);

6.分頁

子組件:

const $emit = defineEmits(['handlePagenation']);
/**
 * 上一頁:pageNum會自動-1
 */
const prevClick = () => {
    // pageNation分頁組件限定,pageNum.value不可能為0;如果pageNum.value比1大就取pageNum.value,否則永遠為1
    $emit('handlePagenation', Math.max(1, pageNum.value));
}

/**
 * 下一頁:pageNum會自動+1
 */
const nextClick = () => {
    // 如果pageNum.value比pages小就取pageNum.value,否則永遠為pages
    $emit('handlePagenation', Math.max(1, Math.min(pages.value, pageNum.value)));
}

/**
 * 點擊特定頁碼(此方法會自動傳入當(dāng)前頁碼)
 * @param {*} currentPage 
 */
const currentChange = (currentPage) => {
    $emit('handlePagenation', currentPage);
}

父組件:

/**
 * 分頁
 */
 const handlePagenation = (pageNumVal) =>{
  // pageNation分頁組件限定,pageNum.value不可能為0;如果pageNum.value比1大就取pageNum.value,否則永遠為1
  pageNum.value = pageNumVal;
  loadDataGrid();
}

7.問題:el-table-v2中數(shù)據(jù)失去響應(yīng)性

以上,實現(xiàn)簡單封裝

總結(jié)

到此這篇關(guān)于vue3+elementplus基于el-table-v2封裝公用table組件的文章就介紹到這了,更多相關(guān)el-table-v2封裝公用table組件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • vue如何通過$router.push傳參數(shù)

    vue如何通過$router.push傳參數(shù)

    這篇文章主要介紹了vue如何通過$router.push傳參數(shù),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • 解決微信瀏覽器緩存站點入口文件(IIS部署Vue項目)

    解決微信瀏覽器緩存站點入口文件(IIS部署Vue項目)

    這篇文章主要介紹了解決微信瀏覽器緩存站點入口文件(IIS部署Vue項目),本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-06-06
  • Vue實現(xiàn)控制商品數(shù)量組件封裝及使用

    Vue實現(xiàn)控制商品數(shù)量組件封裝及使用

    這篇文章主要為大家詳細介紹了Vue實現(xiàn)控制商品數(shù)量組件的封裝及使用,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • Vue項目中是否使用store原理深究

    Vue項目中是否使用store原理深究

    這篇文章主要為大家介紹了在Vue項目中是否使用store原理深究,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-11-11
  • Vue的路由及路由鉤子函數(shù)的實現(xiàn)

    Vue的路由及路由鉤子函數(shù)的實現(xiàn)

    這篇文章主要介紹了Vue的路由及路由鉤子函數(shù)的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-07-07
  • vue接口請求加密實例

    vue接口請求加密實例

    這篇文章主要介紹了vue接口請求加密實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-08-08
  • 使用Vue-cli3.0創(chuàng)建的項目 如何發(fā)布npm包

    使用Vue-cli3.0創(chuàng)建的項目 如何發(fā)布npm包

    這篇文章主要介紹了使用Vue-cli3.0創(chuàng)建的項目,如何發(fā)布npm包,本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-10-10
  • Vue.js通用應(yīng)用框架-Nuxt.js的上手教程

    Vue.js通用應(yīng)用框架-Nuxt.js的上手教程

    本篇文章主要介紹了Vue.js通用應(yīng)用框架-Nuxt.js的上手教程,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-12-12
  • iView UI FORM 動態(tài)添加表單項校驗規(guī)則寫法實例

    iView UI FORM 動態(tài)添加表單項校驗規(guī)則寫法實例

    這篇文章主要為大家介紹了iView UI FORM 動態(tài)添加表單項校驗規(guī)則寫法實例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-01-01
  • 一文完全掌握Vue中的$set方法

    一文完全掌握Vue中的$set方法

    這篇文章主要給大家介紹了關(guān)于如何完全掌握Vue中$set方法的相關(guān)資料,vue中$set方法對數(shù)組和對象的處理本質(zhì)上的一樣的,對新增的值添加響應(yīng)然后手動觸發(fā)派發(fā)更新,需要的朋友可以參考下
    2023-11-11

最新評論