基于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 相关文章推荐
多引号嵌套的变量命名的问题
May 09 Javascript
jQuery中find()方法用法实例
Jan 07 Javascript
jquery实现鼠标经过显示下划线的渐变下拉菜单效果代码
Aug 24 Javascript
简述jQuery ajax的执行顺序
Jan 05 Javascript
利用JQuery写一个简单的异步分页插件
Mar 07 Javascript
文本框只能输入数字的js代码(含小数点)
Jul 10 Javascript
ZeroClipboard.js使用一个flash复制多个文本框
Jun 19 Javascript
js动态添加表格逐行添加、删除、遍历取值的实例代码
Jan 25 Javascript
jQuery实现鼠标滑过商品小图片上显示对应大图片功能【测试可用】
Apr 27 jQuery
layer插件实现在弹出层中弹出一警告提示并关闭弹出层的方法
Sep 24 Javascript
vue 实现一个简单的全局调用弹窗案例
Sep 10 Javascript
Three.js实现雪糕地球的使用示例详解
Jul 07 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
动态网站web开发 PHP、ASP还是ASP.NET
2006/10/09 PHP
IIS6+PHP5+MySQL5+Zend Optimizer+phpMyAdmin安装配置图文教程 2009年
2009/06/08 PHP
CI框架装载器Loader.php源码分析
2014/11/04 PHP
分享自定义的几个PHP功能函数
2015/04/15 PHP
JavaScript 字符编码规则
2009/05/04 Javascript
基于jquery的气泡提示效果
2010/05/31 Javascript
javascript跟随滚动效果插件代码(javascript Follow Plugin)
2013/08/03 Javascript
遮罩层点击按钮弹出并且具有拖动和关闭效果(两种方法)
2015/08/20 Javascript
Nodejs爬虫进阶教程之异步并发控制
2016/02/15 NodeJs
详解jQuery中的empty、remove和detach
2016/04/11 Javascript
Reactjs实现通用分页组件的实例代码
2017/01/19 Javascript
JS判断非空至少输入两个字符的简单实现方法
2017/06/23 Javascript
简单实现js上传文件功能
2017/08/21 Javascript
jQuery 利用ztree实现树形表格的实例代码
2017/09/27 jQuery
Vue监听事件实现计数点击依次增加的方法
2018/09/26 Javascript
使vue实现jQuery调用的两种方法
2019/05/12 jQuery
使用 JavaScript 创建并下载文件(模拟点击)
2019/10/25 Javascript
jQuery实时统计输入框字数及限制
2020/06/24 jQuery
Flask SQLAlchemy一对一,一对多的使用方法实践
2013/02/10 Python
Python栈算法的实现与简单应用示例
2017/11/01 Python
Python使用matplotlib填充图形指定区域代码示例
2018/01/16 Python
目前最全的python的就业方向
2018/06/05 Python
Pycharm配置远程调试的方法步骤
2018/12/17 Python
Python实现爬取亚马逊数据并打印出Excel文件操作示例
2019/05/16 Python
python图形绘制奥运五环实例讲解
2019/09/14 Python
python基于plotly实现画饼状图代码实例
2019/12/16 Python
解决pycharm上的jupyter notebook端口被占用问题
2019/12/17 Python
Python tkinter常用操作代码实例
2020/01/03 Python
Python文件操作方法详解
2020/02/09 Python
Python实现PS滤镜中的USM锐化效果
2020/12/04 Python
美国第一香水网站:Perfume.com
2017/01/23 全球购物
大型车展策划方案
2014/02/01 职场文书
洗发水广告词
2014/03/13 职场文书
基本公共卫生服务健康教育工作方案
2014/05/22 职场文书
电子信息工程自荐信
2014/05/26 职场文书
Windows10下安装MySQL8
2021/04/06 MySQL