Write it at the top

When I was working on a mobile project, I needed a left/right (weekly) slide to select dates, and I didn’t use Vue at that time. At that time, I did not find a suitable third party plug-in, so I spent some time writing it in native JavaScript. At that time, I wanted to write it as a VUe-based component, so I did it in a short time. , in this process encountered a pit, will be put forward later!

Look at the effect

Train of thought

Based on the date passed in by the user (not today by default), get the previous, current, and next week’s corresponding dates and put them in array dates

        let vm = this
        this.dates.push(
            {
                date: moment(vm.defaultDate).subtract(7.'d').format('YYYY-MM-DD'),}, {date: vm.defaultDate,
            },
            {
                date: moment(vm.defaultDate).add(7.'d').format('YYYY-MM-DD'})),Copy the code

Generate a date for each week based on the datAS

getDaies (date) {
            let vm = this,
                arr = []
            let weekOfDate = Number(moment(date).format('E'))
            let weeks = ['day'.'一'.'二'.'三'.'four'.'five'.'六']
            let today = moment()
            let defaultDay = moment(vm.defaultDate)
            for (var i = 0; i < 7; i++) {
                let _theDate = moment(date).subtract(weekOfDate - i, 'd')
                arr.push({
                    date: _theDate.format('YYYY-MM-DD'),
                    week: weeks[i],
                    isToday: _theDate.format('YYYY-MM-DD') === today.format('YYYY-MM-DD'),
                    isDay: _theDate.format('E') === defaultDay.format('E')})}return arr
        }
Copy the code

Generate the style for each slide cell

        getTransform (index) {
            let vm = this
            let style = {}
            if (index === vm.activeIndex) {
                style['transform'] = 'translateX('+ vm.distan.x +'px)'
            }
            if (index < vm.activeIndex) {
                style['transform'] = 'translateX(-100%)'
            }
            if (index > vm.activeIndex) {
                style['transform'] = 'translateX(100%)'
            }
            style['transition'] = vm.isAnimation ? 'the transform 0.5 s ease - out' : 'transform 0s ease-out'
            return style
        }
Copy the code

The next step is to handle the TouchStart, TouchEnd, touchMove event. I won’t post the code here, but the logic:

  • Touchstart Records the starting position of sliding
  • Touchmove gets the sliding distance and assigns it to vm.distan.x to get the current week transform in real time
  • Touchend changes the activeIndex value. Of course, changing the activeIndex value is not enough. To enable an infinite slider, you need to set Dates. If it is right swipe to remove the last element in the grid array before unshift on the corresponding date of the last week

Pit point

Transition :transform 0.5s ease-out; Transform 0.5s ease-out; transform 0.5s ease-out; Finally, we changed the activeIndex to delete a date and add a new element to the array. This will cause the dates to change, which will cause Vue to update the interface again, which will cause the animation to come out again! The solution we came up with was to introduce a variable called isAnimation to control the transition value, enable the transition effect only when sliding, listen to the transitionEnd time, reset isAnimation = false, and update dates

use

import weekSlider from 'v-week-slider'

Vue.use(weekSlider)

<week-slider></week-slider>
Copy the code

props

prop Will choose type instructions
defaultDate false String Specifies the date, default today, YYYY-MM-DD
showYear false Boolean Whether to display the date of the current week. The default value is false

events

The name of the instructions The callback parameter
dateClick Click on the date trigger time Click date (YYYY-MM-DD)

The last

Making the address

The first time in the community to send an article, Vue I also still in learning to grope! Write bad please look at the officer pat!