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>
上一篇下一篇

猜你喜欢

热点阅读