背景
因为要做手机页面的商品列表滚动。类似这种
看了一眼人家的插件 索性一想还不是自己写一个。
前期准备
- vue 自定义指令
- zan ui https://www.youzanyun.com/zanui/vant#/zh-CN/intro
- javascript scroll事件
指令代码
const goodScroll = {
inserted(el, binding, vnode) {
const callBack = binding.value
el.addEventListener('scroll', e => {
const allTopValues = [] //保存所有子元素的offsetTop值
el.childNodes.forEach(a => {
allTopValues.push(a.offsetTop)
})
const scrollTop = el.pageYOffset || el.scrollTop || el.scrollTop
let i = 0
for (; i < allTopValues.length; i++) {
//确定父标签落在哪个子元素内
if (allTopValues[i] > scrollTop) {
break
}
}
callBack(i - 1) //回调指令绑定函数
})
}
}
export { goodScroll }
vue template(关键部分)
<div class="g-container">
<div class="g-category">
//注意此处的 :active-key="activeKey" 回调会改变这个值
<van-badge-group :active-key="activeKey">
<van-badge :title="item.name" :key="index" v-for="(item,index) in category" @click="onClick(index)" />
</van-badge-group>
</div>
//注意此处的 v-goodScroll="onScroll" ref="goodslist"
<div class="goods-list" v-goodScroll="onScroll" ref="goodslist">
<ul v-for="(aandg,index) in aandgs" :key="index" class="g-item">
<li class="li-title">{{aandg.category.name}}</li>
<li class="li-goods clearfix" v-for="goods in aandg.goods" :key="'_goods_'+goods.id">
<div class="g-item-left">
<img :src="goods.picUrl">
</div>
<div class="g-item-right">
<div class="g-item-name">{{goods.name}}</div>
<div class="g-item-price">¥{{goods.price || 100}}</div>
<div class="g-item-add"><van-icon name="add-o" /></div>
</div>
</li>
</ul>
</div>
</div>
vue script
methods:{
onClick(index) {
this.$refs.goodslist.scrollTop = this.$refs.goodslist.childNodes[index].offsetTop
// console.log(this.$refs.goodslist)
},
onScroll(i) {
this.activeKey = i
console.log(i)
}
}
思路
滑动
- 在指令里,为需要滑动的元素监听 scroll 事件,
- 滚动完毕计算元素滚动的距离,得到滚动到当前哪个子组件范围里。回调指令绑定函数
- 在改变右侧的导航。
导航点击
- 为滑动元素添加refs
- 导航点击时,得到滑动元素的子元素序号。(反正是你能找到哪个子组件就行,管你传啥。哈哈)
- 通过 refs得到滑动元素的dom。操作dom即可。
广告 :想学架构的同学看下 直通车