在線商城項目06-商品列表頁前端邏輯實現(xiàn)

簡介

本篇,我們做一些商品列表頁的前端邏輯功能。

  1. 價格過濾列表的點擊邏輯
  2. 價格過濾列表的露出邏輯
  3. 排序點擊的邏輯

1. 價格過濾列表的點擊邏輯

step1:價格過濾列表的字段顯示。
這里,我們不做太復(fù)雜的邏輯,這些過濾字段不從后端請求,也不由用戶輸入,而是在前端寫死。在GoodsList.vue中進行如下修改:

          <div class="filter stopPop" id="filter">
            <dl class="filter-price">
              <dt>Price:</dt>
              <dd><a href="javascript:void(0)">All</a></dd>
              <dd v-for="(item, index) in priceFilterList" :key="item.index">
                <a v-if="item.endPrice" href="javascript:void(0)">{{item.startPrice}} - {{item.endPrice}}</a>
                <a v-else href="javascript:void(0)">> {{item.startPrice}}</a>
              </dd>
            </dl>
          </div>

  data () {
    return {
      prdList: [],
      priceFilterList: [
        {
          startPrice: 0,
          endPrice: 100
        },
        {
          startPrice: 100,
          endPrice: 500
        },
        {
          startPrice: 500,
          endPrice: 2000
        },
        {
          startPrice: 2000
        }
      ]
    }
  }

step2: 點擊某個過濾項時會點亮并且請求數(shù)據(jù)
在GoodsList.vue中進行如下修改:

          <div class="filter stopPop" id="filter">
            <dl class="filter-price">
              <dt>Price:</dt>
              <dd><a href="javascript:void(0)" :class="{'cur': priceChecked === 'all'}" @click="checkPriceFilter('all')">All</a></dd>
              <dd v-for="(item, index) in priceFilterList" :key="index">
                <a v-if="item.endPrice" href="javascript:void(0)" :class="{'cur': priceChecked === index}" @click="checkPriceFilter(index)">{{item.startPrice}} - {{item.endPrice}}</a>
                <a v-else href="javascript:void(0)" :class="{'cur': priceChecked === index}" @click="checkPriceFilter(index)">> {{item.startPrice}}</a>
              </dd>
            </dl>
          </div>

  data () {
    return {
      prdList: [],
      priceFilterList: [
        {
          startPrice: 0,
          endPrice: 100
        },
        {
          startPrice: 100,
          endPrice: 500
        },
        {
          startPrice: 500,
          endPrice: 2000
        },
        {
          startPrice: 2000
        }
      ],
      priceChecked: 'all',
      filterPrice: null
    }
  }

  methods: {
    getPrdList (params) {
      axios.get('mock/goods', {params: params}).then((res) => {
        console.log('res', res)
        let data = (res && res.data) || {}
        if (data.code === '000') {
          this.prdList = data.result || []
          console.log('prdList', this.prdList)
        } else {
          alert(`err:${data.msg || '系統(tǒng)錯誤'}`)
        }
      })
    },
    checkPriceFilter (index) {
      this.priceChecked = index
      this.filterPrice = index === 'all' ? null : this.priceFilterList[index]
      this.getPrdList(this.filterPrice)
    }
  }
}

此時點擊不同過濾項會點亮該過濾項并帶上相應(yīng)參數(shù)去請求獲取產(chǎn)品列表的接口,目的達到。

2. 價格過濾列表的露出邏輯

由于頁面使用響應(yīng)式,當(dāng)屏幕寬度過小時價格過濾列表會隱藏。此時我們要控制價格過濾列表的展現(xiàn)與消失邏輯。主要有以下邏輯:

  1. 點擊FILTER BY按鈕,右側(cè)會彈出價格過濾列表,并會展現(xiàn)遮罩層
  2. 選取價格以后會帶參請求產(chǎn)品列表數(shù)據(jù),并關(guān)閉彈層和遮罩層
  3. 點擊遮罩層會關(guān)閉彈層和遮罩層
    實現(xiàn)代碼如下:
<template>
  <div>
    <PageHeader></PageHeader>
    <PageBread>
      <span>Goods</span>
    </PageBread>
    <div class="accessory-result-page accessory-page">
      <div class="container">
        <div class="filter-nav">
          <span class="sortby">Sort by:</span>
          <a href="javascript:void(0)" class="default cur">Default</a>
          <a href="javascript:void(0)" class="price">Price
            <svg class="icon icon-arrow-short">
              <symbol id="icon-arrow-short" viewBox="0 0 25 32">
                <title>arrow-short</title>
                <path class="path1" d="M24.487 18.922l-1.948-1.948-8.904 8.904v-25.878h-2.783v25.878l-8.904-8.904-1.948 1.948 12.243 12.243z"></path>
              </symbol>
              <use xlink:href="#icon-arrow-short"></use>
            </svg>
          </a>
          <a href="javascript:void(0)" class="filterby stopPop" @click="showFilterBy">Filter by</a>
        </div>
        <div class="accessory-result">
          <!-- filter -->
          <div class="filter stopPop" id="filter" :class="{'filterby-show': isShowFilterBy}">
            <dl class="filter-price">
              <dt>Price:</dt>
              <dd><a href="javascript:void(0)" :class="{'cur': priceChecked === 'all'}" @click="checkPriceFilter('all')">All</a></dd>
              <dd v-for="(item, index) in priceFilterList" :key="index">
                <a v-if="item.endPrice" href="javascript:void(0)" :class="{'cur': priceChecked === index}" @click="checkPriceFilter(index)">{{item.startPrice}} - {{item.endPrice}}</a>
                <a v-else href="javascript:void(0)" :class="{'cur': priceChecked === index}" @click="checkPriceFilter(index)">> {{item.startPrice}}</a>
              </dd>
            </dl>
          </div>

          <!-- search result accessories list -->
          <div class="accessory-list-wrap">
            <div class="accessory-list col-4">
              <ul>
                <li v-for="item in prdList" :key="item.productId">
                  <div class="pic">
                    <a href="#"><img v-lazy="`../../../static/${item.productImage}`" alt=""></a>
                  </div>
                  <div class="main">
                    <div class="name">{{item.productName}}</div>
                    <div class="price">{{item.salePrice}}</div>
                    <div class="btn-area">
                      <a href="javascript:;" class="btn btn--m">加入購物車</a>
                    </div>
                  </div>
                </li>
              </ul>
            </div>
          </div>
        </div>
      </div>
    </div>
    <div class="md-overlay" v-show="isShowOverLay" @click="closeFilterBy"></div>
    <PageFooter></PageFooter>
  </div>
</template>

<script>
import PageHeader from '../../components/PageHeader'
import PageBread from '../../components/PageBread'
import PageFooter from '../../components/PageFooter'
import axios from 'axios'

export default {
  data () {
    return {
      prdList: [], // 產(chǎn)品列表
      // 價格過濾列表
      priceFilterList: [
        {
          startPrice: 0,
          endPrice: 100
        },
        {
          startPrice: 100,
          endPrice: 500
        },
        {
          startPrice: 500,
          endPrice: 2000
        },
        {
          startPrice: 2000
        }
      ],
      priceChecked: 'all', // 選中的價格過濾列表項
      filterPrice: null, // 選中的價格過濾列表對象
      isShowFilterBy: false, // 是否展示過濾列表彈窗
      isShowOverLay: false // 是否展示遮罩層
    }
  },
  components: {
    PageHeader,
    PageBread,
    PageFooter
  },
  created () {
    this.getPrdList()
  },
  methods: {
    // 請求接口獲取產(chǎn)品列表數(shù)據(jù)
    getPrdList (params) {
      axios.get('mock/goods', {params: params}).then((res) => {
        console.log('res', res)
        let data = (res && res.data) || {}
        if (data.code === '000') {
          this.prdList = data.result || []
          console.log('prdList', this.prdList)
        } else {
          alert(`err:${data.msg || '系統(tǒng)錯誤'}`)
        }
      })
    },
    // 選取價格過濾列表項
    checkPriceFilter (index) {
      this.priceChecked = index
      this.filterPrice = index === 'all' ? null : this.priceFilterList[index]
      this.getPrdList(this.filterPrice)
      this.closeFilterBy()
    },
    // 展示過濾列表彈窗
    showFilterBy () {
      this.isShowFilterBy = true
      this.isShowOverLay = true
    },
    // 關(guān)閉過濾列表彈窗
    closeFilterBy () {
      this.isShowFilterBy = false
      this.isShowOverLay = false
    }
  }
}
</script>

3. 排序點擊的邏輯

這里我們只設(shè)置了默認(rèn)排序以及按價格升降排序,所謂的默認(rèn)排序其實就是很多商城里面的綜合排序,由后臺根據(jù)指定算法進行計算。這里主要實現(xiàn)以下邏輯控制:
點擊Price會改變后面的箭頭,默認(rèn)箭頭向下,點擊以后箭頭向上,并向后臺請求產(chǎn)品列表時帶上sort=priceDown參數(shù),請求回來的產(chǎn)品列表按價格降序排列,并且點擊非排序按鈕請求時也會帶上sort=priceDown參數(shù)。
再點擊一次箭頭向下,并向后臺請求產(chǎn)品列表時帶上sort=priceUp參數(shù),請求回來的產(chǎn)品列表按價格升序排列,并且點擊非排序按鈕請求時也會帶上sort=priceUp參數(shù)。
不管何時,點擊default,price箭頭變?yōu)橄蛳?,并向后臺請求產(chǎn)品列表時帶上sort=default參數(shù),請求回來的產(chǎn)品列表按默認(rèn)順序排列,并且點擊非排序按鈕請求時也會帶上sort=default參數(shù)。
代碼如下:

<template>
  <div>
    <PageHeader></PageHeader>
    <PageBread>
      <span>Goods</span>
    </PageBread>
    <div class="accessory-result-page accessory-page">
      <div class="container">
        <div class="filter-nav">
          <span class="sortby">Sort by:</span>
          <a href="javascript:void(0)" class="default" :class="{'cur': sortChecked === 'default'}" @click="checkSort('default')">Default</a>
          <a href="javascript:void(0)" class="price" :class="{'cur': sortChecked === 'priceUp' ||  sortChecked === 'priceDown'}" @click="checkSort(isPriceUp?'priceDown':'priceUp')">Price
            <span v-if="isPriceArrowUp">↑</span>
            <span v-else>↓</span>
            <!--<svg class="icon icon-arrow-short">-->
              <!--<symbol id="icon-arrow-short" viewBox="0 0 25 32">-->
                <!--<title>arrow-short</title>-->
                <!--<path class="path1" d="M24.487 18.922l-1.948-1.948-8.904 8.904v-25.878h-2.783v25.878l-8.904-8.904-1.948 1.948 12.243 12.243z"></path>-->
              <!--</symbol>-->
              <!--<use xlink:href="#icon-arrow-short"></use>-->
            <!--</svg>-->
          </a>
          <a href="javascript:void(0)" class="filterby stopPop" @click="showFilterBy">Filter by</a>
        </div>
        <div class="accessory-result">
          <!-- filter -->
          <div class="filter stopPop" id="filter" :class="{'filterby-show': isShowFilterBy}">
            <dl class="filter-price">
              <dt>Price:</dt>
              <dd><a href="javascript:void(0)" :class="{'cur': priceChecked === 'all'}" @click="checkPriceFilter('all')">All</a></dd>
              <dd v-for="(item, index) in priceFilterList" :key="index">
                <a v-if="item.endPrice" href="javascript:void(0)" :class="{'cur': priceChecked === index}" @click="checkPriceFilter(index)">{{item.startPrice}} - {{item.endPrice}}</a>
                <a v-else href="javascript:void(0)" :class="{'cur': priceChecked === index}" @click="checkPriceFilter(index)">> {{item.startPrice}}</a>
              </dd>
            </dl>
          </div>

          <!-- search result accessories list -->
          <div class="accessory-list-wrap">
            <div class="accessory-list col-4">
              <ul>
                <li v-for="item in prdList" :key="item.productId">
                  <div class="pic">
                    <a href="#"><img v-lazy="`../../../static/${item.productImage}`" alt=""></a>
                  </div>
                  <div class="main">
                    <div class="name">{{item.productName}}</div>
                    <div class="price">{{item.salePrice}}</div>
                    <div class="btn-area">
                      <a href="javascript:;" class="btn btn--m">加入購物車</a>
                    </div>
                  </div>
                </li>
              </ul>
            </div>
          </div>
        </div>
      </div>
    </div>
    <div class="md-overlay" v-show="isShowOverLay" @click="closeFilterBy"></div>
    <PageFooter></PageFooter>
  </div>
</template>

<script>
import PageHeader from '../../components/PageHeader'
import PageBread from '../../components/PageBread'
import PageFooter from '../../components/PageFooter'
import axios from 'axios'

let queryPrdObj = {}

export default {
  data () {
    return {
      prdList: [], // 產(chǎn)品列表
      // 價格過濾列表
      priceFilterList: [
        {
          startPrice: 0,
          endPrice: 100
        },
        {
          startPrice: 100,
          endPrice: 500
        },
        {
          startPrice: 500,
          endPrice: 2000
        },
        {
          startPrice: 2000
        }
      ],
      priceChecked: 'all', // 選中的價格過濾列表項
      filterPrice: null, // 選中的價格過濾列表對象
      isShowFilterBy: false, // 是否展示過濾列表彈窗
      isShowOverLay: false, // 是否展示遮罩層
      sortChecked: 'default',
      isPriceUp: true
    }
  },
  computed: {
    isPriceArrowUp () {
      return !this.isPriceUp
    }
  },
  components: {
    PageHeader,
    PageBread,
    PageFooter
  },
  created () {
    this.getPrdList()
  },
  methods: {
    // 請求接口獲取產(chǎn)品列表數(shù)據(jù)
    getPrdList () {
      queryPrdObj = Object.assign(queryPrdObj, this.filterPrice, {sort: this.sortChecked})
      axios.get('mock/goods', {params: queryPrdObj}).then((res) => {
        console.log('res', res)
        let data = (res && res.data) || {}
        if (data.code === '000') {
          this.prdList = data.result || []
          console.log('prdList', this.prdList)
        } else {
          alert(`err:${data.msg || '系統(tǒng)錯誤'}`)
        }
      })
    },
    // 選取價格過濾列表項
    checkPriceFilter (index) {
      this.priceChecked = index
      this.filterPrice = index === 'all' ? null : this.priceFilterList[index]
      this.getPrdList()
      this.closeFilterBy()
    },
    // 展示過濾列表彈窗
    showFilterBy () {
      this.isShowFilterBy = true
      this.isShowOverLay = true
    },
    // 關(guān)閉過濾列表彈窗
    closeFilterBy () {
      this.isShowFilterBy = false
      this.isShowOverLay = false
    },
    checkSort (val) {
      this.sortChecked = val
      if (val === 'priceUp' || val === 'priceDown') {
        this.isPriceUp = !this.isPriceUp
      } else {
        this.isPriceUp = true
      }
      this.getPrdList()
    }
  }
}
</script>

總結(jié)

本篇主要是一些前端業(yè)務(wù)邏輯的編碼,這里的實現(xiàn)其實存在一個小bug,是關(guān)于篩選價格方面的,后面在在線商城項目12-商品列表頁價格篩選實現(xiàn)一文中我做了修改。另外,那個向上箭頭的svg重構(gòu)沒有提供,直接畫svg我還也沒有研究過,所以用向上和向下箭頭代替了。后期我們可能會引入iconfont。下面我們提交代碼:

git status
git diff
git commit -am 'goodslist logic done'
git push
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,632評論 19 139
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,422評論 4 61
  • 今天凌晨一點半,我從睡夢中猛然驚醒,下意識的看了下表,完了,晚了! 昨天,6月17號,是我參加“好報”的寫作訓(xùn)練營...
    野蠻實踐閱讀 383評論 2 1
  • 不知道大家是否和我有過相似的經(jīng)歷,在同齡人面前談天說地,在長輩面前默不作聲,還要被七大姑八大姨說內(nèi)向,太沉悶…… ...
    牛角包妹妹閱讀 848評論 0 0
  • 第一次發(fā)看看效果
    賀海罡媽媽閱讀 281評論 0 0

友情鏈接更多精彩內(nèi)容