关于封装组件的⼀些思路--持续更新
1.⼀般封装的组件都有需要,点击内部按钮或者什么,带着数据触发⽗组件⽅法的情况,
这时可能会想到$emit⼦传⽗,但是其实我⽤过这种⽅式,少还好,⼀但函数多了,
那组件⾝上⼀堆@函数,看的很难看,⼜多,但⼜没办法,毕竟必须要每个都写@函数
今天在公司看到了另⼀种封装⽅法,我觉得可以借鉴⼀下,很不错
就传⼀个对象给⼦组件,⾥⾯传相应的配置,⽐如⼀个按钮对象数组,
每个对象⾝上有按钮类型,触发的⽗函数名等等,还可以传很多东西,
可以放在当前⽬录的mock.js⾥,这⾥主要讲讲这个触发的⽗函数名
传进去之后,会在相关按钮上绑定同⼀个的函数,
⽐如叫triggerMethods(funcName,data),不同的按钮传接收到得不同得函数名,
以及各⾃的数据然后函数⾥通过this.$parent[funcName](data)触发函数
很妙啊,很⽅便  这样不管多少个⽅法,⼦组件上也只会看到传的⼀个数据对象⽽已
⼆次封装el-table 封装的datatable
<template>
<div class="data_table_wrap" id="mone_test_data_table">
<!-- 条件过滤表单 -->
<slot v-if="tableCfg.filterSlot" name="tableFilterSlot"></slot>
<div v-else-if="!tableCfg.filterSlot && hasFilter" class="table_filter_form_wrap">
<el-row class="title">
<el-col :span="12">
<i class="el-icon-search"></i>筛选查询
</el-col>
<el-col :span="12" class="t_r">
<el-button type="primary" size="mini">查询</el-button>
<el-button type="primary" size="mini">重置</el-button>
</el-col>
</el-row>
<el-form :model="filterForm" class="filter_form" size="small" label-width="100px;">
<el-row>
<el-col :span="8" v-for="item in filterCfg" :key="item.name">
<el-form-item :label="item.label" :prop="item.name">
<el-input v-if="pe == 'text'" v-model="filterForm[item.name]" :placeholder="item.label"></el-input>
<el-select v-if="pe == 'select'" v-model="filterForm[item.name]" :placeholder="item.label">
<el-option v-for="(o, i) in item.option" :key="o.value + i" :label="o.label" :value="o.value"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
</el-form>
</div>
<!-- 表格⼯具栏 -->
<slot v-if="lbarSlot && tableCfg.showToolbar" name="tableToolbarSlot"></slot>
<el-row v-else-if="!lbarSlot && tableCfg.showToolbar" class="toolbar_wrap not_filter_toolbar_wrap">
<el-col :span="20" >
<div class="toolbar_btn_wrap" v-show="!isShowBatchOperationBtn">
<template v-if="hasToolbarBtn">
<label v-for="item in toolbarCfg.btn" :key="item.id">
<el-button v-if="pe == 'primary'" @click="triggerParentMethod(item.clickEvent, { currBtnConfig: item})" type="primary" size="mini" class="t                            <el-button v-else-if="pe == 'danger'" @click="triggerParentMethod(item.clickEvent, { currBtnConfig: item})" type="danger" size="mini" clas                            <div v-else-if="pe == 'dropdown'" class="toolbar_btn_dropdown">
<span>{{ item.label }} </span> <i class="el-icon-caret-bottom"></i>
<ul>
<li v-for="menu in item.dropdownMenu" :key="menu.id" @click="handleCommand(menu)">{{ menu.label }}</li>
</ul>
</div>
<el-button v-else @click="triggerParentMethod(item.clickEvent, { currBtnConfig: item})" type="text" size="mini" class="toolbar_btn">{{ item.label                        </label>
</template>
</template>
<span v-if="hasToolbarBatchOperationBtn" class="toolbar_btn toolbar_btn_batch_operation" @click="changeBatchOperationState(true)"><i class="ic                </div>
<label class="batch_operation_wrap" v-show="isShowBatchOperationBtn" v-if="hasToolbarBatchOperationBtn">
<span @click="changeBatchOperationState(false)" class="mone_test_btn_text"><i class="el-icon-refresh-left"></i>取消</span>
<span v-for="item in toolbarCfg.batchOperationBtn" :key="item.id" class="mone_test_btn_text"
@click="triggerParentMethod(item.clickEvent, { currBtnConfig: item, isBatchOperation: true})"
>
{{ item.label }}
</span>
</label>
</el-col>
<el-col :span="4" class="t_r">
<el-dropdown class="toolbar_btn" trigger="click">
<span class="el-dropdown-link btn_set_column_state">
<i class="el-icon-setting"></i>
</span>
<el-dropdown-menu slot="dropdown" class="column_state_list_wrap mone_test_dataTableColumnStateList">
<ul class="column_state_list_title">
<li class="">
<el-checkbox :indeterminate="columnStateCfg.indeterminate" v-model="columnStateCfg.checkAll" @change="columnStateClickAll">列表项</e                            </li>
</ul>
<el-checkbox-group v-model="columnStateCfg.showColumn" @change="columnStateChange">
<ul>
<li v-for="(item, i) in theadCfg" :key="i">
<el-checkbox :label="item.prop">
<span>{{ item.label }}</span>
</el-checkbox>
</li>
</ul>
</el-checkbox-group>
</el-dropdown-menu>
</el-dropdown>
</el-col>
</el-row>
<!-- 表格 -->
<el-table :data="data" @selection-change="handleSelectionChange" class="data_table" border>
<el-table-column type="selection" width="55"></el-table-column>
<template v-for="(item, index) in theadCfg">
<template v-if="!item.isHide">
<!-- 链接 -->
<el-table-column v-if="pe=='link'" :prop="item.prop" :label="item.label" :width="item.width" :key="item.prop+index"
:render-header="(h,obj) => rendThFilter(h, Object.assign(obj, {cfg: item}))"
>
<template slot-scope="scope">
<span v-if="!item.switch" class="mone_test_btn_text extended_display link" @click="triggerParentMethod(item.clickEvent, {index: scope.$index,                            <!--<el-button v-if="!item.switch" size="mini"  type="text">{{ w[item.prop] }}</el-button>-->
<span v-if="item.switch" class="link"
:
@click="triggerParentMethod(item.clickEvent, {index: scope.$index, row: w, columnConfig: item})"
>
{{ w[item.prop] }}
</span>
<!--<slot name="testSlot">myslot</slot>-->
</template>
</el-table-column>
<!-- -->
<!--:filters="item.filter" :filter-method="filterThead" :filtered-value="['HTTP']"-->
<el-table-column v-else-if="pe=='tagRound'" :prop="item.prop" :label="item.label" :width="item.width" :key="item.prop+index"
:render-header="(h,obj) => rendThFilter(h, Object.assign(obj, {cfg: item}))"
>
<template slot-scope="scope">
<span class="tag_Round" :
>
{{ w[item.prop] }}
</span>
</template>
</el-table-column>
<!-- -->
<el-table-column v-else-if="pe=='tag'" :prop="item.prop" :label="item.label" :width="item.width" :key="item.prop+index"
:render-header="(h,obj) => rendThFilter(h, Object.assign(obj, {cfg: item}))"
>
<template slot-scope="scope">
<span class="tag" :style="{
color: w[item.prop], 'color', item),
'background-color': w[item.prop], 'bgColor', item),
'border-color': w[item.prop], 'borderColor', item),
}"
>
{{ w[item.prop] }}
</span>
</template>
</el-table-column>
<!-- 操作列 -->
<el-table-column v-else-if="pe=='operation'" :label="item.label" :width="item.width" :key="item.prop+index"
:render-header="(h,obj) => rendThFilter(h, Object.assign(obj, {cfg: item}))"
>
<template slot-scope="scope">
<el-tooltip effect="dark" :content="ltip || oBtn.label" placement="top" v-for="oBtn in item.btns" :key="oBtn.id" popper-class="mone_test_d                                <span @click="triggerParentMethod(oBtn.clickEvent, {index: scope.$index, row: w, columnConfig: item, currBtnConfig: oBtn })" class                                    <i :class="oBtn.icon"></i>{{ oBtn.label }}
</span>
</el-tooltip>
</template>
</el-table-column>
<!-- 插槽 -->
<el-table-column v-else-if="pe=='slot'" :prop="item.prop" :label="item.label" :width="item.width" :key="item.prop+index"
:render-header="(h,obj) => rendThFilter(h, Object.assign(obj, {cfg: item}))"
>
<template slot-scope="scope">
<slot name="customColumn" :row="{...w}" :index="scope.$index" :colCfg="{...item}"></slot>
<!--<slot name="customColumn"  :data="{...scope}"></slot>-->
</template>
<!--<slot :data="{...scope}"></slot>-->
</el-table-column>
<!-- 默认 -->
<el-table-column v-else :prop="item.prop" :label="item.label" :width="item.width" :key="item.prop+index"
:render-header="(h,obj) => rendThFilter(h, Object.assign(obj, {cfg: item}))"
></el-table-column>
</template>
</template>
</el-table>
<div v-if="tableCfg.showPagination" v-show="data&&data.length>0" class="pagination_wrap">
<el-pagination ref="pagination" :current-page="pagination.pageNum" background
:page-sizes="pagination.pageSizes"
:page-size="pagination.pageSize"
:layout="pagination.layout"
:total="al"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
></el-pagination>
</div>
</div>
</template>
</template>
<script lang="ts">
import { Component, Vue, Prop, Watch} from 'vue-property-decorator'; // import { ElForm } from 'element-ui/types/form.js'
import { DefaultCfg, TableCfg } from './mocks'
import { DataTableService } from 'mone-test/services';
import _ from 'lodash';
import ThFilter from './thFilter.vue'
const DefaultPagination = {
pageNum: 1,
pageSizes: [10, 20, 30, 50],
pageSize: 10,
total: 0,
layout: 'total, sizes, prev, pager, next, jumper'
};
@Component({
name: 'DataTable',
components: {
}
})
export default class DataTable extends Vue {
/*** props ***/
@Prop({ type: Object, default: ()=>{ return {}; } }) configInfo;
@Prop({ type: Array, default: ()=>{ return []; } }) tableData;
/*** data ***/
tableCfg: object = {};
data: any = []; // 表格数据
filterCfg: object = []; // 筛选查询的配置
filterForm: object = {}; // 筛选查询的表单
isShowBatchOperationBtn = false;
toolbarCfg: object = {};
theadCfg: object = []; // 表头配置
columnStateCfg: object = { // 列显⽰隐藏相关
indeterminate: false,
checkAll: true,
showColumn: [], // 显⽰的列的
}; // 显⽰隐藏列的相关配置
pagination: object = {}; // 分页的相关配置
requestCfg: object = {}; // 请求配置
hasFilter: boolean = false; // 是否有筛选过滤
hasToolbarBtn: boolean = false; // 是否有⼯具按钮
hasToolbarBatchOperationBtn: boolean = false; // 是否有批量操作按钮    getDataThFilterParam: object = {}; // 查询数据的表头筛选参数
selectedData: object[] = [];
/*** computed ***/
/*** watch ***/
@Watch('configInfo', {deep: true})
getConfigInfo(newVal: string, oldVal: string){
this.initData();
}
constructor() {
super()
}
created(){
this.initData();
}
/*** methods ***/
// 初始化数据
initData(){
const self = this as any;
const self = this as any;
/
/ Object.figInfo, DefaultCfg);
self.tableCfg = _.extend({}, DefaultCfg, figInfo);
htmlborder// Object.Config, figInfo);
// 筛选
if(self.tableCfg.filter && self.tableCfg.filter.length){
self.filterCfg = _.extend([], self.tableCfg.filter);
self.filterForm = {};
self.tableCfg.filter.forEach(item => {
self.$set(self.filterForm, item.name, '');
});
self.hasFilter = true;
}
// toolbar
if(lbars && Object.keys(lbars).length){
self.hasToolbarBtn = lbarCfg.btn && lbarCfg.btn.length ? true : false;
self.hasToolbarBatchOperationBtn = lbarCfg.batchOperationBtn && lbarCfg.batchOperationBtn.length ? true : false;        }
// 表头配置
if(self.tableCfg.thead && self.tableCfg.thead.length){
self.theadCfg = _.extend([], self.tableCfg.thead);
// 表头筛选
self.tableCfg.thead.forEach(item => {
if(!!item.filterDefaultValue){
self.$DataThFilterParam, item.prop, item.filterDefaultValue);
}
});
}
// 显⽰隐藏列的相关配置
const showColumn: any[] = [];
self.theadCfg.forEach(item => {
if(!item.isHide){
showColumn.push(item.prop);
}
});
self.$lumnStateCfg, 'showColumn', showColumn);
// 分页
self.pagination = _.extend({}, (self.tableCfg as any).pagination);
// 请求配置
}
//
handleCommand(command) {
if(!command.clickEvent || command.clickEvent == '') return false;
this.$parent[command.clickEvent]();
}
// 切换显⽰批量操作按钮状态
changeBatchOperationState(state){
this.isShowBatchOperationBtn = state;
}
// 设置列显⽰隐藏状态
theadStateChange(item, isChecked, childrenChecked){
console.log(item);
console.log(isChecked);
console.log(childrenChecked);
}
/
/ 点击列显⽰/隐藏全选
columnStateClickAll(val){
console.log(val);

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。