vue axios 异步请求数据时 better-scroll不能初始化成功
1、vue 项目中使用axios异步请求数据
2、slide 图片滚动使用的是better-scroll插件
3、使用的vue slot插槽封装了better-scroll slide方法
4、第一次初始化不成功 获取不到滚动的width
5、父组件代码:
<template>
<div>
<div class="slide-wrap">
<slide :homelist.sync="homelist" :autoPlay="isAutoPlay" :loop="isLoop" :showDot="isShowDot" :interval="interval" :threshold="threshold" :speed="speed">
<div v-for="(item,index) in homelist" :key="index">
<a :href="item.advContent">
<img class="needsclick" :src="item.advTitle" alt="">
</a>
</div>
</slide>
</div>
</div>
</template>
<script>
import { getCommonAdv} from '@/api'
import slide from '@/components/pageRender/slideRender'
export default {
data(){
return {
homelist: [],
newslist: [],
isAutoPlay: true,
isLoop: true,
isShowDot: true,
speed: 400,
threshold: 0.3,
interval: 4000
}
},
created() {
this.getIndexBanner();
},
methods: {
getIndexBanner() {
let params = {apGradeno:'index_adv'}
getCommonAdv(params).then(res => { //此处是封装axios API请求
this.homelist = res.adv_list
console.log('11111')
}).catch(e => {
console.log(e);
});
}
},
components: {
slide
}
}
</script>
6、子组件代码
<template>
<div class="slider" ref="slide">
<div class="slider-group" ref="group">
<slot></slot>
<!--slot插槽说明
外部引用slide时,slider包裹的DOM会被插入进这个slot插槽部分
eg:
在相关页面需要引用slide组件的地方写下如下代码:
<slide>
<div>...这里写循环的内容与结构....</div>
</slide>
-->
</div>
<div class="dots">
<span class="dot" v-for="(item, index) in dots" :class="{active: currentPageIndex === index}"></span>
</div>
</div>
</template>
<script>
import BScroll from 'better-scroll'
import { addClass } from '@/utils/dom'
/**
* slide 基于better-scroll实现,监听了它的几个事件{snap,snapLoop,snapThreshold,snapSpeed }
* 注:better-scroll因为版本原因,以上几个事件会有出入,请参考官方文档
**/
const COMPONENT_NAME = 'slide'
export default {
name: COMPONENT_NAME,
data() {
return {
dots: [], // 定义一个名为dots的数组,小圆点数组
currentPageIndex: 0 // 当前的页码
}
},
//定义可在外部控制的属性
props: {
loop: { // 是否是循环轮播
type: Boolean,
default: true
},
autoPlay: { // 自动播放
type: Boolean,
default: true
},
interval: { // 自动轮播间隔
type: Number,
default: 4000
},
showDot: { //显示dot
type: Boolean,
default: true
},
threshold: { //表示可滚动到下一个的阈值
type: Number,
default: 0.3
},
speed: { //滚动速度
type: Number,
default: 400
},
homelist: { // 列表的数据
type: Array,
default: null
}
},
mounted() {
this.update()
//当调整浏览器窗口的大小时,发生 resize 事件。
window.addEventListener('resize', () => {
console.log('resize')
if (!this.slide || !this.slide.enabled) {
return
}
clearTimeout(this.resizeTimer)
this.resizeTimer = setTimeout(() => {
if (this.slide.isInTransition) {
this.onScrollEnd()
} else {
if (this.autoPlay) {
this.play()
}
}
this.refresh()
}, 60)
})
},
methods: {
update() {
// 初始化 better-scroll时机(*一般初始化better-scroll不成功,使用vue $nextTick方法 或者better-scroll推荐的settimeout延时20秒)
this.$nextTick(() => {
this.init()
})
},
refresh() {
this.setSlideWidth(true)
this.slide.refresh()
},
init() {
console.log('2222')
// clearTimeout(this.timer)
this.currentPageIndex = 0
this.setSlideWidth()
if (this.showDot) {
this.initDots()
}
this.initSlider()
if (this.autoPlay) {
this.play()
}
},
// 因为是横向滚动,需计算slide 的宽度并且赋值
setSlideWidth(isResize) {
this.children = this.$refs.group.children // 获取整个列表有多少个元素
console.log('group元素:')
console.log(this.children)
console.log('获取整个列表有多少个元素:' + this.children.length)
let width = 0 // 总的宽度
let slideWidth = this.$refs.slide.clientWidth // slide 父元素的宽度
for (let i = 0; i < this.children.length; i++) {
let child = this.children[i] // 获取每个子元素
addClass(child, 'slider-item') // 添加名为slider-item的类名
child.style.width = slideWidth + 'px'
width += slideWidth
}
if (this.loop && !isResize) { // 如果slide是需要循环的话,slide会在左右两侧copy两个子元素从而保证循环切换
width += 2 * slideWidth
}
this.$refs.group.style.width = width + 'px'
},
//初始化dot
initDots() {
this.dots = new Array(this.children.length)
console.log('获取dots:' + this.dots.length)
},
//初始化slide
initSlider() {
console.log(this.threshold)
this.slide = new BScroll(this.$refs.slide, {
scrollX: true, // 横向滚动
scrollY: false, // 不允许纵向滚动
momentum: false, // 是否开启动量动画,关闭可以提升效率
snap: {
loop: this.loop,
threshold: 0.3,
speed: 400
}
})
this.slide.on('scrollEnd', () => {
// 参考文档 https://ustbhuangyi.github.io/better-scroll/doc/zh-hans/api-specific.html#getcurrentpage
let pageIndex = this.slide.getCurrentPage().pageX
if (this.loop) {
pageIndex -= 1 // 因为设置自动播放之后,会自动在左右两侧copy两个子元素,所以在设置pageIndex时应减一
}
this.currentPageIndex = pageIndex
if (this.autoPlay) {
this.play()
}
})
// 参考文档 https://ustbhuangyi.github.io/better-scroll/doc/zh-hans/events.html#beforescrollstart
this.slide.on('beforeScrollStart', () => {
if (this.autoPlay) {
clearTimeout(this.timer)
}
})
},
onScrollEnd() {
let pageIndex = this.slide.getCurrentPage().pageX
this.currentPageIndex = pageIndex
if (this.autoPlay) {
this.play()
}
},
play() {
clearTimeout(this.timer)
this.timer = setTimeout(() => {
this.slide.next()
}, this.interval)
},
watch: {
// 监听数据的变化,调用refresh方法重新计算,保证滚动效果正常
homelist() {
setTimeout(() => {
this.refresh()
}, 20)
}
}
}
}
</script>
7、group元素能打印出数组,但是长度却是0
8、调试了下 发现在axios异步请求没有返回数据的时候走了slide的初始化
9、子组件修改之后是可以正确加载的,只是初始化不行,请帮我看看是哪个环节出现的问题
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论