需求是做一个表格(如图),表格中的每一列都需要做成单独组件,每个表头后都有一个筛选 类型不同显示的筛选也不同 根据需要可能显示的列数量也不一样,而且可能会有多个相同类型的 彼此不影响 请问这样应该怎么写
1、可copy的代码展示
<divclass="field"><divclass="inner">inputC:params="val"<divclass="bottom"><el-buttontype="primary"@click="update">编辑<el-buttontype="primary"@click="submit">提交<el-buttontype="primary"@click="search">查询<el-buttontype="primary"@click="search2">查询2
动态组件了解一下:
<!-- 动态组件由 vm 实例的 `componentId` property 控制 -->
<component :is="componentId"></component>
官方文档:https://v2.cn.vuejs.org/v2/api/#component
这是一个封装好的表格组件 ,里面的列一部分是引入的组件,和你这差不多可以参考下
组件:
<template>
<div style="height:100%">
<div :style="{height:'calc(100% - ' + (page.pageSize?'50px':'0px') +')'}">
<el-table ref="table" v-loading="loading" element-loading-text="Loading" :stripe="stripe" :data="tableData"
:row-key="rowKey" height="100%" fit :highlight-current-row="highlightCurrentRow" tooltip-effect="dark"
style="width: 100%" @sort-change="handleSortChange" @selection-change="handleSelectionChange"
@current-change="handleCheckChange" @row-click="rowClick">
<!--多选列-->
<el-table-column v-if="indexShow" label="序号" fixed type="index" align="center" width="50">
</el-table-column>
<el-table-column v-if="selectionShow" type="selection" width="50" align="center" highlight-current-row fixed
:reserve-selection="true"></el-table-column>
<el-table-column v-for="(item, index) in tableLabel" :width="item.width ? item.width : ''"
:fixed="item.fixed ? item.fixed : false" :type="item.type ? item.type : ''" :key="index"
:align="item.align ? item.align : 'center'" :label="item.label" :prop="item.prop"
:sortable="item.sortable ? 'custom' : false" show-overflow-tooltip v-show="index==1">
<template slot-scope="scope">
<slot v-if="item.slot" :scope="scope.row" :name="item.slot"></slot>
<div v-html="item.render(scope.row)" v-else-if="item.render"></div>
<span v-else>{{ scope.row[item.prop] }} {{ item.type }}</span>
</template>
</el-table-column>
<el-table-column v-if="tableOption.label" :width="tableOption.width" :label="tableOption.label" align="center"
class-name="small-padding fixed-width" :fixed="tableOption.fixed ? tableOption.fixed : false">
<template slot-scope="scope">
<el-button v-for="(item, index) in tableOption.options" :key="index" :type="item.type" :icon="item.icon"
@click="handleButton(item.methods, scope.row, scope.row)" size="mini">
{{ item.label }}
</el-button>
</template>
</el-table-column>
</el-table>
</div>
<div>
<el-button type="primary" class="btn_bg ml_30" style="margin-top: 6px;">导出本页</el-button>
<el-button type="primary" plain class="btn_bg btn_bg1" style="margin-top: 6px;">导出全部</el-button>
<el-pagination style="float:right" v-if="page.pageSize" background @size-change="handleSizeChange"
@current-change="handleCurrentChange" :current-page.sync="page.pageNo" :page-size="page.pageSize"
:page-sizes="[10, 20, 50, 100]" layout="total,sizes,prev, pager, next, jumper" :total="page.total">
</el-pagination>
</div>
</div>
</template>
<script>
export default {
props: {
loading: {
type: Boolean,
default: false,
},
page: {
type: Object,
default: () => {
return { total: 0, pageSize: 0, pageNo: 1 };
},
},
tableData: {
type: Array,
default: () => {
return [];
},
},
tableLabel: {
type: Array,
default: () => {
return [];
},
},
tableOption: {
type: Object,
default: () => {
return {};
},
},
indexShow: {
type: Boolean,
default: true,
},
selectionShow: {
type: Boolean,
default: false,
},
radioShow: {
type: Boolean,
default: false
},
rowKey: {
type: String,
default: 'id'
},
stripe: {
type: Boolean,
default: false,
},
highlightCurrentRow: {
type: Boolean,
default: true
},
},
data() {
return {
currentPage: 1,
}
},
components: {},
methods: {
handleButton(methods, row, index) {
// 按钮事件
this.$emit("handleButton", { methods: methods, row: row, index: index });
},
handleSortChange(val) {
// 排序
this.$emit("handleSortChange", val);
},
handleSelectionChange(val) {
this.$emit("handleSelectionChange", val);
},
handleCheckChange(val) {
this.$emit("handleCheckChange", val);
},
rowClick(val) {
this.$emit("rowClick", val);
},
handleSizeChange(val) {
// console.log(`每页 ${val} 条`);
this.$emit("handleCheckChange", {});
this.$emit("handleSizeChange", val);
},
handleCurrentChange(val) {
this.$emit("handleCheckChange", {});
this.$emit("handleCurrentChange", val);
}
},
};
</script>
<style scoped lang="less">
/deep/.el-button {
padding: 8px 8px 8px 27px;
border-width: 2px;
}
/deep/.btn_bg {
background: url(../assets/images/download_one.png) no-repeat #1c3d90!important;
background-position: 6px center!important;
}
/deep/.btn_bg1 {
background: url(../assets/images/download.png) no-repeat #fff!important;
background-position: 6px center!important;
}
/deep/.btn_bg:active,
.btn_bg:hover,
.btn_bg:focus {
background: url(../assets/images/download_one.png) no-repeat #1c3d90!important;
background-position: 6px center!important;
}
/deep/.btn_bg1:active,
.btn_bg1:hover,
.btn_bg1:focus {
background: url(../assets/images/download.png) no-repeat #fff !important;
background-position: 6px center !important;
color: #1c3d90 !important;
}
</style>
使用:
<vTable :table-data="tableData" :table-label="tableColumn" :page="page"></vTable>
列字段配置:
tableColumn: [{
prop: 'itemNumber',
label: '项目编号',
fixed: true,
width: '220',
slot: 'num'
}, {
prop: 'itemName',
label: '项目名称',
width: '280',
}, {
prop: 'itemCategory',
label: '项目类别',
width: '120',
render: (e) => { return changeCode('item_category', e.itemCategory) }
}, {
prop: 'itemStatus',
label: '项目阶段',
width: '180',
render: (e) => { return changeCode('item_status', e.itemStatus) }
},{
prop: 'itemContractNumber',
label: '合同编号',
width: '180',
}, {
prop: 'itemBudget',
label: '预算',
width: '180',
render: (e) => { return bigNumberTransform(e.itemBudget,'table') }
}, {
prop: 'itemIndustry',
label: '所属行业',
width: '180',
render: (e) => { return changeCode('item_industry', e.itemIndustry) }
}, {
prop: 'itemState',
label: '项目状态',
width: '180',
render: (e) => { return changeCode('item_state', e.itemState) }
}, {
prop: 'itemArea',
label: '项目地区',
width: '150',
}, {
prop: 'itemScale',
label: '规模',
width: '150',
render: (e) => { return changeCode('item_budget', e.itemScale) }
}, {
prop: 'itemTotalInvestment',
label: '立项总投资',
width: '120',
render: (e) => { return bigNumberTransform(e.itemTotalInvestment,'table') }
}, {
prop: 'itemGroupInvestment',
label: '集团投资/认缴出资额',
width: '240',
render: (e) => { return bigNumberTransform(e.itemGroupInvestment,'table') }
}, {
prop: 'itemPrimaryCoverage',
label: '主要内容',
width: '220',
}, {
prop: 'itemRegionalDepartment',
label: '区域事业部/单位',
width: '240',
}, {
prop: 'itemSixAreas',
label: '五大领域',
width: '150',
render: (e) => { return changeCode('item_six_areas', e.itemSixAreas) }
}, /* {
prop: 'itemIsEstablishment',
label: '是否立项',
width: '150',
render: (e) => { return changeCode('yesOrNo', e.itemIsEstablishment) }
}, // {
prop: 'itemIsExample',
label: '是否示范项目',
width: '240',
render: (e) => { return changeCode('yesOrNo', e.itemIsExample) }
}, {
prop: 'itemExampleType',
label: '示范项目类型',
width: '240',
render: (e) => { return changeCode('item_example_type', e.itemExampleType) }
},/ {
prop: 'itemIsReserve',
label: '是否储备项目',
width: '240',
render: (e) => { return changeCode('yesOrNo', e.itemIsReserve) }
}, {
prop: 'itemIsPlan',
label: '是否计划内项目',
width: '240',
render: (e) => { return changeCode('yesOrNo', e.itemIsPlan) }
}, {
prop: 'itemIsNewCreat',
label: '是否新建项目',
width: '240',
render: (e) => { return changeCode('yesOrNo', e.itemIsNewCreat) }
}, {
prop: 'itemIsEstablishCompany',
label: '是否成立项目公司',
width: '240',
render: (e) => { return changeCode('yesOrNo', e.itemIsEstablishCompany) }
}, / {
prop: 'itemIsIndustrialInfrastructure',
label: '是否产业基建项目',
width: '240',
render: (e) => { return changeCode('yesOrNo', e.itemIsIndustrialInfrastructure) }
}, */{
prop: 'itemDocumentNumber',
label: '文号',
width: '180',
}, {
prop: 'itemApprovalTime',
label: '批复时间',
width: '240',
}, {
prop: 'itemProjectCompany',
label: '项目公司',
width: '220',
}, {
prop: 'itemFilingSubmission',
label: '提交备案表时间',
width: '240',
}, {
prop: 'itemContactsPeople',
label: '联系人',
width: '150',
}, {
prop: 'itemRemark',
label: '备注',
width: '150',
}, {
prop: 'itemConclusionTime',
label: '审结时间',
width: '240',
}],
使用动态组件完成即可。如果数据库中保存的是组件路径,直接使用import(路径)
动态引入组件,如果数据库中保存的是完成的模板,则可以直接将模板内容赋值给currentCom
。
第二种方式如果使用tempalte
模板,则需要在vite.config.ts
中指定vue
的别名vue.esm-bundler.js
<template>
<component :is="currentCom"></component>
</template>
<script setup lang="ts">
import { shallowRef } from 'vue'
import type { Component } from 'vue'
let currentCom = shallowRef<Component>()
// 按路径加载组件
// import('./components/Home.vue').then(res => {
// currentCom.value = res.default
// })
// 直接组件赋值
currentCom.value = {
template: `<div>111</div>`
}
</script>
把所有组件路径放在一个数组里面,需要哪个再动态引入哪个
添加动态路由https://blog.csdn.net/qq_53018334/article/details/127032479?spm=1001.2014.3001.5501
看一下我这个应该能帮助到你 https://blog.csdn.net/qq_37215621/article/details/126653345
</component
所有组件的路径放在数组里,然后更加需要选择哪个组件
window监听鼠标的点击事件,根据点击的元素,动态将表单插进去,并展开。
单独用一个数组存需要展示的列,动态渲染。