基于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 生成指定范围数值随机数
Jan 09 Javascript
jQeury淡入淡出需要注意的问题
Sep 08 Javascript
jquery判断字符输入个数(数字英文长度记为1,中文记为2,超过长度自动截取)
Oct 15 Javascript
在Javascript里访问SharePoint列表数据的实现方法
May 22 Javascript
如何让easyui gridview 宽度自适应窗口改变及fitColumns应用
Jan 25 Javascript
jQuery.prototype.init选择器构造函数源码思路分析
Feb 05 Javascript
JS 两个字符串时间的天数差计算
Aug 25 Javascript
jquery SweetAlert插件实现响应式提示框
Aug 18 Javascript
JavaScript原生编写《飞机大战坦克》游戏完整实例
Jan 04 Javascript
详解如何在Vue里建立长按指令
Aug 20 Javascript
使用rollup打包JS的方法步骤
Dec 05 Javascript
js回文数的4种判断方法示例
Jun 04 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新手NOTICE错误常见解决方法
2011/12/07 PHP
php遍历文件夹所有文件子文件夹函数代码
2013/11/27 PHP
php中AES加密解密的例子小结
2014/02/18 PHP
php判断是否为ajax请求的方法
2016/11/29 PHP
HTTP头隐藏PHP版本号实现过程解析
2020/12/09 PHP
使用jquery插件实现图片延迟加载技术详细说明
2011/03/12 Javascript
jquery div拖动效果示例代码
2013/12/08 Javascript
js Calender控件使用详解
2015/01/05 Javascript
window.location.reload 刷新使用分析(去对话框)
2015/11/11 Javascript
基于jQuery实现带动画效果超炫酷的弹出对话框(附源码下载)
2016/02/22 Javascript
jquery+CSS3实现3D拖拽相册效果
2016/07/18 Javascript
图解prototype、proto和constructor的三角关系
2016/07/31 Javascript
jQuery解析XML 详解及方法总结
2016/09/28 Javascript
Bootstrap实现带暂停功能的轮播组件(推荐)
2016/11/25 Javascript
关于Function中的bind()示例详解
2016/12/02 Javascript
ES6新特性三: Generator(生成器)函数详解
2017/04/21 Javascript
详解nodejs异步I/O和事件循环
2017/06/07 NodeJs
详解webpack介绍&amp;安装&amp;常用命令
2017/06/29 Javascript
JavaScript中正则表达式判断匹配规则及常用方法
2017/08/03 Javascript
Vue.js 的移动端组件库mint-ui实现无限滚动加载更多的方法
2017/12/23 Javascript
layui文件上传控件带更改后数据传值的方法
2019/09/23 Javascript
JS实现购物车基本功能
2020/11/08 Javascript
[00:42]《辉夜杯》—职业组预选赛12月3日15点 正式打响
2015/12/03 DOTA
详解Python中最难理解的点-装饰器
2017/04/03 Python
Python动态语言与鸭子类型详解
2019/07/01 Python
Python tkinter三种布局实例详解
2020/01/06 Python
Python接口自动化测试的实现
2020/08/28 Python
Jabra捷波朗美国官网:用于办公、车载和运动的无线蓝牙耳麦
2017/02/01 全球购物
美术课外活动总结
2014/07/08 职场文书
中华在我心中演讲稿
2014/09/13 职场文书
工作粗心大意检讨书
2014/09/18 职场文书
校长个人总结
2015/03/03 职场文书
企业法人代表证明书
2015/06/18 职场文书
大学生心理健康教育心得体会
2016/01/12 职场文书
2016优秀护士先进个人事迹材料
2016/02/25 职场文书
Python实现天气查询软件
2021/06/07 Python