vue 自定义grid

这篇博客介绍了如何基于Element-UI的Grid组件进行简单封装,包括Grid和GridColumn的使用,并提到了将column里的formatter功能放在了plugin中,同时引入了util和api模块。虽然存在一些懒加载的遗留问题,但可通过注释或修改来解决。源代码可在github找到。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基于element-ui grid 的 简单封装

grid

<template>
    <div>
        <el-table :data="rows"
            stripe
            border
            :show-header="showHeader"
            style="width:100%">
            <template v-for="(column,key,index) in columns">
                <GridColumn  :column="column" :key="key" :pk="index"></GridColumn>
            </template>
        </el-table>
        <div class="text-right m-t" v-if="showFooter">
            <Pagination :options="this" @list="list"></Pagination>
        </div>
    </div>
</template>

<script>
    import api from "~/api"
    import {baseUtil, renderUtil} from "~/util"
    import GridColumn from "./Grid.column.js"

    export default {
        props:{
            inData:null,
            columns:{
                type:Array,//{header,dataIndex,type}
                required:true
            },
            url:null,
            getQuery:{
                type:Function
            },
            showHeader: {
                type: Boolean,
                default: true
            },
            showFooter:{
                type: Boolean,
                default: true
            },
        },
        components:{
            GridColumn
        },
        created(){
            if(this.inData){
                this.rows=this.inData;
            }
        },
        data(){
            return {
                rows:[],
                params:{},
                total:0
            }
        },

        watch:{ //watch props 变化
            'inData':function(value){
                if(value)
                    this.rows=value;
            },
            'url':function(value){
                //url 变化 重取数据
                this.list();
            }
        },

        mounted(){
            if(this.url)
                this.list();
        },
        methods:{
            list(){
                api.request({
                    url:this.url,
                    params:this.getQueryData(),
                    success:json=>{
                        this.rows=json.rows;
                        this.total=json.total;
                    }
                })
            },

            getQueryData(){
                var outQuery=this.params
                if(this.getQuery){
                    outQuery=Object.assign({},this.params,this.getQuery())
                }
                return outQuery;
            }
        }

        
    }
</script>

gridcolumn

var pick=require('lodash/pick')

const isNotIn=(obj,v,key)=>v&&(obj[key]=v)

import pluginHelper from './Grid.column.plugin.js'


export default {
    name:'GridColumn',
    render(h){
        var me=this;
        function renderChild(column){

            var ps={attrs:{}};
            var {header,dataIndex,width,formatter,children,type,pk,slot}=pluginHelper(column,h);
            ps.attrs.key=dataIndex||(pk+type);
            isNotIn(ps.attrs,header,'label')
            isNotIn(ps.attrs,dataIndex,'prop')
            isNotIn(ps.attrs,width,'width')
            isNotIn(ps.attrs,formatter,'formatter')

            if(slot){
                //搞定
                ps.scopedSlots={default:({row})=>slot({row,column})}
            }
            
            if(column.children){
                ps.attrs.headerAlign="center";
                return <el-table-column {...ps}>
                    {
                        column.children.map((child,index)=>{
                            return renderChild(child)
                        })
                    }
                </el-table-column>
            }
            else{
                return <el-table-column 
                {...ps}>
                </el-table-column>
            }
        }

        if(this.column)    
            return renderChild(this.column);
    },
    props:{
        column:null,
        pk:{
            type:String,
        }
    },
}

column 里的formater 放在plugin 里了

/** 对column 的补充 
* date 04-20
* author wolfsky7 -->------|----------------->
**/
import {renderUtil} from '~/util'


//各种formater 定义
// Vue.prototype.renderYmd = renderUtil.renderYmd;
// Vue.prototype.renderTime = renderUtil.renderTime;
// Vue.prototype.renderNumber = renderUtil.renderNumber;
// Vue.prototype.renderMoney = renderUtil.renderMoney;
// Vue.prototype.renderEnum = renderUtil.renderEnum;
// Vue.prototype.renderPhone = renderUtil.renderPhone;
// Vue.prototype.renderEnabled = renderUtil.renderEnabled;
// Vue.prototype.renderDistrictCode = renderUtil.renderDistrictCode;

const typeFormaters={
    'time':'renderTime',
    'money':'renderMoney',
    'number':'renderNumber',
    'phone':'renderPhone',
    'ymd':'renderYmd',
    'enum':'renderEnum',
    'districtCode':'renderDistrictCode',
    'status':'renderStatus',
    'gender':renderUtil.renderEnum2.bind(null,'gender'),
    'gateway':renderUtil.renderEnum2.bind(null,'gateway'),
}

const typeRenders={
    'switch':h=>({row,column})=><el-switch value={row[column.dataIndex]}></el-switch>,
    'btns':h=>({row,column})=><div class="nowrap">
        {
            column.btns.map(btn=>{
                return <el-button  size="mini" type={btn.type||'primary'} on-click={btnHandler(btn,row)}>{btn.text}</el-button>
            })
        }
        </div>
}

const btnHandler=(btn,row)=>()=>{
    btn.handler(row);
}

export default (column,h)=>{
    //对column 进行补充
    column=types(column,h)

    column=customsTypes(column,h);

    column=customs(column,h);

    return column;
}

const types=(column,h)=>{
    //类型补充
    if(!column.formatter&&'type' in column&&typeFormaters[column.type]){
        let formatter,format=typeFormaters[column.type];
        if(typeof format=="function"){
            formatter=format;
        }
        else{
            formatter=renderUtil[format];
        }
        return {
            ...column,
            formatter
        }
    }

    return column;
}

const customsTypes=(column,h)=>{
    if(!column.render&&column.type in typeRenders){
        column.render=typeRenders[column.type]
    }
    return column;
}


const customs=(column,h)=>{
    if('render' in column){
        var slot=column.render(h);
        var {render,...left}=column
        return {
            ...left,
            slot
        }
    }
    return column;
}


其中 引入了 util 和 api  懒的 改  了 自己注释 或者 修改一下 即可

github 


在 ag-Grid Vue 中,自定义单元格(custom cell)允许你根据数据内容动态渲染 HTML 或使用自定义组件。这为创建交互式和复杂的表格提供了很大的灵活性。以下是实现自定义单元格的一些关键步骤: 1. **列定义**: 在 ag-Grid Vue 中,你需要在列配置中指定`cellRenderer`属性,设置为一个函数或Vue组件,这个函数或组件将会被用来渲染每个单元格的内容。 ```javascript <ag-grid-vue :columnDefs="[ { headerName: 'Name', field: 'name', cellRenderer: customCellRenderer }, // 其他列定义 ]" /> ``` 2. **定制渲染函数**: 如果你想用函数,你可以这样写: ```javascript function customCellRenderer(params) { return `<span>${params.value}</span>`; } ``` 3. **Vue组件**: 使用 Vue 组件时,确保你在列配置中设置`cellRendererParams`,它将包含所有必要的数据和上下文信息: ```javascript const CustomCellComponent = { template: '<div>{{ value }}</div>', props: ['value'] }; function customCellRenderer(params) { return Vue.extend(CustomCellComponent).options.render.call(this, params); } ``` 4. **访问值和事件处理**: 在组件内部,你可以访问单元格的数据(`params.value`),并可以添加事件监听器处理用户交互。 5. **传递事件和数据**: 如果需要从单元格触发事件或者传递数据到父组件,可以在组件上添加`@click`等事件,并通过`$emit`发送事件。 6. **样式和布局**: 自定义单元格可以根据需要使用 CSS 来控制样式和布局,确保与 ag-Grid 的样式体系兼容。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值