基于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新手语法小结
Jun 15 Javascript
javaScript矢量图表库-gRaphael几行代码实现精美的条形图/饼图/点图/曲线图
Jan 09 Javascript
jquery制作弹窗提示窗口代码分享
Mar 02 Javascript
Jquery对数组的操作技巧整理
Mar 25 Javascript
Javascript aop(面向切面编程)之around(环绕)分析
May 01 Javascript
jQuery基于BootStrap样式实现无限极地区联动
Aug 26 Javascript
js禁止表单重复提交
Aug 29 Javascript
JS设计模式之命令模式概念与用法分析
Feb 06 Javascript
layui表格checkbox选择全选样式及功能的实例
Mar 07 Javascript
vue实现的网易云音乐在线播放和下载功能案例
Feb 18 Javascript
富文本编辑器vue2-editor实现全屏功能
May 26 Javascript
vue history 模式打包部署在域名的二级目录的配置指南
Jul 02 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
php面向对象的方法重载两种版本比较
2008/09/08 PHP
PHP连接MSSQL2008/2005数据库(SQLSRV)配置实例
2014/10/22 PHP
php从csv文件读取数据并输出到网页的方法
2015/03/14 PHP
PHP设计模式之装饰器模式定义与用法简单示例
2018/08/13 PHP
php面试实现反射注入的详细方法
2019/09/30 PHP
js文字滚动停顿效果代码
2008/06/28 Javascript
JavaScript 利用Cookie记录用户登录信息
2009/12/08 Javascript
淘宝搜索框效果实现分析
2011/03/05 Javascript
JS+flash实现chrome和ie浏览器下同时可以复制粘贴
2013/09/22 Javascript
js获得网页背景色和字体色的方法
2014/03/21 Javascript
基于javascript实现的搜索时自动提示功能
2014/12/26 Javascript
jQuery晃动层特效实现方法
2015/03/09 Javascript
jquery中ready()函数执行的时机和window的load事件比较
2015/06/22 Javascript
后端接收不到AngularJs中$http.post发送的数据原因分析及解决办法
2016/07/05 Javascript
jQuery实现table中的tr上下移动并保持序号不变的实例代码
2016/07/11 Javascript
AngularJS 与百度地图的结合实例
2016/10/20 Javascript
详解Nodejs的timers模块
2016/12/22 NodeJs
Angular2+国际化方案(ngx-translate)的示例代码
2017/08/23 Javascript
vue插件开发之使用pdf.js实现手机端在线预览pdf文档的方法
2018/07/12 Javascript
js遍历详解(forEach, map, for, for...in, for...of)
2019/08/28 Javascript
vue-preview动态获取图片宽高并增加旋转功能的实现
2020/07/29 Javascript
Python SQLAlchemy基本操作和常用技巧(包含大量实例,非常好)
2014/05/06 Python
Python实现简单字典树的方法
2016/04/29 Python
Python标准模块--ContextManager上下文管理器的具体用法
2017/11/27 Python
在Python函数中输入任意数量参数的实例
2019/07/16 Python
PyTorch中的C++扩展实现
2020/04/02 Python
python调用私有属性的方法总结
2020/07/24 Python
HTML5的结构和语义(2):结构
2008/10/17 HTML / CSS
亚瑟士美国官网:ASICS美国
2017/02/01 全球购物
介绍java中初始化块的使用
2012/09/11 面试题
城市规划毕业生求职信
2013/10/10 职场文书
办公室班子四风问题对照检查材料
2014/10/04 职场文书
群众路线查摆问题整改措施
2014/10/10 职场文书
客户经理岗位职责大全
2015/04/09 职场文书
《世界多美呀》教学反思
2016/02/22 职场文书
磁贴还没死, 微软Win11可修改注册表找回Win10开始菜单
2021/11/21 数码科技