The code implements a basic sliding function, and monitors sliding operations through mouse press, mouse release and mouse move events.
The specific implementation logic is as follows:
- In the
onMounted
hook function, we add three event listeners to the scroll container:mousedown
event: when the mouse is pressed, setcontrol.isDown
totrue
, and record the mouse start positioncontrol.startX
and scrollbar positioncontrol.scrollLeft
.mouseup
event: When the mouse is released, setcontrol.isDown
tofalse
, indicating that the mouse has been lifted.mousemove
event: when the mouse moves, ifcontrol.isDown
istrue
, calculate the mouse sliding distancewalk
, and set the scroll container’sscrollLeft
property tocontrol.scrollLeft - walk
.Through these event monitoring, we can realize the scrolling effect of scrolling the container when the mouse slides.
In addition, the code also includes the sliding function when the left and right arrow buttons are clicked. In the
onPageLeft
method, by modifying thescrollLeft
property of the scrolling container, slide to the left by a container width distance; in theonPageRight
method, by Modify thescrollLeft
property of the scrolling container to slide to the right by a container width.
Structure code
<template> <div class="swiper"> <div class="watch-list-arrow watch-list-arrow--left" @click="onPageLeft"> <div class="watch-list-arrow-btn">←</div> </div> <div ref="currencyItemsRef" class="currency-items"> <div class="currency-item" v-for="(item, index) in symbols" :key="index"> {<!-- -->{ item }} </div> </div> <div class="watch-list-arrow watch-list-arrow--right" @click="onPageRight"> <div class="watch-list-arrow-btn">→</div> </div> </div> </template>
Business logic
<script setup> import { ref, reactive, onMounted } from 'vue'; const symbols = ref([ 'BTC111', 'ETH', 'XRP', 'LTC', 'BCH', 'ADA', 'DOGE', 'DOT', 'LINK', 'UNI1', 'UNI2', 'UNI3', 'UNI4', 'UNI5', 'UNI6', 'UNI999' ]); const currencyItemsRef = ref(null); // Left and right arrows slide const onPageLeft = () => { // version one // currencyItemsRef.value.scrollLeft -= currencyItemsRef.value.offsetWidth; // version two // const containerWidth = currencyItemsRef.value.clientWidth; // const currentScrollLeft = currencyItemsRef.value.scrollLeft; // const nextScrollLeft = currentScrollLeft - containerWidth; // if (nextScrollLeft >= 0) { // currencyItemsRef.value.scrollTo({ // left: nextScrollLeft, // behavior: 'smooth' // }); // } else { // currencyItemsRef.value.scrollTo({ // left: 0, // behavior: 'smooth' // }); // } // version three currencyItemsRef.value.scroll({ left: currencyItemsRef.value.scrollLeft - currencyItemsRef.value.offsetWidth, behavior: 'smooth' }); }; const onPageRight = () => { // version one // currencyItemsRef.value.scrollLeft += currencyItemsRef.value.offsetWidth; // version two // const containerWidth = currencyItemsRef.value.clientWidth; // const maxScrollLeft = currencyItemsRef.value.scrollWidth - containerWidth; // const currentScrollLeft = currencyItemsRef.value.scrollLeft; // const nextScrollLeft = currentScrollLeft + containerWidth; // if (nextScrollLeft <= maxScrollLeft) { // currencyItemsRef.value.scrollTo({ // left: nextScrollLeft, // behavior: 'smooth' // }); // } else { // currencyItemsRef.value.scrollTo({ // left: maxScrollLeft, // behavior: 'smooth' // }); // } // version three currencyItemsRef.value.scroll({ left: currencyItemsRef.value.scrollLeft + currencyItemsRef.value.offsetWidth, behavior: 'smooth' }); }; // mouse scroll const control = reactive({ isDown: false, // Whether to press the mouse startX: 0, // mouse start position scrollLeft: 0 // scroll bar position }); const move = (e) => { if (!control. isDown) return; e.preventDefault(); const x = e.pageX - currencyItemsRef.value.offsetLeft; const walk = (x - control.startX) * 2; // sliding distance currencyItemsRef.value.scrollLeft = control.scrollLeft - walk; // control. scrollLeft = control. scrollLeft - walk; // requestAnimationFrame(() => { // currencyItemsRef.value.scrollLeft = control.scrollLeft; // }); }; onMounted(() => { console.log('dom', currencyItemsRef.value); // Summarize the realization of sliding on the web side, which is to monitor the mouse press, mouse release, and mouse movement events currencyItemsRef.value.addEventListener('mousedown', (e) => { control.isDown = true; control.startX = e.pageX - currencyItemsRef.value.offsetLeft; control.scrollLeft = currencyItemsRef.value.scrollLeft; }); currencyItemsRef.value.addEventListener('mouseup', (e) => { control.isDown = false; }); currencyItemsRef.value.addEventListener('mousemove', move); }); </script> <!-- In this example, we use vue's ref function to create a currencyItemsRef reference, which points to the div element of the scroll container. We also define the onPageLeft and onPageRight methods to handle the sliding events when the left and right arrows are clicked. In the onPageLeft method, we slide to the left by a distance of one container width by subtracting the width of the scrolling container. Similarly, in the onPageRight method, we slide to the right by a distance of one container width by adding the width of the scrolling container. By clicking the left and right arrow buttons, you can see that the scroll container will slide accordingly to display different items. -->
style
<style lang="scss" scoped> .swiper { display: flex; align-items: center; width: 800px; overflow: hidden; } .watch-list-arrow { display: flex; align-items: center; justify-content: center; width: 30px; height: 30px; background-color: lightgray; cursor: pointer; } .watch-list-arrow-btn { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; font-size: 20px; } .currency-items { display: flex; gap: 10px; overflow-x: scroll; scroll-behavior: smooth; scroll-snap-type: x mandatory; -webkit-overflow-scrolling: touch; /* &::-webkit-scrollbar { display: none; } */ } .currency-item { flex: 0 0 auto; width: 100px; height: 100px; background-color: lightblue; } </style>
The knowledge points of the article match the official knowledge files, and you can further learn relevant knowledge Vue entry skill tree Vue componentsGlobal and local components