Vue---动态遍历加载组件
2020-03-04 本文已影响0人
zsyyyyy
动态循环加载组件
1,需求场景: image.png如上图的弹框的搜索筛选条件:每一项的都是一个组件,通过动态遍历加载出来,而且右边可以控制每一项的排序以及是否显示隐藏在外面
image.png
直接上代码:
因为筛选搜索条件是每个选项卡都需要的,所以就把筛选搜索条件放在每个选项卡上面公用,同时筛选搜索条件放在一个组件里遍历
-父组件部分-
<div>
<el-tabs v-model="reminderVEnums" @tab-click="handleClick">
<!--高级搜索子组件-->
<advancedSearch
style="margin:20px 0 30px 0"
:filter.sync="filter"
:reminderVEnums.sync="reminderVEnums"
v-show="reminderVEnums!='rework'" <!--因为上面"开发票选项卡"不需显示,所以这里判断一下-->
ref="advancedSearch">
</advancedSearch>
<!-- 第一个选项卡开始 -->
<el-tab-pane :label="'待发货订单('+NEW_ORDER+')'" name="NEW_ORDER">
<!-- 选项卡子组件-->
<remindertable:orderList="orderList"></remindertable>
</el-tab-pane>
<!-- 第一个选项卡结束 -->
<!--后面的选项卡就不放出来了-->
</el-tabs>
</div>
<script lang="ts">
import Vue from "vue";
import Component from "vue-class-component";
import remindertable from "./remindertable";//选项卡子组件
import advancedSearch from "./components/advancedSearch";//高级搜索子组件
@Component({
props: {},
components: { //注册组件
remindertable,
advancedSearch
}
})
export default class AfterOrder extends Vue {
reminderVEnums = "NEW_ORDER";//选项卡默认选中待发货
//高级搜索的初始值
filter = {
rderStatus: "ORDER_WAIT_SENDGOODS", //默认页面加载待发货状态选项卡
paymentMode: "", //支付方式
preDrugType: [""], //处方类型
patientKeyword: null, //医院信息关键字
hospitalKeyword: null, //患者信息关键字
consigneeKeyword: null, //收件信息关键字
prescriptionOrderKeyword: null, //订单处方关键字
minPrice: null,
maxPrice: null,
orderTime: [] //时间
};
//切换选项卡就初始化filter
handleClick(tab, e) {
this.filter.rderStatus = "";
this.filter.paymentMode = "";
this.filter.orderTime = [""];
this.filter.preDrugType = [""];
this.filter.patientKeyword = null;
this.filter.hospitalKeyword = null;
this.filter.consigneeKeyword = null;
this.filter.prescriptionOrderKeyword = null;
}
}
</script>
这里看看组件的目录结构
image.png
-子组件部分开始-
<template>
<div>
<el-form label-width="80px" :inline="true" class="demo-form-inline">
<!-- 外面的条件搜索筛选显示 <!-- :is为动态组件,is属性指向谁,就显示哪个组件,或者true显示,false隐藏-->-->
<component
v-for="item in obj"
:is="(reminderVEnums!='ALL'&&item.content=='orderStatusEnum')?'':(item.showFlag?item.content:'')"
:key="item.id"
:filter.sync="filter"
style="display:inline-block"
></component>
<el-button
type="primary"
icon="el-icon-search"
@click="search()"
style="display:inline-block;vertical-align:top;margin-left:20px"
v-show="searchBtn"
>搜索</el-button>
<el-button
type="primary"
icon="el-icon-search"
@click="show()"
style="display:inline-block;vertical-align:top;margin-left:20px"
>高级搜索</el-button>
</el-form>
<!--高级搜索的弹框-->
<el-dialog
title="高级搜索"
:visible.sync="dialogVisible"
width="40%"
center
:close-on-click-modal="false"
:close-on-press-escape="false"
@close="hidden()"
>
<el-form label-width="100px" v-bouncing="loading">
<!-- 组件循环 高级搜索弹框里面的搜索条件组件遍历 -->
<component
v-for="item in obj"
:is="reminderVEnums!='ALL'&&item.content=='orderStatusEnum'?'':item.content"
:key="item.id"
:filter.sync="filter"
:list.sync="obj"
:current.sync="item"
:dialog="true"
></component>
<span slot="footer" class="dialog-footer">
<el-button @click="hidden()">取 消</el-button>
<el-button type="primary" @click="search()" style="margin-left: 50px;">搜 索</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import orderStatusEnum from "./advancedSearch/orderStatusEnum.vue";
import paymentMode from "./advancedSearch/paymentMode.vue";
import preDrugType from "./advancedSearch/preDrugType.vue";
import price from "./advancedSearch/price.vue";
import patientKeyword from "./advancedSearch/patientKeyword.vue";
import hospitalKeyword from "./advancedSearch/hospitalKeyword.vue";
import consigneeKeyword from "./advancedSearch/consigneeKeyword.vue";
import prescriptionOrderKeyword from "./advancedSearch/prescriptionOrderKeyword.vue";
import orderTime from "./advancedSearch/orderTime.vue";
import moment from "moment";
import * as api from "../../../api/orderapi";
import * as Config from "../../../api/conf";
export default {
//注册筛选条件组件
components: {
orderStatusEnum,
paymentMode,
preDrugType,
patientKeyword,
hospitalKeyword,
consigneeKeyword,
prescriptionOrderKeyword,
price,
orderTime
},
//父子通讯数据
props: ["filter", "reminderVEnums"],
data() {
return {
loading: false,//loading状态
dialogVisible: false,//高级搜索弹框
obj: [],//后台返回的需要遍历的"搜索条件"
};
},
created() {
this.getAdvancedSearch();
},
//监听夫传子的数据变化
watch: {
filter: {
handler(newValue, oldValue) {
console.log(555555,newValue);
this.filter = newValue;
},
deep: true
}
},
computed: {
searchBtn: function() {
return this.obj.filter(i => i.showFlag == true).length > 0;
}
},
methods: {
//获取高级搜索条件的请求方法
getAdvancedSearch() {
this.loading = true;
api.getAdvancedSearch().then(res => {
//需要重新排序(处理新增、删除的情况)
// this.obj = res.data;
this.loading = false;
if (res.success) {
console.log(55555,res)
let list = this.util.copyObj(res.data);
list.map((item, index) => {
item.sort = list.length - index;
return item;
});
this.obj = list;
} else {
console.error(res.message);
this.$message.error(res.message);
}
})
.catch(res => {
console.error(res);
});
},
//后台返回的数据格式:
[
{
id: 8,//id
name: "订单金额",//label
content: "price",//组件名
sort: 9,//排序
showFlag: false,//是否把筛选显示在外面
showTime: "2020-03-04 13:54:44"//显示的时间记录
},
{
id: 1,
name: "订单状态",
content: "orderStatusEnum",
sort: 8,
showFlag: true,
showTime: "2020-03-04 13:54:44",
},
{
id: 8
name: "订单金额"
content: "price"
sort: 9
showFlag: false
showTime: "2020-03-04 13:54:44"
}
]
//这里就不全部写出来
//修改高级搜索(上升下降显示掩藏,需要对后台)
editAdvancedSearch(d) {
this.loading = true;
d = { list: d };
api.editAdvancedSearch(d).then(res => {
this.loading = false;
if (res.success) {
this.getAdvancedSearch();
} else {
console.error(res.message);
this.$message.error(res.message);
}
})
.catch(res => {
console.error(res);
});
},
show() {
this.dialogVisible = true;
},
hidden() {
this.dialogVisible = false;
},
//升序、降序
ascending(name, isAscending) {
let list = this.util.copyObj(this.obj);
//找出当前升序的数据
let obj = list.find(i => i.content == name);
//旧序号
let oldSort = obj.sort;
//新序号
let newSort = isAscending ? oldSort + 1 : oldSort - 1;
if (newSort > list.length || newSort <= 0) {
this.$message.error("序号错误");
}
list.forEach(i => {
//升序
if (i.content == name) {
i.sort = newSort;
} else {
//降序
if (i.sort == newSort) {
i.sort = oldSort;
}
}
});
this.editAdvancedSearch(this.package(list));
},
//搜索
search() {
this.$parent.$parent.getOrderList(true);
},
//组装数组
package(list) {
var d = [];
list.forEach(i => {
d.push({ id: i.id, sort: i.sort, showFlag: i.showFlag });
});
return d;
},
//外面搜素条件显示或隐藏
showHandle(name) {
let list = this.util.copyObj(this.obj);
list.forEach(i => {
if (i.content == name) {
i.showFlag = !i.showFlag;
}
});
this.editAdvancedSearch(this.package(list));
},
}
};
</script>
-以下是每一项的筛选条件(相当于孙组件)-
这里就上传一项的筛选条件组件代码,其他也是一样的,只是每一个筛选条件放在一个组件即可
<template>
<div>
<el-form-item label="支付方式" style="margin-bottom: 10px;">
<el-select v-model="filter.paymentMode" :style="{width:(list?'70%':'200px')}">
<el-option
v-for="(item,index) in paymentList"
:value="item.code"
:label="item.name"
:key="index"
></el-option>
</el-select>
<img
src="../../../../assets/shangyi.png"
class="img"
@click="ascending()"
v-show="showAscending"
v-if="list"
/>
<img
src="../../../../assets/xiayi.png"
class="img"
@click="descending()"
v-show="showDescending"
v-if="list"
/>
<el-button round style="float: right;padding: 7px 12px;" v-if="list" @click="showHandle">{{hidden?'隐藏':'显示'}}</el-button>
</el-form-item>
</div>
</template>
<script>
export default {
props: ["filter", "list", "current"],
data() {
return {
paymentList: [
{
code: "",
name: "全部"
},
{
code: "PAY_IN_SHOP",
name: "到店支付"
},
{
code: "HAND_PAYMENT",
name: "二维码支付"
},
{
code: "ORDER_PAY_ONDEV",
name: "货到付款"
},
{
code: "ONLINE_PAYMENT",
name: "微信支付"
},
{
code: "DRUG_SHOP_PAYMENT",
name: "门店支付"
},
{
code: "PAY_IN_HOSPITAL",
name: "院内支付"
}
]
};
},
computed: {
hidden: function() {
return this.current.showFlag;
},
//是否展示升序
showAscending: function() {
return this.list.length != this.current.sort;
},
//是否展示降序
showDescending: function() {
return 1 != this.current.sort;
}
},
created() {},
methods: {
//升序
ascending() {
this.$parent.$parent.$parent.ascending("paymentMode", true);
},
//降序
descending() {
this.$parent.$parent.$parent.ascending("paymentMode", false);
},
//是否把筛选搜索条件显示外面
showHandle() {
this.$parent.$parent.$parent.showHandle("paymentMode");
}
}
};
</script>