Reference: juejin. Cn/post / 684490…

The effect

BetterScroll

/ / installation
npm install better-scroll --save
/ / import
import Bscroll from "better-scroll";
Copy the code

Rolling principle: You need a parent container of fixed height, and then roll on top of it.

// Set scrollH as the parent container height, for example:
this.scrollH= window.innerHeight - 150
Copy the code

The overall structure

The relevant data

data() {
  return {
      foodList: [].// Menu information
      scrollH:' '.// The height of the wheel window
      heightList: [].// Storage location
      scrollY:' '.// Roll distance
  };
},
Copy the code

Example -foodList data structure:

foodList:[
    {name:'vegetables'.foods: ['Baby vegetable'.'Cabbage'] {},name:'meat'.foods: ['pork'.'beef'] {},name:'fruit'.foods: ['apple'.'watermelon'] {},name:'sweet'.foods: ['tea'.'Waffle']},],Copy the code

The DOM

Left menu bar

<div ref="leftMenu">
  <ul>
    <li
      v-for="(item, index) in foodList"     
      :key="index"
      :class="{ active: currentIndex === index }"
      @click="selectLeft(index)"
    >
      {{ item.name }}
    </li>
  </ul>
</div>
Copy the code
  • ref="leftMenu"Gets the DOM of the left menu bar to create a scrolling window
  • @click="selectLeft(index)"Click the left menu to trigger, used to slide to the specified content
  • :class="{ active: currentIndex === index }"Changing styles dynamically

Interior bar on the right

<div ref="rigntMenu" :style="'height:' + scrollH + 'px'" style="overflow: hidden">
  <ul>
    <li v-for="(item, index) in foodList" 
        :key="index" 
        ref="rightItem">
      <span class="rightTitle">{{ item.name }}</span>
      <div
        v-for="(food, key) in item.foods"
        :key="key"
      >
		{{ food }}
      </div>
    </li>
  </ul>
</div>
Copy the code
  • ref="rigntMenu"Gets the DOM from the right pane to create a scroll window
  • ref="rightItem"Gets the DOM height of a category
  • :style="'height:' + scrollH + 'px'"Dynamic binding fixes the height of the container

Functions and Methods

Create scroll window

Use new Bscroll(corresponding to DOM,{related configuration}) to create a scroll window

scrollInit() {
    // Create the left menu bar scroll window
    this.leftMenu = new Bscroll(this.$refs.leftMenu, {
        click: true.// Allow clicking
    });
    
    // Create a scroll window for the right pane
    this.rigntMenu = new Bscroll(this.$refs.rigntMenu, {
        probeType: 3.// Trigger the Scroll event during rigntMenu scrolling
        click: true});// While scrolling on the right, listen for the scroll event to get the scroll distance, and store the scroll distance in scrollY
    // Scroll distance: the distance between the top of the container and the top of the content
    this.rigntMenu.on("scroll".(pos) = > {
        this.scrollY = Math.abs(Math.round(pos.y));
    });
},
Copy the code

Gets the right item location

getListHeight(){
    const lis=this.$refs.rightItem   // Get the DOM of each item
    this.heightList=[]	// Store the top position of each item
    let height=0  
    this.heightList.push(height)  // The top vertical position of the first term is 0
    lis.map(item= >{
        height+=item.clientHeight // The top position of the second item = the top position of the first item + the content height of the second item, and so on
        this.heightList.push(height)
    })
},
Copy the code

Right linkage left

computed: {
    currentIndex() {
        // Determine the left menu position according to the current scroll wheel sliding distance
        const index = this.heightList.findIndex((item, index) = > {
            return  (this.scrollY >= this.heightList[index] &&
                     this.scrollY < this.heightList[index + 1])});return index > 0 ? index : 0; }},Copy the code

Left linkage right

selectLeft(index) {
  let rightItem = this.$refs.rightItem; 
  let el = rightItem[index]; // Get the corresponding DOM according to the index
  this.rigntMenu.scrollToElement(el, 1000); // Scroll the right scroll window to the corresponding DOM
},
Copy the code

Initialize the

mounted() {
   this.scrollH= window.innerHeight - 150
    this.$nextTick(() = > {
        this.scrollInit()
        this.getListHeight()
    })
}
Copy the code

For dynamic data, the following can be written at the end of the function that fetched the data.

this.$nextTick(() = > {
    this.scrollInit()
    this.getListHeight()
})
Copy the code

  • Article demo source: github.com/sanhuamao1/…
  • Encapsulated into components: sanhuamao1.coding.net/public/demo…