vue中better-scroll实现商品分类左右联动

结合better-scroll插件实现商品分类左右联动交互方式。

文章目录

  • vue中better-scroll实现商品分类左右联动
    • 前提准备
    • 效果图
    • 1. 初始化数据
    • 2. 实现左联动右
    • 3. 实现右联动左
    • 完整demo

前提准备

  • 安装: npm i better-scroll -S
  • 组件中引入: import BScroll from 'better-scroll'
  • better-scroll官网

相关文章:

better-scroll监听元素吸顶

better-scroll商品详情联动

步骤:

  • 先实现左联右
  • 再实现右联左

效果图

1. 初始化数据

data() {return {currentIndex: 0, //当前选中indexscrollY: 0,heightList: [0], //存储某个分类下的商品高度列表flag: false, //标识是否选中fixedTitle: '', //当前分类标题tagList: [{"type": 1, "name": "全部"}, {"type": 2, "name": "热销"}], //分类列表tagIndex: 0, //分类tag当前indextype: 1, // 1:全部 2:热销categoryList: [ // 数据仅供测试,请自行copy多些来看效果{   categoryId: 1,name: "健康蔬菜",goods: [{goodsName: '大个小番茄',goodsSummary: '绿色小番茄',goodsStock: 231,goodsRetailPrice: 5.4,goodsMarketPrice: 6.8,// goodsMainImage: require('../../assets/images/icon/icon_1.png')goodsMainImage: 'xxxxx'},{goodsName: '新鲜小奶白菜',goodsSummary: '清脆、鲜嫩蔬菜',goodsStock: 134,goodsRetailPrice: 3.8,goodsMarketPrice: 5.5,goodsMainImage: 'xxxxx'},]},{   categoryId: 2,name: "时令蔬菜",goods: [{goodsName: '大又甜地瓜',goodsSummary: '自家种植放心品尝',goodsStock: 344,goodsRetailPrice: 6.5,goodsMarketPrice: 8.4,goodsMainImage: 'xxxxx'},{goodsName: '精美套餐',goodsSummary: '健康搭配新鲜蔬菜',goodsStock: 1099,goodsRetailPrice: 45.9,goodsMarketPrice: 65.8,goodsMainImage: 'xxxxx'},{goodsName: '水果黄瓜',goodsSummary: '可口脆嫩水果黄瓜',goodsStock: 785,goodsRetailPrice: 3.5,goodsMarketPrice: 4.8,goodsMainImage: 'xxxxx'},]},]}
},

2. 实现左联动右

使用better-scroll中的scrollToElement方法。

说明:

  1. scrollToElement(el, time, offsetX, offsetY, easing)

    滚动到某个元素,el(必填)表示 dom 元素,time 表示动画时间,offsetXoffsetY 表示坐标偏移量,easing 表示缓动函数

  2. scroll: 滚动时触发

  3. scrollEnd:滚动结束时触发

  4. destroy():销毁 better-scroll,解绑事件


  • 目标元素区域上添加ref属性标识。【右侧商品列表中标识ref="good"
<!-- 右侧商品列表 -->
<section class="right_list fixeds" ref="r_list"><div><div class='listsWrap'><ul class="goods-list" v-for="(outerItem, outerIdx) in categoryList" :key="outerIdx" ref="good"><li class="goods-li bd" v-for="(item, index) in outerItem.goods" :key="index"><!-- 自定义内容 --></li></ul></div></div>
</section>
  • 在左边菜单中添加点击事件,滑动到右侧对应的位置。【这里定义changeMenu事件】
<aside class="fixeds" ref="l_list"><ul class="left-menu"><li ref="l_item" :class="{'active': index === currentIndex}" @click="changeMenu(index, item.name)" v-for="(item, index) in categoryList" :key="index"><div class="cname" ref="cname">{{item.name}}</div></li></ul>
</aside>
changeMenu (index, name) {this.currentIndex = index; //当前选中indexthis.fixedTitle = name; //当前选中标题//【-32 标题高度】 根据自身调整,如果不需要写0即可。this.rightList.scrollToElement(this.$refs.good[index], 1000, 0, -32);
},
  • 初始化better-scroll中获取左菜单定义的ref属性,并开启点击事件
 this.left = new BScroll(this.$refs.l_list, {click: true, //是否开启点击事件probeType: 3, //是否会截流scroll事件})

3. 实现右联动左

  • 监听右侧滚动时触发的距离,可通过scroll事件来监听当前值。

这里右侧数据格式: 每个分类下有n个商品【即嵌套列表】

this.rightList = new BScroll(this.$refs.r_list, {probeType: 3, // 是否会截流scroll事件scrollY: true,  // 是否开启Y轴滚动方向click: true, // 是否开启点击事件useTransition: false, // 防止iphone微信滑动卡顿bounce: true, // 是否启用回弹动画效果momentumLimitDistance: 5 // 符合惯性拖动的最小拖动距离
})this.rightList.on('scroll', (res) => {// 获取当前滚动距离this.scrollY = Math.abs(Math.round(res.y));
})
  • 定义数组,用来存储每个分类下的商品列表离顶部的距离
this.$refs.good.forEach((el, index) => {this.heightList.push(el.offsetHeight + this.heightList[index]);
})
  • 拿到content滚动距离和每个子商品列表离顶部距离比较。更新左菜单index选中状态

遍历每个分类下的商品列表距离列表

for (let i = 0; i < this.heightList.length; i++) {if (this.scrollY > this.heightList[i] && this.scrollY < this.heightList[i + 1]) {if (!this.flag) {this.currentIndex = i;}}
}

完整demo

请下载

完整js

<script>
import BScroll from "better-scroll";export default {data() {return {currentIndex: 0, // 当前选中indexscrollY: 0,heightList: [0], // 存储某个分类下的商品高度列表flag: false, // 解决是否选中当前分类indexfixedTitle: '', // 当前分类标题tagList: [{"type": 1, "name": "全部"}, {"type": 2, "name": "热销"}], //分类列表tagIndex: 0, //分类tag当前indextype: 1, // 1:全部 2:热销categoryList: [ // 数据仅供测试,请自行copy多些来看效果{   categoryId: 1,name: "健康蔬菜",goods: [{goodsName: '大个小番茄',goodsSummary: '绿色小番茄',goodsStock: 231,goodsRetailPrice: 5.4,goodsMarketPrice: 6.8,goodsMainImage: 'xxxxx'},{goodsName: '新鲜小奶白菜',goodsSummary: '清脆、鲜嫩蔬菜',goodsStock: 134,goodsRetailPrice: 3.8,goodsMarketPrice: 5.5,goodsMainImage: 'xxxxx'},]},{   categoryId: 2,name: "时令蔬菜",goods: [{goodsName: '大又甜地瓜',goodsSummary: '自家种植放心品尝',goodsStock: 344,goodsRetailPrice: 6.5,goodsMarketPrice: 8.4,goodsMainImage: 'xxxxx'},{goodsName: '精美套餐',goodsSummary: '健康搭配新鲜蔬菜',goodsStock: 1099,goodsRetailPrice: 45.9,goodsMarketPrice: 65.8,goodsMainImage: 'xxxxx'},{goodsName: '水果黄瓜',goodsSummary: '可口脆嫩水果黄瓜',goodsStock: 785,goodsRetailPrice: 3.5,goodsMarketPrice: 4.8,goodsMainImage: 'xxxxx'},]},]}},mounted() {this.fixedTitle = this.categoryList[0].name;this.$nextTick(() => {// 初始化better-scrollthis.scrollInit(); // 获取某个分类下商品列表离顶部距离this.getCategoryListHeight();})},methods: {toCommTap(url) {this.$router.push(url);},changeMenu (index, name) {this.flag = true;this.currentIndex = index;this.fixedTitle = name;//【-32 标题高度】 根据自身调整,如果不需要写0即可。this.rightList.scrollToElement(this.$refs.good[index], 1000, 0, -32);},chageTag(index, type) {this.tagIndex = index;this.type = type;console.log('切换标签');},/** * 初始化*/scrollInit() {this.left = new BScroll(this.$refs.l_list, {click: true,probeType: 3,})this.rightList = new BScroll(this.$refs.r_list, {probeType: 3, // 是否会截流scroll事件scrollY: true,  // 是否开启Y轴滚动方向click: true, // 是否开启点击事件useTransition: false, // 防止iphone微信滑动卡顿bounce: true, // 是否启用回弹动画效果momentumLimitDistance: 5 // 符合惯性拖动的最小拖动距离})this.rightList.on('scroll', (res) => {this.scrollY = Math.abs(Math.round(res.y));for (let i = 0; i < this.heightList.length; i++) {if (this.scrollY > this.heightList[i] && this.scrollY < this.heightList[i + 1]) {if (!this.flag) {this.currentIndex = i;}// 当滚动到倒数第2个位置时左侧列表向上滚动一个距离if (i === this.$refs.l_item.length - 2) {this.left.scrollToElement(this.$refs.l_item[1], 1000, 0, 0)}// 当滚动到倒数第3个位置时左侧列表向上下滚动一个距离if (i === 2) {this.left.scrollToElement(this.$refs.l_item[0], 1000, 0, 0)}// 获取当前分类标题this.fixedTitle = this.$refs.cname[i].innerText;}}})this.rightList.on("scrollEnd", pos => {//结束时触发事件获取一次位置,因为使用了模式2,惯性滚动不触发事件this.scrollY = Math.abs(Math.round(pos.y));this.flag = false;})},/*** 获取商品列表高度*/getCategoryListHeight() {this.$refs.good.forEach((el, index) => {this.heightList.push(el.offsetHeight + this.heightList[index]);})},addToShopCart(item) {// 添加购物车事件},}
}
</script>

vue实现商品分类左右联动相关推荐

  1. vue省市区镇四级联动

    vue省市区镇四级联动 参考文档https://terryz.gitee.io/vue/#/region/demo 使用npm把插件安装到项目中 npm i -S v-region 在项目入口main ...

  2. Django 前后端分离实战项目 生鲜超市(七)之Vue展示商品分类数据和搜索

    Vue展示商品分类数据和搜索 前言 所有vue接口全部在src/api/api.js文件下 代码已上传至github:https://github.com/kalipoison/fresh-marke ...

  3. vue项目实现商品分类双向联动【简洁易懂】

    先上一张效果图给大家looklook 源码如下 <template> <!-- OK OK --><div class="list"><! ...

  4. Vue实现左右菜单联动实现

    知乎 个人博客 Github 源码传送门:Rain120/vue-study 根据掘金评论需求,更新了数据接口并修复了一些问题 之前在外卖软件上看到这个左右联动的效果,觉得很有意思,所以就尝试使用Vu ...

  5. 【巷子】---vue基于mint-ui三级联动---【vue】

    一.基本配置 https://github.com/modood/Administrative-divisions-of-China 三级联动数据地址 二.vue基本配置 1.cnpm install ...

  6. vue mint-ui 三级地址联动

    我也是第一次写这种地址联动的 刚开始的时候 我还以为直接用select来写 后来公司的ios告知并不是这样的 他说应该时这样的 于是第一想法 赶紧找插件吧 但是找了一会未果  就问了公司大神 他刚开始 ...

  7. 【vue+vue-area-linkage】三级联动省市区选择器

    1.安装新依赖**:npm i --save vue-area-linkage area-data 这里其实安装了两个依赖分别是: 选择器插件 npm i --save vue-area-linkag ...

  8. vue实现省市区三级联动地址选择组件

    昨天收到一个新的需求,需要选择地址,因此就要做一个省市区三级联动的组件来使用,在网上找了一些资源,然后进行了尝试,没想到就这么成功了!要记录一下方便后续使用. 效果如下:  下面就记录一下代码叭! 一 ...

  9. 如何用vue做一个二级联动

    如何做一个像这样二级联动的目录? 先来说说重点和思路:重点在于router-view的使用以及vue-router的配置,思路是两层children的嵌套. 下面开始实现功能. 翻开我们的vue工程的 ...

最新文章

  1. myecplise 添加svn插件
  2. compileReleaseJavaWithJavac
  3. maven运行时的配置及命令详解
  4. 基于 Spring Cloud 的服务治理实践
  5. java用do while语句逆序输出_跟我学java编程—深入理解do-while循环语句的用法
  6. 服务器建立共享后无法写入文件,Win7 局域网共享问题,XP访问Win7复制或写入一会文件之后出现无法访问,您没有权限,或者说服务器空间不足...
  7. 第二阶段冲刺 站立会议03
  8. C#数组原来这么简单,你学废了吗?
  9. 适用于树莓派Raspberry Pi的嵌入式QT平台(二) -- 在Windows下用Qt Creator开发编译Raspberry Qt 5应用程序...
  10. 代码之美~强大的构造方法重载
  11. 182.查找重复的电子邮箱
  12. 高效维持网络长连接:手把手教你实现 自适应的心跳保活机制
  13. c 语言基础笔试题1
  14. Mars3D基础学习:地图图层 Layer
  15. feign不能正常传递参数MultipartFile(文件)时的解决手段
  16. %02x与%2x 之间的区别
  17. 致远OA—V5版本系统预置用户密码恢复方法
  18. 科大奥锐干涉法测微小量实验的数据,大学物理实验报告答案大全(实验数据)
  19. 问道怎么找回以前的服务器,问道服务器盘点“北京古都”传奇之地
  20. 计算机启动后只有鼠标桌面黑屏,电脑开机黑屏只有鼠标的解决方法

热门文章

  1. 华为20plus升级鸿蒙系统,华为鸿蒙系统正式版发布!多款手机可升级,完美解决安卓痛点!...
  2. mysql的case then语句_mysql case then使用
  3. 学python可以做什么职业-转行学python后,从事自由职业,分享下月入10000+的经验...
  4. three.js 项目篇 之 汽车展示与控制车身颜色与贴膜材质
  5. 华为推出OpenHarmony生态使能服务 加速OpenHarmony商用发行版落地
  6. Spring基本使用(元素lookup-method使用)
  7. 乡村少年宫计算机小组活动教案,乡村少年宫电脑绘兴趣小组教案.doc
  8. woff 404 woff2 404
  9. 智能卡 14443A 协议 读卡器 和智能卡 数据传输协议
  10. 网络行为审计技术深度解析