iT邦幫忙

2021 iThome 鐵人賽

DAY 18
0
Modern Web

前端暴龍機,Vue2.x 進化 Vue3系列 第 18

[前端暴龍機,Vue2.x 進化 Vue3 ] Day18.組件練習-分頁(一)

組件的部份因為有比較複雜,所以會做個小練習來熟悉一點 - 分頁的組件

分頁組件(props & $emit 運用)

快速利用簡單的分頁組件範例來寫個小練習吧

  需求:
   1. 分頁組件會有上一頁、下一頁以及總共的各頁數按鈕可以點擊
   2. pageSize、pageIndex、pageCount、itemCount 由父組件傳送過來
   

先定義好子組件

Vue.component('page-component', {
    template: `
        <div>
            <button type="button" @click="prev">上一頁</button>
            <button :class="{pagenow: pageIndex === item}" type="button" v-for="item in pageCount" @click="pageToIndex(item)">{{ item }}</button>
            <button type="button" @click="next">下一頁</button>
        </div>
    `,
    props: ['pageSize', "pageIndex", "pageCount", "itemCount"], //使用`props`聲明它所獲得的資料
    data: function () {
        return {
            pageIdx: 0
        }
    },
    mounted() {
        // 接收資料後更新當前的頁數
        this.setPage(this.pageIndex);
    },
    methods: {
        prev() {
            if (this.pageIndex <= 1) return;
            
            // 因為不能拿 父層的 pageIndex 做運算,所以用子組件拷貝過來的 pageIdx 運算
            this.pageIdx--;
            
            // 回傳資料給父層,告知前一頁頁數該為多少
            this.$emit("uplist", this.pageIdx);
        },
        next() {
            if (this.pageIndex === this.pageCount) return;
            this.pageIdx++;
            
            // 回傳資料給父層,告知下一頁頁數該為多少
            this.$emit("uplist", this.pageIdx);
        },
        setPage(p) {
        
            // 同步父層的 pageIndex
            this.pageIdx = p;
        },
        pageToIndex(p){
        
            // 回傳資料給父層,告知直接跳轉至該頁數
            this.$emit("uplist", p);
        }
    },
});

在子組件中,因為不能直接去動父組件傳送過來的資料 pageIndex,所以我這邊會定義一個 pageIdx 來跟父層的 pageIndex 同步,也方便其他地方做運算的需求

因為要讓當前頁數 pageIndex 符合在總範圍頁數內,所以在上一頁、下一頁觸發的事件中,就可以用 pageIdx 做運算後(上面提到 不能直接去動父組件傳送過來的資料),傳送預期的頁數(pageIndex)給父層

父組件編輯

首先,建立好模板及 props

<div id="app">
  <ul>
      <li v-for="item in renders">{{ item.text }}</li>
  </ul>
  <page-component :page-size="pageSize" :page-index="pageIndex" :page-count="pageCount"
      :item-count="itemCount" @uplist="newlist"></page-component>
</div>

再來,處理假資料的渲染及接收子組件的訊息處理

<script>
var app = new Vue({
  el: '#app',
  data:{
    pageIndex: 1,
    pageCount: 3,
    itemCount: 6,
    pageSize: 2,
    datas: [
        { id: 1, text: "1111" },
        { id: 2, text: "2222" },
        { id: 3, text: "3333" },
        { id: 4, text: "4444" },
        { id: 5, text: "5555" },
        { id: 6, text: "6666" },
    ]
  },
  computed:{
    renderData(){
    
      // 運用 computed 處理資料 filter 方法
      if (this.pageIndex === 1) {
          return this.datas.filter(ele => ele.id <= 2);
      }
      if (this.pageIndex === 2) {
          return this.datas.filter(ele => ele.id > 2 && ele.id <= 4);
      }
      if (this.pageIndex === 3) {
          return this.datas.filter(ele => ele.id > 4 && ele.id <= 6);
      }
    }
  },
  methods:{
      newlist(e) {
          
          // 接收到子組件訊息後的處理
          this.pageIndex = e;
      }
  }
})
</script>

父層的當前頁數資料渲染,透過先前提及的 computed 做處理,方便當條件變更時,自動更新渲染資料,做換頁的動作(模擬後端丟資料)

接著定義當收到子組件傳來的訊息時應該要做的動作 newlist function(),就完成啦~
https://ithelp.ithome.com.tw/upload/images/20210818/2012072264xyacLSqQ.jpg

範例展示


上一篇
[前端暴龍機,Vue2.x 進化 Vue3 ] Day17.父子組件的溝通-$emit
下一篇
[前端暴龍機,Vue2.x 進化 Vue3 ] Day19.組件練習 ref -分頁(二)
系列文
前端暴龍機,Vue2.x 進化 Vue330
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言