Using better-scroll component in Vue to realize horizontal scrolling function

Using better-scroll component in Vue to realize horizontal scrolling function

About

Recently, in the process of learning Vue, I wrote a small project imitating the mobile version of Qunar.com, aiming to practice and consolidate basic knowledge. However, today I found that there is a component on the homepage of Qunar that has a poor user experience. That is, a horizontal list is implemented using the browser's native scrolling. The scrolling of the list is rather awkward and uncomfortable, so I decided to rewrite this component with better-scroll.

Introduction to better-scroll

Better-scroll is a scrolling component based on i-scroll written by Huang Yi (yes, my senior). Project address: https://github.com/ustbhuangyi/better-scroll

1. Implementation principle of scrolling

The scrolling principle of better-scroll is the same as the native scrolling principle of the browser. When the height of the child box is greater than the height of the parent box, vertical scrolling will occur:

Similarly, if the width of the child box is greater than the width of the parent box, then horizontal scrolling will occur (the fundamental principle).

2. Using better-scroll in Vue

The most important thing to note when using better-scroll in Vue is that you must wait until the page rendering is completed before executing the instantiation of BScroll, because better-scroll must get the size of the scrolling area and the size of the parent box to calculate whether it can scroll, so we must have a certain understanding of the life cycle of Vue.

Here is a small demo. Through this demo you will learn how to use better-scroll

<template>
  <div class="wrapper" ref="wrapper"> // The easiest way to get DOM elements in Vue is to use this.$refs
    <ul class="content">
      <li>...</li>
      <li>...</li>
      ...
    </ul>
  </div>
</template>
<script>
  import BScroll from 'better-scroll' //Import better-scroll
  export default {
    mounted() {
      this.$nextTick(() => { // Use this.$nextTick to ensure that the component has been rendered this.scroll = new Bscroll(this.$refs.wrapper, {}) // Instantiate BScroll and accept two parameters, the first one is the dom node of the parent box})
    }
  }
</script>

3. Implementing horizontal scrolling in Vue

1. Comparison of renderings

Use native scrolling:

Use better-scroll:

2. Code (see comments)

<template>
  <div class="recommand-wrap">
    <div class="title">
      <img class="title-img" src="https://imgs.qunarzz.com/piao/fusion/1711/16/bfbb9874e8f11402.png" alt="This week's hot list">
      <span class="title-hotrec">This week's hot list</span>
      <span class="title-allrec">All charts</span>
    </div>
    <div ref="wrapper"> /* This is the parent box*/
      <ul class="cont" ref="cont"> /* This is the child box, the scrolling area*/
        <li class="cont-item" v-for="item of recommendList" :key="item.id">
          <div class="cont-img">
            <img class="img" :src="item.url" :alt="item.text">
          </div>
          <div class="cont-dest">{{item.text}}</div>
          <div class="cont-price">
            <span class="price">¥{{item.price}}</span>
            <span>Start</span>
          </div>
        </li>
      </ul>
    </div>
  </div>
</template>

<script>
import BScroll from 'better-scroll'

export default {
  name: 'HomeRecommand',
  props: {
    recommendList: {
      type: Array,
      required: true
    }
  },
  components:

  },
  data () {
    return {

    }
  },
  methods: {
    verScroll () {
      let width = this.recommendList.length * 110 // Dynamically calculate the size of the scrolling area. As mentioned earlier, the reason for scrolling is that the width of the scrolling area is greater than the width of the parent box this.$refs.cont.style.width = width + 'px' // Modify the width of the scrolling area this.$nextTick(() => {
        if (!this.scroll) {
          this.scroll = new BScroll(this.$refs.wrapper, {
            startX: 0, // For more information about the configuration, please refer to the official documentation of better-scroll. I will not go into details here. click: true,
            scrollX: true,
            scrollY: false,
            eventPassthrough: 'vertical'
          })
        } else {
          this.scroll.refresh() //Call this method if the DOM structure changes}
      })
    }
  },
  mounted () {
    this.$nextTick(() => {
      let timer = setTimeout(() => { // Actually, I don't want to write this timer either, which is equivalent to nesting another layer of $nextTick, but it will fail if (timer) {
          clearTimeout(timer)
          this.verScroll()
        }
      }, 0)
    })
  }
}
</script>

<style lang="scss" scoped>
  .recommand-wrap {
    height: 0;
    padding-bottom: 50%;
    margin-top: .2rem;
    background: #fff;
    padding-left: .24rem;
    width: 100%;
    .title {
      position: relative;
      height: 40px;
      display: flex;
      padding: 12px 0;
      box-sizing: border-box;
      .title-img {
        width: 15px;
        height: 15px;
      }
      .title-hotrec {
        font-size: 16px;
        margin-left: 4px;
      }
      .title-allrec {
        position: absolute;
        padding-top: 2px;
        font-size: 13px;
        right: 20px;
        color: gray;
      }
    }
    .cont {
      list-style: none;
      // overflow-x: scroll;  
      white-space: nowrap;
      font-size: 12px;
      text-align: center;
      padding-right: .24rem;
      .cont-item {
        position: relative;
        display: inline-block;
        padding: .06rem 0 .2rem;
        width: 2rem;
        margin: 0.1rem;
        .cont-img {
          overflow: hidden;
          width: 2rem;
          height: 0;
          padding-bottom: 100%;
          .img {
            width: 100%;
          }
        }
        .cont-dest {
          margin: .1rem 0;
        }
        .cont-price {
          .price {
            color: #ff8300;
          }
        }
      }
    }
  }
</style>

Reference Links

Author: Huang Yi

Link: https://zhuanlan.zhihu.com/p/27407024

Summarize

This concludes this article about using better-scroll component in Vue to implement horizontal scrolling. For more relevant Vue better-scroll horizontal scrolling content, please search 123WORDPRESS.COM's previous articles or continue to browse the following related articles. I hope everyone will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • Vue implements horizontal scrolling of marquee style text
  • Vue uses better-scroll to achieve horizontal scrolling method example
  • Vue replaces the marquee tag to scroll horizontally when the text exceeds the width
  • The problem and solution of setInterval not being cleared when messages scroll horizontally in Vue
  • Vue.js+cube-ui (Scroll component) realizes a horizontal scrolling navigation bar similar to the headline effect
  • Vue sample code to achieve the effect of up and down scrolling of bulletin board text
  • Vue monitors scroll events to implement scroll monitoring
  • Vue.js practice: implementing dynamic anchor points by listening to scroll events
  • Sample code for Vue to achieve seamless scrolling effect of messages
  • Vue realizes horizontal screen scrolling announcement effect

<<:  Detailed tutorial on compiling and installing MySQL 5.7.24 on CentOS7

>>:  How to install nginx on win10

Recommend

Detailed explanation of Vue's ref attribute

Summarize This article ends here. I hope it can b...

Reasons why MySQL cancelled Query Cache

MySQL previously had a query cache, Query Cache. ...

Linux checkup, understand your Linux status (network IO, disk, CPU, memory)

Table of contents 1. Core commands 2. Common comm...

【HTML element】How to embed images

The img element allows us to embed images in HTML...

Detailed explanation of MySQL date string timestamp conversion

The conversion between time, string and timestamp...

Let's talk about parameters in MySQL

Preface: In some previous articles, we often see ...

CSS form validation function implementation code

Rendering principle In the form element, there is...

Why web page encoding uses utf-8 instead of gbk or gb2312?

If you have a choice, you should use UTF-8 In fac...

Best Practices for MySQL Upgrades

MySQL 5.7 adds many new features, such as: Online...

Web data storage: Cookie, UserData, SessionStorage, WebSqlDatabase

Cookie It is a standard way to save the state of ...

Vue basic instructions example graphic explanation

Table of contents 1. v-on directive 1. Basic usag...

Detailed explanation of JavaScript Reduce

Table of contents map filter some every findIndex...