start
The last demonstration of vertical scrolling on mobile end was realized based on Better Scroll. This time continue to use it to implement a horizontal scroll – the wheel – cast graph component. The demo is as follows:
First, sort out the requirements:
- According to the asynchronous request to the picture data for the rotation of the graph display.
- Can control whether it plays automatically, whether to play in a loop, automatic play interval.
- Can prompt current playing page.
The Mock data
As it was a demo, I found several pictures from the Internet and wrote them in JSON format. The data was used to simulate the interface data. Mock. Js is used here. Axios. Installation method is as follows:
npm install mockjs
Copy the code
npm install --save axios vue-axios
Copy the code
I won’t go into the axios usage too much, but let’s briefly describe mock data. Create a new JSON folder under the Mock folder to place the JSON data files. Create an index.js export interface. You can use AXIOS to request the interface.
[
"https://img3.mukewang.com/szimg/5df8852609e0762d12000676-360-202.png"."https://img1.mukewang.com/szimg/5d9c62fb0907ccf012000676-360-202.png"."https://img3.mukewang.com/5aeecb1d0001e5ea06000338-360-202.jpg"
]
Copy the code
const Mock = require('mockjs')
Mock.mock('/slider'.'get', require('./json/slider.json'))
Copy the code
Base component: Slider.vue
Abstract the multicast map component, receive isLoop, isAutoPlay, interval attributes to control the multicast map. The mounted method is called in the same order
- SetSliderWidth () gets and sets the display layer and image wrap layer height.
setSliderWidth() {/* Get the display layer width, calculate the content layer width */ const clientWidth = this.$refs.slider.clientWidth
let sliderWidth = 0
this.children = this.$refs.group.children
for (let i = 0; i < this.children.length; i++) {
this.children[i].style.width = clientWidth + 'px'
sliderWidth += clientWidth
}
if(this.isloop) {/* Loop playback needs to increase the front and back widths */ sliderWidth += clientWidth * 2} this.$refs.group.style.width = sliderWidth + 'px'/* Set the content layer width */},Copy the code
- InitDots () sets the array to place dots based on the number of image layer children.
initDots () {
this.dots = new Array(this.children.length)
},
Copy the code
- InitSlider () initializes the better-scroll.
initSlider () {
this.slider = new BScroll(this.$refs.slider, {
scrollX: true, /* horizontal scroll */ scrollY:false, snap: {/* Loop slider setting */ loop: this.isloop, threshold: 0.3, speed: 400}}) this.slider.on('scrollEnd', () = > {const pageIndex = this. The slider. GetCurrentPage () pageX / * for current shuffling pages, used for dot prompt * / this. CurrentIndex = pageIndexif(this.isautoplay) {clearTimeout(this.timer) /* reset autoPlay, otherwise it will not autoPlay */ this.autoplay ()}})},Copy the code
- AutoPlay () sets autoPlay.
autoPlay () {
this.timer = setTimeout(() => {
this.slider.next(400)
}, this.interval)
}
Copy the code
Complete code:
<template>
<div class="slider-apply" ref="slider"> <! Display layer --> <div class="slider-group" ref="group"> <! -- All images wrapped layer --> <slot></slot> <! </div> <div class="dots"> <! --> <div class="dot" v-for="(item, index) in dots" :key="index" :class="currentIndex===index? 'active':''"></div>
</div>
</div>
</template>
<script type='text/ecmascript-6'>
import BScroll from 'better-scroll'
export default {
data () {
return{dots: [], currentIndex: 0 /* Current page subscript */}}, props: {isLoop: {/* Loop */type: Boolean,
default: true}, isAutoPlay: {/* autoplay */type: Boolean,
default: true}, interval: {/* Playback interval */type: Number,
default: 2000
}
},
mounted/* mounted */setTimeout(() => {
this.setSliderWidth()
this.initDots()
this.initSlider()
if (this.isAutoPlay) {
this.autoPlay()
}
}, 20)
},
methods: {
setSliderWidth() {/* Get the display layer width, calculate the content layer width */ const clientWidth = this.$refs.slider.clientWidth
let sliderWidth = 0
this.children = this.$refs.group.children
for (let i = 0; i < this.children.length; i++) {
this.children[i].style.width = clientWidth + 'px'
sliderWidth += clientWidth
}
if(this.isloop) {/* Loop playback needs to increase the front and back widths */ sliderWidth += clientWidth * 2} this.$refs.group.style.width = sliderWidth + 'px'/* Set the content layer width */},initDots () {
this.dots = new Array(this.children.length)
},
initSlider () {
this.slider = new BScroll(this.$refs.slider, {
scrollX: true, /* horizontal scroll */ scrollY:false, snap: {/* Loop slider setting */ loop: this.isloop, threshold: 0.3, speed: 400}}) this.slider.on('scrollEnd', () = > {const pageIndex = this. The slider. GetCurrentPage () pageX / * for current shuffling pages, used for dot prompt * / this. CurrentIndex = pageIndexif(this.isautoplay) {clearTimeout(this.timer) /* reset autoPlay, otherwise it will not autoPlay */ this.autoplay ()}})},autoPlay () {
this.timer = setTimeout(() => {
this.slider.next(400)
}, this.interval)
}
},
destroyed() {/* Make sure to clear timer */ clearTimeout(this.timer)}} </script> <style lang="stylus"Scoped >. Slider-apply position relative // Let dots locate position 200px width 100% // Slider-apply will display width overflow Hidden based on parent element width Dots position absolute bottom 10px left 50% transform translate(-50%, Display flex. dot margin 0 10px height 7px width 7px background#fffBorder-radius 50. active // Current dot style width 15px border-radius 505px </style>Copy the code
Application component: Slider-apply.vue
You can apply it to your own projects using the method in alider-apply.vue.
<template>
<div class="slider-wrapper">
<Slider v-if="showSlider"> <! ShowSlider makes the data request complete before displaying, otherwise the Better Scroll might miscalculate --> <div v-for="item in imageList" :key="item" class="slider-item">
<img :src="item" class="img">
</div>
</Slider>
</div>
</template>
<script type='text/ecmascript-6'>
import Slider from 'base/slider'
export default {
data () {
return{imageList: [], // imageList showSlider:false// Display slider bit}},created() {this.getimages ()}, methods: {getImages () {
this.axios.get('/slider').then((res) => {
this.imageList = res.data
this.showSlider = true
}).catch((err) => {
console.log(err)
})
}
},
components: {
Slider
}
}
</script>
<style lang="stylus"Scoped >. Slider-wrapper margin 0 auto height 200px width 500px Scoped >. Slider-wrapper margin 0 auto height 200px scoped># 000
border-radius 5px
.slider-item
float</style> </style>Copy the code
conclusion
- If the above steps are not clear, you can find the source in my Github https://github.com/Gesj-yean/vue-demo-collection.
- It’s not as difficult as you might think (go for it).
Later will encapsulate more components, and I write components snap, end, scatter flowers ~
More recommended
- Implement Vue – based Dialog Dialog box components
- Implement Vue – based Pagination pager component
- Understand Vue recursive components, implement Tree Tree control instances ~