Vueは左右メニュー連動実現(更新)

7433 ワード

title:Vue実現左右メニュー連動実現date:2018-08-11 16:31:34 tags:
  • Vue
  • 左右連動top:100 copyright:true
  • 知っている
    個人ブログ
    Github
    ソース転送ゲート:Rain 120/vue-study
    掘金コメントのニーズに応じて、データインタフェースを更新し、いくつかの問題を修正しました.
    以前、テイクアウトソフトでこの左右連動の効果を見て面白かったので、Vueを使って実現してみましたが、この連動を単独のコンポーネントに引き離して、くだらないことは言わないで、まず効果図を1枚ください.
    このコンポーネントは2つの部分に分けられ、1、左メニューです.2、右メニュー.
    ダイナミックデータ構造
    menus: [
      {
        name: '  1',
        data: [
          {
            name: '1.1'
          },
          {
            name: '1.2'
          },
          {
            name: '1.3'
          },
          {
            name: '1.4'
          },
          {
            name: '1.5'
          },
          {
            name: '1.6'
          }
        ]
      }
    ]
    

    Dataデータは、ユーザがカスタマイズしてコンテンツを追加し、DOMをレンダリングする
    左メニューのDOM構造
    "left-menu"
      :data="menus"
      ref="leftMenu">
      
    "left-menu-container">
    • "left-item" ref="leftItem" :class="{'current': currentIndex === index}" @click="selectLeft(index, $event)" v-for="(menu, index) in menus" :key="index">

      "text">{{menu.name}}


    右メニューのDOM構造
    "right-menu"
      :data="menus" 
      ref="rightMenu"
      @scroll="scrollHeight"
      :listenScroll="true"
      :probeType="3">
      
    "right-menu-container">
    • "right-item" ref="rightItem" v-for="(menu, i) in menus" :key="i">
      "title">{{menu.name}}
      • "(item, j) in menu.data" :key="j">
        "data-wrapper">
        "data">{{item.name}}

    ここはdemoを作るためなので、データ上は単なる捏造です.
    もちろんこれはサブアセンブリなので、親アセンブリを介してpropsを渡すので、propsを定義します.
    props: {
        menus: {
          required: true,
          type: Array,
          default () {
            return []
          }
        }
      },
    

    このビジネスシーンでは、右のメニューのスクロールの高さに基づいて左のメニューの位置を計算することを実現しています.もちろん、左のメニューもクリックすることで右のメニューがどれだけスクロールする必要があるかを決定することができます.では、どのようにして容器のスクロールの距離を得るのでしょうか.以前はbetter-scrollを使用していましたが、ドキュメントを読むことでscrollのイベントがあることがわかり、このイベントを傍受することでスクロールしたposを取得することができます.
    if (this.listenScroll) {
      let me = this
      this.scroll.on('scroll', (pos) => {
        me.$emit('scroll', pos)
      })
    }
    

    右のメニューのscrollコンポーネントでscrollイベントを傍受しました
    @scroll="scrollHeight"
    

    method
    scrollHeight (pos) {
      console.log(pos);
      this.scrollY = Math.abs(Math.round(pos.y))
    },
    

    傍受されたposを出してみましょう
    コンソールから現在スクロールされているpos情報が表示されているのを見ることができます.移動端の開発では、座標軸は私たちの数学の座標軸とは逆なので、スライド時のy軸の値は負数です.liの高さを手に入れることができます
     _calculateHeight() {
      let lis = this.$refs.rightItem;
      let height = 0
      this.rightHeight.push(height)
      Array.prototype.slice.call(lis).forEach(li => {
        height += li.clientHeight
        this.rightHeight.push(height)
      })
    console.log(this.rightHeight)
    }
    
    DOMというcreatedの後にこの計算高さの関数を呼び出します
     _calculateHeight() {
      let lis = this.$refs.rightItem;
      let height = 0
      this.rightHeight.push(height)
      Array.prototype.slice.call(lis).forEach(li => {
        height += li.clientHeight
        this.rightHeight.push(height)
      })
      console.log(this.rightHeight)
    }
    

    ユーザーがスクロールしている場合、現在のスクロール距離の実際の区間を計算し、hookを取得する必要があります.
    computed: {
      currentIndex () {
        const { scrollY, rightHeight } = this
        const index = rightHeight.findIndex((height, index) => {
          return scrollY >= rightHeight[index] && scrollY < rightHeight[index + 1]
        })
        return index > 0 ? index : 0
      }
    }
    

    従って、現在左メニューindexであるべきメニュー項目index = 1以上が左メニューである右メニューのスライド連動による実現であり、ユーザも左メニューをクリックすることにより右メニューの連動を実現することができ、この場合、メニュー項目にactiveを加える
    @click="selectLeft(index, $event)"
    

    ここにclick を付けるのは、オリジナルクリックイベントかbetter-scroll配布イベントかを区別するためです
    selectLeft (index, event) {
      if (!event._constructed) {
        return
      }
      let rightItem = this.$refs.rightItem
      let el = rightItem[index]
      this.$refs.rightMenu.scrollToElement(el, 300)
    },
    

    使用
    "menus">
    

    ここで私たちは基本的にこれらのニーズを達成しました