最近項目中遇到的需求,由於初次接觸weex,故做以記錄,如有任何不明或錯誤,歡迎指出。
在收貨地址的列表的某一項上左滑就顯示出該項的編輯和刪除菜單。
實現功能
- 左滑每一項顯示該項的菜單
- 在列表中右滑隱藏顯示的菜單
- 每次只能顯示一項的菜單,打開第二項菜單的同時關閉第一項
實現過程
思路是:將每一項的長度設置爲頁面寬度+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方法的時候傳遞了 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()方法對性能的影響尚未做研究,有待商榷。
如有任何錯誤或不妥之處,歡迎指出。