基于vue的tab-list类目切换商品列表组件的示例代码


Posted in Javascript onFebruary 14, 2020

在大多数电商场景中,页面都会有类目切换加上商品列表的部分,页面大概会长这样

基于vue的tab-list类目切换商品列表组件的示例代码

基于vue的tab-list类目切换商品列表组件的示例代码

每次写类似场景的时候,都需要去为类目商品列表写很多逻辑,为了提高开发效率我决定将这一部分抽离成组件。

实现

1.样式

所有tab栏的样式和商品列表的样式都提供插槽,供业务自己定制

2.变量

isTabFixed: false,//是否吸顶
tab: 1,//当前tab
page: 1,//当前页数
listStatus: {
 finished: false,//是否已是最后一页
 loading: false,//是否加载中
},
items: [],//商品数组
tabMap: [],//tab列表数组
cache:{},//缓存
listName: '',//商品列表名称
tabName: '',//tab列表名称
apiName: '',//api方法名称
queryName: '',//api请求参数名称

3.缓存设计

为了减少消耗,已经请求过的商品列表我都将他们缓存下来

_addCache(proList) {
 cache[this.tab] = {
 finished: this.listStatus.finished,
 page: this.page,
 list: proList,
 };
},

4.请求数据

_getList(type) {
 let data = {};
 data[this.queryName] = this.tab;
 data.page = this.page;
 this.$http[this.apiName](data)
 .then((res) => {
 this.listStatus.finished = !res.has_more;//更新是否是最后一页的状态
 this._handleData(res.items);//处理得到的商品列表
 })
 .catch((err) => {
 note(err.message || '出错啦');
 });
},
_handleData(proList) {
 if (this.page === 1) {//表示是tab切换时请求的数据,所以直接将items的指向切换
 this.items = proList;
 } else {//因为是翻页,所以需要把数据拼接
 this.items = this.items.concat(proList);
 }
 this.$store.setData(this.listName, this.items);//把数据更新给父组件
 this._addCache(this.items);//把数据加入缓存
},

5.操作

逻辑部分主要分两块:一是列表翻页,二是tab相关

列表翻页

这部分的逻辑比较简单,主要分两点

  1. 将page加一
  2. 请求数据
_loadmore() {
 this.page = this.page + 1;
 this._getList();
},

其实对于手机列表的上拉翻页操作,还有很多的点要去注意,比如如何去避免连续请求等,由于我将这些交给了另一个专注列表渲染的组件,这里就不需要再去考虑这些操作。

tab相关

tab切换

tab切换的时候主要是两点

  1. 切换tab的指向
  2. 切换items的指向
  • 已经加载过的列表从缓存中取
  • 没有加载过的请求数据 然后还有两个体验上的点
  1. 视图应该回到顶部
  2. 切换的时候应该获取切换列表的第一页数据
changeTab(id) {
 this.tab = id;
 this.$store.setData(this.tabName, this.tab);//将tab的指向同步给父组件
 this._scrollToTab();//视图回到顶部
 if (cache[this.tab]) {
 const target = cache[this.tab];
 this.listStatus.finished = target.finished;
 this.page = target.page;
 this.items = target.list;
 this.$store.setData(this.listName, this.items);//将商品列表同步给父组件
 } else {
 this.page = 1;
 this._getList();
 }
},
//视图回到顶部
_scrollToTab() {
 let scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
 let productsTop = this.$refs.products.$el.offsetTop;//商品列表距离顶部的距离
 let topHeight = this.$refs.tabNav.offsetHeight;//tab栏的高度
 if (scrollTop > productsTop) {
 window.scrollTo(0, productsTop - topHeight);
 }
},

吸顶

在吸顶的时候,需要对tab栏的样式做一些小小的变动,所以需要一个变量来知道是否吸顶了

handleNavFixed() {
 this.stickyTop = this.$store.getData('stickyTop') || 0;//吸顶的高度
 window.onscroll = (e) => {
 let top = document.documentElement.scrollTop || document.body.scrollTop;
 let tabHeight = this.$refs.tabNav.offsetTop - top - 1;
 if (tabHeight <= this.stickyTop && !this.isTabFixed) {//结合判断为了避免重复计算
 this.isTabFixed = true;
 }
 if (tabHeight >= this.stickyTop && this.isTabFixed) {
 this.isTabFixed = false;
 }
 };
},

6.组件相关

作为一个组件,不同点在于需要做到的是可用性和通用性。 对于组件如何更好的得到父组件的值并把更新的值传回父组件方面,是我在开发过程中的一个卡点,最后我用了一套基于vue的组件通行机制。这种通行机制的实现网上很多,这里就不详细说了。通行机制主要有两个功能

  • 各组件间可以互相调用方法
  • 各个组件都可以得到和更新父组件的数据

由于将tab列表都作为插槽传入,所以初始数据并不需要关心,需要关心的只是更新数据。

对于不同的页面,tab列表的名称,tab定位的名称,商品列表的名称,接口的名称,请求接口的参数都可以会不一样,所以我在这里将这些项作为参数,在初始化这个组件的时候需要传入

//组件部分
init(data = {}) {
 this.listStatus.finished = !data.hasMore;
 this.tabName = data.tabName;
 this.listName = data.listName;
 this.apiName = data.apiName;
 this.queryName = data.queryName;
 this.handleNavFixed();//判断是否吸顶
},
//调用组件
this.$bus.emit('tab-list.init', {
 tabName: 'tab',
 listName: 'items',
 apiName: 'homeList',
 queryName: 'tab_id',
 hasMore: this.hasMore,
});

总结

以上所述是小编给大家介绍的基于vue的tab-list类目切换商品列表组件的示例代码,希望对大家有所帮助!

Javascript 相关文章推荐
用javascript操作xml
Nov 04 Javascript
理解JavaScript变量作用域更轻松
Oct 25 Javascript
JQuery获取当前屏幕的高度宽度的实现代码
Jul 12 Javascript
显示今天的日期js代码(阳历和农历)
Sep 30 Javascript
js倒计时抢购实例
Dec 20 Javascript
jQuery 3.0十大新特性最终版发布
Jul 14 Javascript
node.js的exports、module.exports与ES6的export、export default深入详解
Oct 26 Javascript
解决JSON.stringify()自动将中文转译成unicode的问题
Jan 05 Javascript
Vue 解决在element中使用$notify在提示信息中换行问题
Nov 11 Javascript
JavaScript中的宏任务和微任务详情
Nov 27 Javascript
一文了解JavaScript用Element Traversal新属性遍历子元素
Nov 27 Javascript
微信小程序APP的事件绑定以及传递参数时的冒泡和捕获
Apr 19 Javascript
bootstrap-paginator服务器端分页使用方法详解
Feb 13 #Javascript
JavaScript实现Tab选项卡切换
Feb 13 #Javascript
Angular 多模块项目构建过程
Feb 13 #Javascript
小程序卡片切换效果组件wxCardSwiper的实现
Feb 13 #Javascript
JavaScript实现省市区三级联动
Feb 13 #Javascript
jquery传参及获取方式(两种方式)
Feb 13 #jQuery
JS实现页面数据懒加载
Feb 13 #Javascript
You might like
为什么那些咖啡爱好者大多看不上连锁咖啡店?
2021/03/06 咖啡文化
php获取mysql版本的几种方法小结
2008/03/25 PHP
php发送与接收流文件的方法
2015/02/11 PHP
PHP编译安装时常见错误解决办法
2015/05/28 PHP
PHP结合Jquery和ajax实现瀑布流特效
2016/01/07 PHP
CSS3画一个阴阳八卦图
2021/03/09 HTML / CSS
js同时按下两个方向键
2007/12/01 Javascript
js+CSS 图片等比缩小并垂直居中实现代码
2008/12/01 Javascript
在jQuery ajax中按钮button和submit的区别分析
2012/10/07 Javascript
jquery实现图片上传之前预览的方法
2015/07/11 Javascript
ie下js不执行的几种可能
2017/02/28 Javascript
Angular2实现自定义双向绑定属性
2017/03/22 Javascript
node.js博客项目开发手记
2018/03/16 Javascript
跟混乱的页面弹窗说再见
2019/04/11 Javascript
vue路由的配置和页面切换详解
2020/09/09 Javascript
Python with的用法
2014/08/22 Python
win10环境下python3.5安装步骤图文教程
2017/02/03 Python
用TensorFlow实现多类支持向量机的示例代码
2018/04/28 Python
win8下python3.4安装和环境配置图文教程
2018/07/31 Python
selenium + python 获取table数据的示例讲解
2018/10/13 Python
python字典值排序并取出前n个key值的方法
2018/10/17 Python
Python数据类型之Number数字操作实例详解
2019/05/08 Python
python超时重新请求解决方案
2019/10/21 Python
python PyAUtoGUI库实现自动化控制鼠标键盘
2020/09/09 Python
解决PDF 转图片时丢文字的一种可能方式
2021/03/04 Python
Funko官方商店:源自美国,畅销全球搪胶收藏玩偶
2018/09/15 全球购物
写出程序把一个链表中的接点顺序倒排
2014/04/28 面试题
浪费资源的建议书
2014/03/12 职场文书
党课培训心得体会
2014/09/02 职场文书
建筑横幅标语
2014/10/09 职场文书
爱心捐款感谢信
2015/01/20 职场文书
保安辞职信范文
2015/02/28 职场文书
学校教代会开幕词
2016/03/04 职场文书
2019年公司快递收发管理制度模板
2019/11/20 职场文书
Python中相见恨晚的技巧
2021/04/13 Python
使用Mysql计算地址的经纬度距离和实时位置信息
2022/04/29 MySQL