weex下實現列表項左滑菜單

最近項目中遇到的需求,由於初次接觸weex,故做以記錄,如有任何不明或錯誤,歡迎指出。

這裏寫圖片描述

在收貨地址的列表的某一項上左滑就顯示出該項的編輯和刪除菜單。

實現功能

  1. 左滑每一項顯示該項的菜單
  2. 在列表中右滑隱藏顯示的菜單
  3. 每次只能顯示一項的菜單,打開第二項菜單的同時關閉第一項

實現過程

思路是:將每一項的長度設置爲頁面寬度+300px(1334*750的設計圖),即每一項的寬度爲1050px。

頁面結構如下:

 <scroller class="address__container">
            <div class="address__item" ref="menuItem"  v-for="(item,index) in list" @swipe="slideMenu($event,index)" :key="index" @click="chooseItem(item.id)">
                <div class="address__item__info">
                    <div class="addredd__item__info__top">
                        <text class="fs14 mr4">收貨人</text>
                        <text class="fs14 mr4">XXXXXXXX</text>
                        <text class="fs16" style="height:50px;line-height:35px;">131 1313 1313</text>
                    </div>
                    <div class="address__item__info__bottom">
                        <text class="fs12">某某省某某市某某區</text>
                    </div>
                </div>
                <text class="address__item__control">編輯</text>
                <text class="address__item__control address__item__control-delete">刪除</text>
            </div>
        </scroller>

關於scroller組件點擊這裏可以看到官方的文檔

每一項的CSS如下:

.address__item {
  width: 1050px;
  height: 170px;
  border-bottom-width: 1px;
  border-bottom-color: @border;
  flex-direction: row;
  flex-wrap: nowrap;
}

現在由於由於頁面寬度只有750px,所以有300px被隱藏在右邊了,這300px就是我們兩個按鈕的寬度。

接下來實現左滑顯示菜單:

由於當時正在閱讀WEEX的官方文檔,正好看到了注意: 現在Weex只支持在JavaScript中使用動畫, CSS 動畫是和JavaScript 動畫是不一樣的。我們即將支持在CSS中使用動畫。、所以我選擇了使用weex的內置模塊animation來實現動畫效果。

關於animation模塊點擊這裏查看。

<div class="address__item" ref="menuItem"  v-for="(item,index) in list" @swipe="slideMenu($event,index)" :key="index" @click="chooseItem(item.id)">

這裏調用的weex封裝好的手勢事件來觸發我們的Slide方法。

direction:僅在 swipe 手勢中存在,返回滑動方向,返回值可能爲 up, left, bottom, right。*

我使用了direction屬性來幫助我判斷滑動方向,在項目中的體驗還可以,準確度較高。

  • 左滑事件:
    @params ele 要執行動畫的元素
    leftSlide(ele) {
      animation.transition(
        ele,
        {
          styles: {
            transform: "translateX(-300px)" // 向左移動300px以顯示菜單
          },
          duration: 150, //動畫持續事件
          timingFunction: "linear",// 動畫速度曲線
          needLayout: false, // 節點動畫執行時是否產生布局動畫即LayoutAnimation
          delay: 0 // 延遲執行動畫
        }
      );
    },

右滑事件跟左滑事件相同只是translateX的值爲0表示回到原位。

接下來寫一個用來判斷要滑動的元素以及要滑動方向的方法

 slideMenu(e, index) {
      let listItems = this.$refs.menuItem;
      let ele = this.$refs.menuItem[index];
      let direction = e.direction;
      if (direction == "left") {
        this.leftSlide(ele);
      }else if(direction == "right"){
        this.rightSlide(ele);
      }
    },

調用slideMenu方法的時候傳遞了eventindex,index event中的direction來判斷滑動方向,然後調用不同的方法。

現在基本實現了基礎的左右滑動事件,但是出現了這樣的情況:

所有的菜單都可以同時滑出來

所有的菜單同時展開,看起來很奇怪。

思路大概是這樣,打開左滑菜單之前,檢查有沒有其他的菜單處於打開狀態,如果有,關閉該菜單然後再打開當前的菜單。

起初使用this.$refs.menuItem[index].state = 0 || 1 來標識打開狀態

然後在執行leftSlide前的時候調用一個方法去遍歷所有的menuItem如果state等於1就在該元素上執行右滑操作

後來在實際操作的時候遇到了一些奇怪的問題。於是變換了另一種思路,最終版如下:

將右滑操作改爲將所有項translateX(0)。

在執行leftSlide的之前,執行一次rightSlide()方法。

最終的rightSlide():

rightSlide(){
      let listItems = this.$refs.menuItem;
      for (let i = 0; i < listItems.length; i++) {
        animation.transition(
          listItems[i],
          {
            styles: {
              transform: "translateX(0px)"
            },
            duration: 150, //ms
            timingFunction: "linear",
            needLayout: false,
            delay: 0 //ms
          }
        );
      }
      return false;
    }

最終的leftSlide()

    leftSlide(ele) {
      this.rightSlide();
      animation.transition(
        ele,
        {
          styles: {
            transform: "translateX(-300px)"
          },
          duration: 150, //ms
          timingFunction: "linear",
          needLayout: false,
          delay: 0 //ms
        }
      );
    },

最終實現的效果如下

最終滑動效果

對rightSlide()方法對性能的影響尚未做研究,有待商榷。

如有任何錯誤或不妥之處,歡迎指出。

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