国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

vue移動端側滑面板組件

TNFE / 2176人閱讀

摘要:里邊涉及到的指令是自定義的指令,為了處理移動端的點擊操作,我還整理了一片陋文移動點擊長按滑動指令然后這個組件的源碼我放在了我出來的項目上謝謝各位品嘗,

以下這段都是廢話,請跳過

公司移動端開發平臺進行了大變革,前端架構由DCloud大生態轉換為VUE,所以移動端的UI組件庫從MUI改為使用MintUI,然后開始大刀闊斧的把MintUI組件改成MUI組件的樣子,然后發現少了幾個較為常用的,其中一個就是,嗯,側滑面板(也叫側滑菜單,也叫抽屜面板-andriod官方是這么翻譯的,很形象)。但是,它就是一個布局組件,具體里邊菜單什么的,那都是浮云(嗯,就是愛用幾年前的流行詞匯,而且很喜歡在網上沖浪和踩別人的空間)

以上這段都是廢話,感謝閱讀
需求

開發一個側滑面板(類似QQ、網易郵箱等app的)

可以在左邊,也可以在右邊

側滑面板內容隨意定制

側滑面板相對的就有主面板,那么衍生出不同的體位和姿勢

(1)主面板滑動,側滑面板不動
(2)側滑面板動,主面板不動
(3)它倆一塊動,一起--------

代碼風格盡量和MintUI的其他組件風格類似(這個挺重要的)

參考

mintUI組件中同樣??滑動操作的tabContainer,為了滿足需求5,我連函數名都抄了過來。

不說廢話,上代碼吧

The Waaaaaaaay 1. 設計組件結構

這個組件分為兩部分,一部分為側滑面板容器,另一部分為主面板容器,然后具體容器內部直接放了插槽,然后還需要一個主面板容器的遮罩,為了側滑面板打開的時候顯現出來。上代碼了

2. 配置設計

這塊加了一些我們公司的一些需求,可能各位哥哥姐姐門用不到里邊的一些props的設計,僅供參考

props: {
      // 側滑面板的寬度(單位px)
      "drawerWidth": {
        type: Number,
        default: 200
      },
      // 是否可用
      "enable": {
        type: Boolean,
        default: true
      },
      // 側滑菜單是否在右邊,默認為false,在左邊
      "isRight": {
        type: Boolean,
        default: false
      },
      // 側滑菜單滑動操作類型
      // ["fixDrawer"——固定側滑面板,主面板滑動]
      // ["fixContent"——固定主面板,側滑面板滑動]
      // ["noFixed"——一起滑動!]
      "swipeType": {
        type: String,
        default: "fixDrawer"
      },
      // 點擊出現側滑菜單的按鈕的id ( @TODO 這里如何處理異步渲染的問題 )
      "btnId": {
        type: String,
        default: ""
      },
      // 狀態位,側滑面板是否為打開狀態
      // (因為我們公司有這種一開始就把側滑菜單打開的shabee場景,所以這才會有這么個東西)
      //(如果這個不希望配置的話、可以放在data里邊)
      "isDrawerOpened": {
        type: Boolean,
        default: false
      },
      // 是否可滑動,如果不可滑動的話,就只能通過調用toogle方法打開側滑面板
      // 這個也是公司的一個使用場景,就是你甭滑,找個按鈕觸發一下側滑面板打開的方法才能打開
      //(如果這個不希望配置的話、也可以放在data里邊)
      "swipeable": {
        type: Boolean,
        default: true
      }
    }
2. 樣式設計

不得不承認,我的css寫的shit

對于整個的組件來說,它應該是默認充滿整個父容器的,而且這個組件,我覺得,一般都是用來放在最外層的一個布局組件,所以,默認充滿窗口就行了
所以組件的最外層來一個絕對布局,然后如下:

.mint-drawer-layout {
    position: absolute;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
    overflow-x: hidden;
}

然后側滑面板,只需要縱向充滿就可以了,寬度是配置

.mint-drawer-warp {
    position: absolute;
    top: 0;
    bottom: 0;
}

然后是主面板,沒說的

.mint-content-warp {
    position: relative;
    width: 100%;
    height: 100%;
}
4. 關鍵實現

終于來到了介紹到底該怎么實現的了

滑動處理三步走,start、drag、end

首先第一步上來就要設置一個記錄滑動操作的狀態變量——dragging,設置為false,方便屏蔽滑動時觸發的其他操作的執行

——開始的時候記錄開始滑動的位置
——滑動中,dragging狀態記錄為true,開始進行滑動位置和手指移動的聯動
——滑動結束,dragging狀態記錄為false,計算當前的滑動位置,判斷是劃開側滑面板還是關閉,并進行動畫處理

其中幾個細節小談一哈
(1)左右滑動操作觸發的判斷:我這邊是公司的規范,橫軸移動位移大于五,豎軸位移不大于橫軸的1.73倍就可以
(2)最后結束時判斷側滑面板的打開和關閉:是這樣的,我這邊取的是三分之一的側滑面板的寬度,也就是從打開到關閉,那么像關閉的方向滑動側滑面板寬度的三分之一就可以了,如果是關閉到打開,往打開的方向滑動三分之一就可以了
(3)左側和右側,還有三種不同的滑動方式:三種不同的滑動方式實際上就是控制到底哪個面板隨著手指動,具體的動作過程和面板的偏移量實際上是一樣的。左右兩側就更簡單了,直接是對稱的操作就可

滑動結束的操作,參考的tabcontainer,也挺巧妙的,各位請上眼~

      /**
       * 滑動結束的動畫
       */
      swipeLeaveTransition() {
        let g = this, currentMovingDoms = [];
        let {swipeType, drawerWidth} = g;

        switch (swipeType) {
          case "fixDrawer":
            currentMovingDoms.push(g.content);
            break;
          case "fixContent":
            currentMovingDoms.push(g.drawer);
            break;
          case "noFixed":
            currentMovingDoms.push(g.drawer);
            currentMovingDoms.push(g.content);
            break;
          default:
            break;
        }

        currentMovingDoms.forEach((val) => {
          val.classList.add("swipe-transition");
        });

        setTimeout(() => {
          if (g.isDO) {
            this.swipeMove(drawerWidth);
          } else {
            this.swipeMove(0);
            g.contentMask.style.opacity = 0;
            g.contentMask.style.display = "none";
          }

          g.isToggle = false;

          currentMovingDoms.forEach((val) => {
            once(val, "webkitTransitionEnd", _ => {
              val.classList.remove("swipe-transition");
              g.swiping = false;
            });
          });


        }, 0);
      },

      /**
       * 滑動操作
       * @param offset 滑動位置
       */
      swipeMove(offset) {
        let g = this;
        let {swipeType, isRight} = g;

        g.contentMask.style.display = "block";
        g.contentMask.style.opacity = Math.abs(offset) / g.drawerWidth * 0.4;

        switch (swipeType) {
          case "fixDrawer":
            g.content.style.webkitTransform = `translate3d(${(!isRight ? "" : "-") + offset}px, 0, 0)`;
            g.swiping = true;
            break;
          case "fixContent":
            g.drawer.style.webkitTransform = `translate3d(${(!isRight ? "" : "-") + offset}px, 0, 0)`;
            g.swiping = true;
            break;
          case "noFixed":
            g.content.style.webkitTransform = `translate3d(${(!isRight ? "" : "-") + offset}px, 0, 0)`;
            g.drawer.style.webkitTransform = `translate3d(${(!isRight ? "" : "-") + offset}px, 0, 0)`;
            g.swiping = true;
            break;
          default:
            break;
        }
      },
      
      // 開始滑動
      startDrag(evt) {
        let g = this;
        if (!g.enable || !g.swipeable) return false;

        evt = evt.changedTouches ? evt.changedTouches[0] : evt;

        g.start.x = evt.pageX;
        g.start.y = evt.pageY;
      },

      // 滑動中
      onDrag(evt) {
        let g = this, swiping;
        if (!g.enable || !g.swipeable) return false;

        g.dragging = true;

        const e = evt.changedTouches ? evt.changedTouches[0] : evt;
        const offsetTop = e.pageY - g.start.y;
        const offsetLeft = e.pageX - g.start.x;
        const y = Math.abs(offsetTop);
        const x = Math.abs(offsetLeft);

        swiping = !(x < 5 || (x >= 5 && y >= x * 1.73));
        if (!swiping) return;
        evt.preventDefault();

        let offset;

        if (g.isDO) {
          offset = g.isRight ? (g.drawerWidth - offsetLeft) : (g.drawerWidth - (-offsetLeft));
        } else {
          offset = g.isRight ? -offsetLeft : offsetLeft;
        }

        if (offset < 0 || offset > g.drawerWidth) {
          g.swiping = false;
          return;
        }
        g.offset = offset;
        g.swipeMove(offset);
      },

      // 結束滑動
      endDrag() {
        let g = this;

        if (!g.enable || g.isToggle || !g.dragging) {
          return false;
        }

        const tempWidth = g.drawerWidth / 3;

        if (g.isDO && g.offset < tempWidth * 2) {
          g.isDO = false;
        } else if (!g.isDO && g.offset > tempWidth) {
          g.isDO = true;
        }
        g.dragging = false;

        g.swipeLeaveTransition();
      }

好啦,到這應該就差不多了。。。
里邊涉及到的v-tap指令是自定義的指令,為了處理移動端的點擊操作,我還整理了一片陋文:https://segmentfault.com/a/11... (移動點擊長按滑動vue指令)

然后這個組件的源碼我放在了我fork出來的mintUI項目上
https://github.com/LylaYuKako...

謝謝各位品嘗,

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/94272.html

相關文章

  • 基于React的仿QQ音樂(移動

    摘要:學習成本很低,另外官方有比較完善的中文文檔。簡單本身是沒有錯誤,一個東西能以簡單的方式解決難道不好嗎關于這個中文文檔居然還有人噴那些喜歡用的是不是英文能力差,我就再報以呵呵一笑。本身擁有中文文檔就是一個優勢,結果還成了被噴的地方。 前言 由于這段時間工作上也是挺忙的,就沒有時間去寫這個項目,中間一直都是寫寫停停,進度也是非常慢的。正好前幾天都還比較空,就趕緊抓著空閑時間去寫這個項目,最...

    xiaodao 評論0 收藏0
  • 匠心打造Vue側滑菜單組件

    摘要:本文介紹一個簡單的類似的布局組件的實現,基于。介紹的內容已經制作成組件。即當不可以拖出抽屜時,應觸發默認事件,比如垂直方向的滾動等等。這種優化可以將一部分復雜的計算工作提前準備好,使頁面的反應更為快速靈敏。 本文介紹一個簡單的DrawerLayout(類似Android的DrawerLayout)布局組件的實現,基于Vue.js。介紹的內容已經制作成 vue-drawer-layout...

    sutaking 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<