文章目录
- 问题
- 目前解决效果 v1
- 思路
- 目前解决效果 v0
- 思路
- 代码
- V1
问题
自己封装的 AgGrid
如何自定义传递 icon
,以及点击事件的处理?
目前解决效果 v1
思路
目前解决效果 v0
思路
一张图片说明一下
代码
V1
父组件使用
<template>
<MyPageLayout @handleSearch="handleSearch">
<MyAgGrid :columnDefs="grid.columnDefs" :rowData="grid.rowData" :gridOptions="grid.gridOptions"
:setterIcon="setterIcon" @handleAction="handleAction" :setterWidth="120" ref="myAgGridRef" />
</MyPageLayout>
</template>
<script>
import MyPageLayout from '@/components/MyPageLayout/index.vue'
import MyAgGrid from '@/components/MyAgGrid/index_v1.vue'
import svgComponent from './svgComponent.vue'
export default {
name: 'classOfSilo',
components: {
MyPageLayout,
MyAgGrid,
},
data() {
return {
setterIcon: [
{ icon: `<span>1</span>`, tip: 'html' },
{ icon: svgComponent, tip: 'component' },
{ icon: 'el-icon-eleme', tip: '11' },
{ icon: 'el-icon-s-tools', tip: '22' },
{ icon: 'el-icon-phone', tip: '33' },
],
};
},
}
</script>
svgComponent
<template>
<img :src="findsvg" class="find-svg" />
</template>
<script>
import findsvg from '@/assets/erp-icons/find-replace.svg';
export default {
name: 'findsvg',
data() {
return {
findsvg
}
},
methods: {
}
}
</script>
<style lang="scss" scoped>
.find-svg {
width: 16px;
height: 16px;
cursor: pointer;
position: relative;
top: -2px;
}
</style>
二次封装 MyAgGrid
<template>
<AgGridVue :style="myStyle" :class="theme" :columnDefs="mergedColumnDefs" :rowData="rowData"
:gridOptions="mergedGridOptions" @grid-ready="onGridReady">
</AgGridVue>
</template>
<script>
import { AgGridVue } from "@ag-grid-community/vue";
import { ModuleRegistry } from '@ag-grid-community/core';
import { AG_GRID_LOCALE_CN } from '@ag-grid-community/locale';
import { RowGroupingModule } from '@ag-grid-enterprise/row-grouping';
import { ClientSideRowModelModule } from '@ag-grid-community/client-side-row-model';
import Setter from '@/components/MyAgGrid/components/Setter.vue'
ModuleRegistry.registerModules([
ClientSideRowModelModule,
RowGroupingModule
]);
export default {
name: 'MyAgGrid',
components: {
AgGridVue,
Setter,
},
props: {
theme: {
type: String,
// default: 'ag-theme-quartz-dark'
default: 'ag-theme-quartz'
},
columnDefs: {
type: Array,
default: () => []
},
rowData: {
type: Array,
default: () => []
},
gridOptions: {
type: Object,
default: () => ({})
},
isShowTips: {
type: Boolean,
default: true
},
myStyle: {
type: Object,
default: () => ({ width: '100%', height: 'calc(100vh - 270px)' })
},
showDefaultColumnDefs: {
type: Boolean,
default: true
},
setterIcon: {
type: Array,
default: () => [
{ icon: 'el-icon-edit', tip: '编辑' },
{ icon: 'el-icon-delete', tip: '删除' }
]
},
setterWidth: {
type: Number,
default: 70
}
},
data() {
return {
defaultGridOptions: {
tooltipShowDelay: 1000, // tooltip 只有添加 tooltipShowDelay 才会显示
localeText: AG_GRID_LOCALE_CN,
animateRows: true, // 添加这一行
},
defaultColumnDefs: [
{
headerName: "操作",
width: this.setterWidth,
field: "setter",
pinned: 'right',
cellRenderer: 'Setter',
cellRendererParams: {
isShowTips: this.isShowTips,
setterIcon: this.setterIcon,
actionHandler: this.handleAction, // 传递点击处理方法
},
resizable: true
}
],
gridApi: null
}
},
computed: {
mergedGridOptions() {
return { ...this.defaultGridOptions, ...this.gridOptions };
},
mergedColumnDefs() {
if (this.showDefaultColumnDefs == false) {
return [...this.columnDefs]
}
return [...this.defaultColumnDefs, ...this.columnDefs];
}
},
methods: {
getGridApi() {
return this.gridApi
},
onGridReady(params) {
this.gridApi = params.api
},
handleAction(index, rowData) {
this.$emit('handleAction', index, rowData)
},
},
}
</script>
<style scoped lang="scss">
::v-deep .ag-pinned-right-header {
// margin-right: 16px;
.ag-header-row-column {
padding-right: 16px;
}
}
::v-deep .ag-pinned-left-header {
border-right: none;
}
::v-deep .ag-pinned-right-cols-container {
margin-right: 0 !important;
}
::v-deep .ag-center-cols-container {
margin-right: 0 !important;
}
/deep/ .ag-root-wrapper {
border-radius: 0;
}
</style>
Setter.vue
<template>
<div class="setter">
<template v-for="(item, index) in iconList">
<el-tooltip v-if="isShowTips" class="item" effect="light" :content="item.tip" placement="bottom-start"
:key="`icon-${index}`">
<RenderIcon :icon="item.icon" class="icon-wrapper" @click.native="clickIcon(index)" />
</el-tooltip>
<RenderIcon v-else :icon="item.icon" class="icon-wrapper" @click.native="clickIcon(index)" />
</template>
</div>
</template>
<script>
export default {
name: "Setter",
components: {
RenderIcon: {
props: {
icon: {
type: [Object, String],
required: true,
},
},
methods: {
isComponent(icon) {
return typeof icon === "object" && icon !== null && typeof icon.render === "function";
},
isHtmlTag(icon) {
const htmlTagRegex = /^<([a-zA-Z][a-zA-Z0-9]*)\b[^>]*>(.*?)<\/\1>$/;
return typeof icon === "string" && htmlTagRegex.test(icon);
},
},
render(h) {
const { icon } = this;
if (this.isComponent(icon)) {
return h(icon, { class: "mr6" });
} else if (this.isHtmlTag(icon)) {
return h("span", { domProps: { innerHTML: icon }, class: "mr6" });
} else {
return h("i", { class: `mr6 ${icon}` });
}
},
},
},
computed: {
iconList() {
return this.params.setterIcon;
},
isShowTips() {
return this.params.isShowTips;
},
},
methods: {
clickIcon(index) {
this.params.actionHandler(index, this.params.data);
},
},
};
</script>
<style lang="scss" scoped>
.mr6 {
margin-right: 6px;
}
.icon-wrapper {
cursor: pointer;
}
</style>