溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

vue如何實現商城中商品“篩選器”功能

發布時間:2020-07-01 11:04:10 來源:億速云 閱讀:418 作者:清晨 欄目:開發技術

小編給大家分享一下vue如何實現商城中商品“篩選器”功能,希望大家閱讀完這篇文章后大所收獲,下面讓我們一起去探討方法吧!

vue商城中商品“篩選器”功能的實現

   在使用vue搭建商城項目的時候,要實現一個商品篩選器的功能,在完成之后,再一次被vue的數據驅動的強大感到震撼!

       首先,我們來看一下具體的需求吧。你可以先看下面的這兩張圖,然后再看文字描述,可能會更容易理解。

vue如何實現商城中商品“篩選器”功能

沒有觸發時的狀態

vue如何實現商城中商品“篩選器”功能

觸發后的狀態

       我們需求有下面幾點:
       1、默認情況下,只顯示一級菜單,二級菜單不顯
       2、存在二級菜單的情況下,在二級菜單沒有顯示的情況下,點擊一級菜單,一級菜單的樣式發生改變,二級菜單不顯示
       3、存在二級菜單的情況下,一級菜單已經點擊過之后,再點擊一級菜單,會顯示二級菜單
       我們舉例子說明一下,當前的一級菜單有默認、有貨優先、直營優先,只有默認是含有二級菜單的,比如現在焦點在有貨優先上面,那么我們點擊默認的時候,不會彈出默認下面的二級菜單,只會改變一級菜單默認的樣式(字體和三角形的顏色),當再次點擊一級菜單默認的時候,其下面的二級菜單就顯示出來了。
       需求分析完成后,我們開始編寫代碼吧。

一、創建篩選器數據結構

       跟以前的開發方式不同,我們首先要創建數據結構,而不是編寫模版代碼。

1、設置篩選器數據結構

// 數據源
optionsDatas: [
  {
   id: '1',
   name: '默認',
   subs: [
    {
     id: '1',
     name: '默認',
    },
    {
      id: '1-2',
      name: '價格由高到低',
    },
    {
      id: '1-3',
      name: '銷量由高到低',
    },
    ]
  },
  {
   id: '2',
   name: '有貨優先',
   subs: []
  },
  {
   id: '3',
   name: '直營優先',
   subs: []
  }
]

       這個數據結構設計得是非常出彩的,此處您可能還看不到,在下面具體的應用中你就能感覺到它的優美呢。

2、設置二級菜單(選中項subs)的數據結構

// 選中的篩選項
selectOption: {},
// 是否展開子篩選項
sShowSubContent: false
  當然,我們要在created鉤子函數中對selecOption進行賦值操作,保證其具有初始值。

created: function () {
  // 設置初始選中項
  this.selectOption = this.optionsDatas[0];
}

二、設置模版代碼

       下面是完整模版代碼,內容相對比較多,我們按照功能逐塊進行講解吧。

<div class="goods-options z-index-2">
  <ul class="goods-options-list">
   <li class="goods-options-item" v-for="(item, index) in optionsDatas" :key="index">
    <a class="goods-options-item-content" @click="onOptionsItemClick(item, index)">
     <span class="goods-options-item-content-name" :class="{'goods-options-item-content-name-active' : selectOption.id === item.id}">{{item.name}}</span>
     <span class="goods-options-item-content-caret caret" v-if="item.subs.length > 0"
     :class="[isShowSubContent && selectOption.id === item.id &#63; 'goods-options-item-content-caret-open' : 'goods-options-item-content-caret-close']" 
     ></span>
    </a>
   </li>
  </ul>
  <transition name="fold-height">
   <div class="options-sub-content z-index-2" v-show="isShowSubContent">
    <ul class="options-sub-content-list">
     <li class="options-sub-content-list-item" v-for="(item, index) in selectOption.subs" :key="index" @click="onSubOptionsItemClick(item, index)">
      <a class="options-sub-content-list-item-content">
       <span class="options-sub-content-list-item-content-name" :class="{'options-sub-content-list-item-content-name-active' : selectOption.id === item.id}">{{item.name}}</span>
       <img class="options-sub-content-list-item-content-select" v-show="selectOption.id === item.id" src="@img/options-select.svg"  srcset="">
      </a>
     </li>
    </ul>
   </div>
  </transition>

  <div class="cover" v-show="isShowSubContent" @click="isShowSubContent = false"></div>
</div>
1、渲染一級菜單
  <ul class="goods-options-list">
   <li class="goods-options-item" v-for="(item, index) in optionsDatas" :key="index">
    <a class="goods-options-item-content" @click="onOptionsItemClick(item, index)">
     <span class="goods-options-item-content-name" :class="{'goods-options-item-content-name-active' : selectOption.id === item.id}">{{item.name}}</span>
     <span class="goods-options-item-content-caret caret" v-if="item.subs.length > 0"
     :class="[isShowSubContent && selectOption.id === item.id &#63; 'goods-options-item-content-caret-open' : 'goods-options-item-content-caret-close']" 
     ></span>
    </a>
   </li>
  </ul>

1.1、一級菜單的樣式變化

       一級菜單的文字顏色的變化需要滿足下面的規則,也就是selectOption.id === item.id。也就是說在當選中是一級菜單是默認的時候,我們就要其文字顏色改編成紅色。

:class="{'goods-options-item-content-name-active' : selectOption.id === item.id}"

       相應地,三角形的顏色和箭頭的朝向也需要進行更改。更改的邏輯如下。當然,如果一級菜單沒有對應的二級菜單時,三角形就不應該顯示。

:class="[isShowSubContent && selectOption.id === item.id &#63; 'goods-options-item-content-caret-open' : 'goods-options-item-content-caret-close']"
v-if="item.subs.length > 0"

1.2、一級菜單的點擊事件onOptionsItemClick(item, index)實現的主要功能是改變一次菜單的樣式和二級菜單的顯示/隱藏。具體的功能如下分析所示:
       1、如果子選項視圖處于展開狀態,則關閉掉子選項視圖
       2、展示子選項視圖
              2.1、選中項包含子選項
              2.2、當前篩選項處于選中狀態
       3、設置選中項為用戶點擊的選項

onOptionsItemClick: function (item, index) {
  // 如果子選項視圖處于展開狀態,則關閉掉子選項視圖
  if (this.isShowSubContent) {
   this.isShowSubContent = false;
   return;
  }
  // 1、選中項包含子選項
  // 2、當前篩選項處于選中狀態
  // 展示子選項視圖
  if (item.subs.length > 0 && this.selectOption.id === item.id) {
   this.isShowSubContent = true;
  } 
   // 設置選中項為用戶點擊的選項
  this.selectOption = item;
}

2、渲染二級菜單

<transition name="fold-height">
 <div class="options-sub-content z-index-2" v-show="isShowSubContent">
   <ul class="options-sub-content-list">
    <li class="options-sub-content-list-item" v-for="(item, index) in selectOption.subs" :key="index" @click="onSubOptionsItemClick(item, index)">
     <a class="options-sub-content-list-item-content">
      <span class="options-sub-content-list-item-content-name" :class="{'options-sub-content-list-item-content-name-active' : selectOption.id === item.id}">{{item.name}}</span>
      <img class="options-sub-content-list-item-content-select" v-show="selectOption.id === item.id" src="@img/options-select.svg"  srcset="">
     </a>
    </li>
   </ul>
  </div>
</transition>

2.1、二級菜單樣式的變化
       二級菜單的樣式變化需要滿足下面的規則。這個規則基本上跟一級菜單的一致。

:class="{'options-sub-content-list-item-content-name-active' : selectOption.id === item.id}"

       對于右側的對勾,需要符合下面的邏輯。

v-show="selectOption.id === item.id"

2.2、二級菜單的點擊事件onSubOptionsItemClick(item, index),這個事件需要實現功能如下:
       1、設置選中項為用戶點擊的選項
       2、將選中項置頂
       3、關閉子選項視圖

onSubOptionsItemClick: function (subItem, index) { 
  // 遍歷所有的可選項,將選中項置頂
  this.optionsDatas.forEach(options => {
   options.subs.forEach (subOptions => {
    if (subOptions.id === subItem.id) {
     options.id = subOptions.id;
     options.name = subOptions.name;
     }
   })
  });
  // 關閉子選項視圖
  this.isShowSubContent = false;
}

2.3、二級菜單動畫的實現
       二級菜單動畫的實現,我們采用了vue的過度動畫。其使用到的css動畫如下:

/**
 子選項內容區展開動畫,當 v-if=“true” 的時候調用
 當子選項部分展開時,初始狀態max-height為0,結束狀態max-height為180
*/
 .fold-height-enter-active {
  animation-duration: .3s;
  animation-name: fold-height-open;
 }

 @keyframes fold-height-open {
   0% {
    max-height: 0;
   }
   100% {
    max-height: px2rem(180);
   }
 }
/**
 子選項內容區關閉動畫,當 v-if=false 的時候調用
 當子選項部分關閉時,初始狀態max-height為180,結束狀態max-height為0
*/
  .fold-height-leave-active {
   animation-duration: .3s;
   animation-name: fold-height-close;
  }

  @keyframes fold-height-close {
   0% {
    max-height: px2rem(180);
   }
   100% {
    max-height: 0;
   }
  }

2、遮罩的顯示/隱藏

       最后就剩下一個遮罩的樣式和邏輯了,這個比較簡單,其邏輯如下:此處不在進行多余的解釋。

<div class="cover" v-show="isShowSubContent" @click="isShowSubContent = false">
</div>

       至此,我們所有的邏輯分析和代碼實現都已完成。設計的最巧妙的就是這個數據結構,完全滿足了我們業務需求。在下面是完整的代碼,希望對您有用。

<template>
 <div class="goods-options z-index-2">
  <ul class="goods-options-list">
   <li class="goods-options-item" v-for="(item, index) in optionsDatas" :key="index">
    <a class="goods-options-item-content" @click="onOptionsItemClick(item, index)">
     <span class="goods-options-item-content-name" :class="{'goods-options-item-content-name-active' : selectOption.id === item.id}">{{item.name}}</span>
     <span class="goods-options-item-content-caret caret" v-if="item.subs.length > 0"
     :class="[isShowSubContent && selectOption.id === item.id &#63; 'goods-options-item-content-caret-open' : 'goods-options-item-content-caret-close']" 
     ></span>
    </a>
   </li>
  </ul>
  <transition name="fold-height">
   <div class="options-sub-content z-index-2" v-show="isShowSubContent">
    <ul class="options-sub-content-list">
     <li class="options-sub-content-list-item" v-for="(item, index) in selectOption.subs" :key="index" @click="onSubOptionsItemClick(item, index)">
      <a class="options-sub-content-list-item-content">
       <span class="options-sub-content-list-item-content-name" :class="{'options-sub-content-list-item-content-name-active' : selectOption.id === item.id}">{{item.name}}</span>
       <img class="options-sub-content-list-item-content-select" v-show="selectOption.id === item.id" src="@img/options-select.svg"  srcset="">
      </a>
     </li>
    </ul>
   </div>
  </transition>

  <div class="cover" v-show="isShowSubContent" @click="isShowSubContent = false"></div>
 </div>
</template>


<script>
export default {
 data: function () {
  return {
   // 數據源
   optionsDatas: [
    {
     id: '1',
     name: '默認',
     subs: [
      {
       id: '1',
       name: '默認',
      },
      {
       id: '1-2',
       name: '價格由高到低',
      },
      {
       id: '1-3',
       name: '銷量由高到低',
      },
     ]
    },
    {
     id: '2',
     name: '有貨優先',
     subs: []
    },{
     id: '3',
     name: '直營優先',
     subs: []
    }
   ],
   // 選中的篩選項
   selectOption: {},
   // 是否展開子篩選項
   isShowSubContent: false
  }
 },
 created: function () {
  // 設置初始選中項
  this.selectOption = this.optionsDatas[0];
 },
 methods: {
  /**
   * 1、如果子選項視圖處于展開狀態,則關閉掉子選項視圖
   * 2、展示子選項視圖
   *  1、選中項包含子選項
   *  2、當前篩選項處于選中狀態
   * 3、設置選中項為用戶點擊的選項
   */
  onOptionsItemClick: function (item, index) {
   // 如果子選項視圖處于展開狀態,則關閉掉子選項視圖
   if (this.isShowSubContent) {
    this.isShowSubContent = false;
    return;
   }
   // 1、選中項包含子選項
   // 2、當前篩選項處于選中狀態
   // 展示子選項視圖
   if (item.subs.length > 0 && this.selectOption.id === item.id) {
    this.isShowSubContent = true;
   } 
   // 設置選中項為用戶點擊的選項
   this.selectOption = item;

   
  },
  /**
   * 1、設置選中項為用戶點擊的選項
   * 2、將選中項置頂
   * 3、關閉子選項視圖
   */
  onSubOptionsItemClick: function (subItem, index) {
   // 設置選中項為用戶點擊的選項
   // this.selectOption = subItem;
   
   // 遍歷所有的可選項,將選中項置頂
   this.optionsDatas.forEach(options => {
    options.subs.forEach (subOptions => {
     if (subOptions.id === subItem.id) {
      options.id = subOptions.id;
      options.name = subOptions.name;
     }
    })
   });

   // 關閉子選項視圖
   this.isShowSubContent = false;
  },

 },
 watch: {
  /**
   * 當選擇項發生變化的時候,需要通知父組件
   */
  selectOption: function (newValue, oldValue) {
   this.$emit('optionsChange', newValue);
  }
 }
}
</script>


<style lang="scss" scoped>
@import '@css/style.scss';
 .goods-options {
  width: 100%;
  border-bottom: 1px solid $lineColor;
  &-list {
   display: flex;
   width: 100%;
   height: $goodsOptionsHeight;
   background-color: white;
   .goods-options-item {
    flex-grow: 1;

    &-content {
     height: 100%; 
     display: flex;
     justify-content: center;
     align-items: center;

     &-name {
      font-size: $infoSize;
      margin-right: $marginSize;

      &-active{
       color: $mainColor;
      }
     }

     // 子選項展開時,三角形的動畫
     &-caret {
      &-open {
       transform:rotate(-180deg);
       transition: all .3s;
      }

      &-close {
       transform:rotate(0deg);
       transition: all .3s;
      }
     }

    }
   }

  }

  // 子選項內容區
  .options-sub-content {
   // 脫離標準文檔流
   position: absolute;
   width: 100%;
   max-height: px2rem(180);
   overflow: hidden;
   overflow-y: auto;
   background-color: white;
   &-list {

    &-item {

     &-content {
      display: flex;
      align-items: center;
      border-top: 1px solid $lineColor;
      padding: $marginSize;
      height: px2rem(44);
      box-sizing: border-box;
      &-name {
       font-size: $infoSize;
       display: inline-block;
       flex-grow: 1;

       &-active{
        color: $mainColor;
       }
      }

      &-select {
       width: px2rem(18);
       height: px2rem(18);
      }

     }

    }
   }
  }

  /**
   子選項內容區展開動畫,當 v-if=“true” 的時候調用
   當子選項部分展開時,初始狀態max-height為0,結束狀態max-height為180
  */
  .fold-height-enter-active {
   animation-duration: .3s;
   animation-name: fold-height-open;
  }

  @keyframes fold-height-open {
   0% {
    max-height: 0;
   }
   100% {
    max-height: px2rem(180);
   }
  }

  /**
   子選項內容區關閉動畫,當 v-if=false 的時候調用
   當子選項部分關閉時,初始狀態max-height為180,結束狀態max-height為0
  */
  .fold-height-leave-active {
   animation-duration: .3s;
   animation-name: fold-height-close;
  }

  @keyframes fold-height-close {
   0% {
    max-height: px2rem(180);
   }
   100% {
    max-height: 0;
   }
  }
 }
</style>

看完了這篇文章,相信你對vue如何實現商城中商品“篩選器”功能有了一定的了解,想了解更多相關知識,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女