寫在最前面···
之前在做一個手機端專案的時候,需要一個左右滑動(按周滑動)選擇日期外掛,而且當時這個專案沒有用到Vue。當時又沒有找到合適的第三方外掛,就花了點時間用原生JavaScript寫了出來,當時心中就想把它寫成基於Vue的元件,這短時間閒了把它弄出來了!,在這個過程中遇到了一個坑,後面會提出來!
先看效果
思路
根據使用者傳入日期(不傳預設今天),獲取上一週,當週,下一週對應的日期放陣列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'),
}
)
複製程式碼
根據datas 生成每一週對應的日期
getDaies (date) {
let vm = this,
arr = []
let weekOfDate = Number(moment(date).format('E'))
let weeks = ['日', '一', '二', '三', '四', '五', '六']
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
}
複製程式碼
生成每一個滑動單元的style
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 ? 'transform 0.5s ease-out' : 'transform 0s ease-out'
return style
}
複製程式碼
然後就是處理touchstart touchend touchmove事件了,這裡就不貼程式碼了,說下邏輯:
- touchstart 記錄滑動起點位置
- touchmove 獲得滑動距離賦值給 vm.distan.x 實時獲得當前周transform
- touchend 改變activeIndex的值,當然改變activeIndex的值是不夠的,要實現無限滑動,就要在操作一下dates,如果是左滑刪除dates的第一個元素並且往dates裡面push下下週對應日期,如果是右滑刪除最後一個元素併網陣列前面unshift上上週對應的日期
坑點
因為這個元件是通過css3的transition來實現動畫的,最開始我是把所用三個滑動元素在css裡面寫了transition:transform 0.5s ease-out; 誰知道自己把自己坑了,因為最後我們改變activeIndex後要刪除一個日期,還要往陣列裡面新增一個元素,這樣就會引起dates的改變,進而引起Vue去重新更新介面,導致動畫又出來了!最後想到的解決辦法就是引入一個變數isAnimation來控制transition的值,只有當滑動的時才開啟過度動畫效果,再偵聽transitionend時間重置isAnimation = false後再更新dates
使用
import weekSlider from 'v-week-slider'
Vue.use(weekSlider)
<week-slider></week-slider>
複製程式碼
props
prop | 必選 | 型別 | 說明 |
---|---|---|---|
defaultDate | false | String | 指定日期,預設今天,YYYY-MM-DD |
showYear | false | Boolean | 是否顯示當前周所屬年月,預設false |
events
名稱 | 說明 | 回撥引數 |
---|---|---|
dateClick | 點選日期觸發時間 | 點選的日期(YYYY-MM-DD) |
最後
第一次在社群發文章,Vue我也還在學習摸索中!寫得不好請各位看官輕拍!