美文网首页
Vue---动态遍历加载组件

Vue---动态遍历加载组件

作者: zsyyyyy | 来源:发表于2020-03-04 16:37 被阅读0次

    动态循环加载组件

    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>
    

    相关文章

      网友评论

          本文标题:Vue---动态遍历加载组件

          本文链接:https://www.haomeiwen.com/subject/zwgplhtx.html