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>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章