Vue项目实战:订单列表页面实现

目录

在这里插入图片描述

(1)调整Order父组件结构(解决Bug)

之前在Vue项目实战:订单确认页面实现中关于订单父组件结构封装里写到:在order.vue中引入<order-header></order-header>,然后通过路由判断当前页面属于哪个,并展示不同内容。但现在发现那样子做存在一个问题:

问题

在使用微信支付完后跳转到订单列表页面,但是订单列表页面中的<order-header></order-header>的内容仍是订单支付页面中<order-header></order-header>的内容,没有变成<order-header></order-header>对应的内容。但是如果跳转完订单列表页面,在重新刷新一下页面,那<order-header></order-header>的内容就会改变。

原因

订单列表的路由是order的子路由,当我们从order路由跳转到它的子路由时,并不会再次执行order.vue中的mounted()函数。此函数只有在页面渲染时才会执行。也就是说,如果想用之前的方法,那只有在第一次从别的路由(比如购物车路由)跳转到订单列表路由时,此前order页面并没有被渲染过,则可以出现相应的<order-header></order-header>组件内容。如果是从订单订单确认跳转到订单列表的话,此时没有重新渲染order页面,那<order-header></order-header>内容不会改变。

解决方法

不用之前的第二种方法,删去之前路由判断的代码,而用第一次,在每个页面中引入<order-header></order-header>

如,在orderConfirm.vue:

    <order-header title="订单确认">
      <template v-slot:tip>
        <span>请认真填写收货地址</span>
      </template>
    </order-header>
<script>
import OrderHeader from "./../components/OrderHeader";
export default {
  components: {
    OrderHeader,
  }
}

(2)订单列表数据渲染

在orderList.vue中:

<!-- 省略不重要代码,下面是如何判断并展示订单状态 -->
			<div class="good-state fr" v-if="order.status == 20">
                <a href="javascript:;">{{order.statusDesc}}</a>
              </div>
              <div class="good-state fr" v-else>
                  <a href="javascript:;" @click="goPay(order.orderNo)">{{order.statusDesc}}</a>
              </div>
<script>
  export default{
    data() {
        return {
            list: []
        }
    },
    mounted() {
        this.getOrderList();
    },
    methods: {
        getOrderList() {
            this.axios.get('/orders').then((res) => {
                this.list = res.list;
            })
        },
        goPay(orderNo) {
            //三种路由跳转方式
            this.$router.push({
                path: '/order/pay',
                query: {
                    orderNo
                }
            })
           /* this.$router.push({
                name: 'order-pay',
                query: {
                    orderNo
                }
            })
            */ 
           //this.$router.push('/order/pay')         
        }
    }
  }
</script>

(3)Loading 和 NoData优化

  • 在orderList.vue中引入并使用之前定义的Loading组件:

    这个优化是针对请求发出来,响应还没回来前做个loading处理。在请求时显示,请求回来后不显示。

<loading v-if="loading"></loading>   //3.使用组件
<script>
  import Loading from './../components/Loading';  //1.导入组件
  export default{
    components:{
      Loading  //2.注册组件
    },
    data() {
        return {
            loading: true
        }
    },
    methods: {
        getOrderList() {
            this.axios.get('/orders').then((res) => {
                this.loading = false;
                this.list = res.list;
            }).catch(() => {
                this.loading = false;
            })
        } 
  }
  • NoData优化:

    在订单列表无数据时,显示NoData组件,给用户订单列表为空提示。

    在components文件夹中新建NoData.vue:

<template>
  <div class="no-data">
    <img src="/imgs/icon-no-data.png" alt="">
    <p>当前暂无提交的订单记录.</p>
  </div>
</template>
<!--此处省略样式等不重要代码-->

​ 在orderList.vue中引入并使用NoData组件:

<no-data v-if="!loading && list.length == 0"></no-data>
<script>
  import NoData from './../components/NoData';
  export default{
    components:{
      NoData
    },
    data() {
        return {
            list: [],
            loading: true
        }
    },
    methods: {
        getOrderList() {
            this.axios.get('/orders').then((res) => {
              this.loading = false;
                this.list = [] || res.list;
            }).catch(() => {
              this.loading = false;
            })
        },
    }
  }

(4)订单列表分页 - 分页器

​ 在orderList.vue中使用ElementUI中的Pagination组件:

          <el-pagination
            class="pagination"
            background
            layout="pre, pager, next"
            :pageSize="pageSize"
            :total="total"
            @current-change="handleChange"
          ></el-pagination>
<script>
  import {Pagination} from 'element-ui';
  export default{
    components:{
      [Pagination.name]: Pagination
    },
  data() {
    return {
      list: [],
      loading: false,
      pageSize: 10, //每页几条数据
      pageNum: 1,  //当前是第几页
      total: 0   //总条数
    };
  },
  mounted() {
    this.getOrderList();
  },
  methods: {
    getOrderList() {
      this.axios
        .get("/orders", {
          params: {
            pageNum: this.pageNum
          }
        })
        .then(res => {
          this.loading = false;
          this.list = [] || res.list;
          this.total = res.total;
        })
        .catch(() => {
          this.loading = false;
        });
    },
    handleChange(pageNum) {
      this.pageNum = pageNum;
      this.getOrderList();
    }
  }
};
</script>

(5)订单列表分页 - 加载更多

​ 在orderList.vue中使用ElementUI中的Button组件:

<div class="load-more" v-if="showNextPage">
	<el-button type="primary" :loading="loading" @click="loadMore">加载更多</el-button>    
</div>
<script>
  import {Button} from 'element-ui';
  export default{
    components:{
      [Button.name]: Button
    },
  data() {
    return {
      list: [],
      loading: false,
      pageSize: 10,
      pageNum: 1,
      showNextPage: true, //是否显示按钮,但数据都加载完了,就不需要显示“加载更多”按钮。
    };
  },
  methods: {
    getOrderList() {
      this.axios
        .get("/orders", {
          params: {
            pageNum: 10,
            pageNum: this.pageNum
          }
        })
        .then(res => {
          this.loading = false;
          this.list = res.list.concat(res.list);  //数据累加
          this.showNextPage = res.hasNext
        })
        .catch(() => {
          this.loading = false;
        });
    },
      loadMore() {
          this.pageNum++;
          this.getOrderList();
      }   
  }
};
</script>

(6)订单列表分页 - 滚动加载

  • 安装该插件:

    npm install vue-infinite-scroll --save

  • 在orderList.vue中使用Vue中的vue-infinite-scroll插件:

<div class="scroll-more"
     v-infinite-scroll="scrollMore"
     infinite-scroll-disabled = "busy"
     infinite-scroll-distance="410"
     >
    <img src="/imgs/loading-svg/loading-spinning-bubbles.svg" alt="" v-show="loading">
</div>
<script>
// v-infinite-scroll="scrollMore" :滚动的时候会调用的方法
//infinite-scroll-disabled = "busy" : 控制滚动加载是否有效,在busy为false:滚动才有效,才能触发loadMore函数,为true时,滚动不会触发函数。
//infinite-scroll-distance="410" : 不是距离底部410px时才触发loadMore函数
  import {Button} from 'element-ui';
  export default{
    directives: {infiniteScroll},
    components:{
      [Button.name]: Button
    },
  data() {
    return {
      list: [],
      loading: false,
      pageSize: 10,
      pageNum: 1,
      busy: false,  //滚动加载,是否触发
    };
  },
  methods: {
    getOrderList() {
      this.loading = true; 
      this.busy = true;
      this.axios
        .get("/orders", { 
          params: {
            pageNum: 10,
            pageNum: this.pageNum
          }
        })
        .then(res => {
          this.loading = false;
          this.list = res.list.concat(res.list);  //数据累加
          this.busy = false;
        })
        .catch(() => {
          this.loading = false;
        });
    },
    getList() {
      this.loading = true;
      this.busy = true;
      this.axios
        .get("/orders", {
          params: { 
            pageNum: 10,
            pageNum: this.pageNum
          }
        })
        .then(res => {
          this.list = res.list.concat(res.list);  //数据累加
          this.loading = false;
          if(res.hasNextPage) {
              this.busy = false;
          } else {
              this.busy = true;
          }
        })
    },
      scrollMore() { 
          this.busy= true;
          setTimeout(() => {
              this.pageNum++;
              this.getList();
          }, 500)
      }   
  }
};
</script>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章