基于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 相关文章推荐
jQuery 处理表单元素的代码
Feb 15 Javascript
Javascript倒计时代码
Aug 12 Javascript
js动态设置div的值下例子
Oct 29 Javascript
用js实现in_array的方法
Nov 05 Javascript
js通过更改按钮的显示样式实现按钮的滑动效果
Apr 23 Javascript
使用bootstrapValidator插件进行动态添加表单元素并校验
Sep 28 Javascript
详解jQuery的Cookie插件
Nov 23 Javascript
详解在Vue中通过自定义指令获取dom元素
Mar 04 Javascript
详解微信小程序中的页面代码中的模板的封装
Oct 12 Javascript
two.js之实现动画效果示例
Nov 06 Javascript
jQuery实现的点击显示隐藏下拉菜单功能完整示例
May 17 jQuery
jquery实现烟花效果(面向对象)
Mar 10 jQuery
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
win7安装php框架Yii的方法
2016/01/25 PHP
PHP实现的贪婪算法实例
2017/10/17 PHP
完整显示当前日期和时间的JS代码
2007/09/17 Javascript
js 数组实现一个类似ruby的迭代器
2009/10/27 Javascript
jQuery 表单验证扩展(四)
2010/10/20 Javascript
JS对img进行操作(换图片/切图/轮换/停止)
2013/04/17 Javascript
javascript格式化json显示实例分析
2015/04/21 Javascript
Google 地图API资料整理及详细介绍
2016/08/06 Javascript
JavaScript基于对象去除数组重复项的方法
2016/10/09 Javascript
详解Vue.js——60分钟组件快速入门(上篇)
2016/12/05 Javascript
利用Js+Css实现折纸动态导航效果实例源码
2017/01/25 Javascript
ES6新特性之Symbol类型用法分析
2017/03/31 Javascript
js简易版购物车功能
2017/06/17 Javascript
json2.js 入门教程之使用方法与实例分析
2017/09/14 Javascript
javaScript手机号码校验工具类PhoneUtils详解
2017/12/08 Javascript
Vue EventBus自定义组件事件传递
2018/06/25 Javascript
angular1.x ui-route传参的三种写法小结
2018/08/31 Javascript
Angular4.x Event (DOM事件和自定义事件详解)
2018/10/09 Javascript
JS立即执行函数功能与用法分析
2019/01/15 Javascript
详解超简单的react服务器渲染(ssr)入坑指南
2019/02/28 Javascript
js取0-9随机取4个数不重复的数字代码实例
2019/03/27 Javascript
jquery实现选项卡切换代码实例
2019/05/14 jQuery
LayUi数据表格自定义赋值方式
2019/10/26 Javascript
TypeScript之调用栈的实现
2019/12/31 Javascript
vue+element实现图片上传及裁剪功能
2020/06/29 Javascript
在Mac OS上搭建Python的开发环境
2015/12/24 Python
对numpy和pandas中数组的合并和拆分详解
2018/04/11 Python
对python多线程中Lock()与RLock()锁详解
2019/01/11 Python
关于多种方式完美解决Python pip命令下载第三方库的问题
2020/12/21 Python
联想法国官方网站:Lenovo法国
2018/10/18 全球购物
金融专业推荐信
2013/11/14 职场文书
会计自荐书
2013/12/02 职场文书
迷你西餐厅创业计划书范文
2013/12/31 职场文书
2014年小学体育工作总结
2014/12/11 职场文书
php字符串倒叙
2021/04/01 PHP
用CSS3画一个爱心
2021/04/27 HTML / CSS