详情页实现思路

点击商品进去详情页,根据点击请求更加详细的信息,要传过来goodsItem的iid,根据id去服务器请求更加详细的信息;配置路由映射关系,点击进行跳转,带参数传递跳转。
在GoodsListItem中

itemClick(){this.$router.push('/detail/'+this.goodsItem.iid)/* this.$router.push({path:'/detail',query:{iid:this.goodsItem.iid}}) */}

但是获取到的iid在更换点击商品时没有改变,并没有发生新的请求,因为发生了路由跳转,router-view由keep-alive包着,不会每次销毁并重新创建,所以不会给iid给新的值,详情页不要使用keep-alive,使用exclude属性

<keep-alive exclude="Detail"><router-view></router-view>
</keep-alive>

首页的位置保持不变

指定版本安装better-scroll npm install better-scroll@1.13.2 --save
用keep-alive标签把router-view标签包住,点击其他导航栏,再点击首页,自动回到顶部,不是因为创建了新的Home.vue,获取离开时滚动的位置,再次进入的时候设置保存的位置。【频繁切换还是会自动回到顶部???】

导航栏的封装

1.在childComps中创建组件DetailNavBar.vue,在组件中引入公共组件TabBar,替换TabBar组件中的插槽,在详情页Detail中引入封装好的导航栏DetailNavBar,
2.引入一个返回图标,绑定点击事件,点击之后会返回到之前进入的状态
3.将导航栏中的标题定义成数组titles然后遍历,进行flex布局
4.标题点击谁,谁就变成红色
** 定义一个当前索引currentIndex,动态绑定class,动态绑定点击事件 【此处是否可以直接引入tabControl组件??】

加入滚动的效果Scroll

1.指定版本安装better-scroll npm install better-scroll@1.13.2 --save
2.详情页的底部导航栏NavBar不用展示,可以给详情页相对布局并设置层级关系,给一个白色的背景色,详情页就可以脱离原来的标准流,把底部导航栏隐藏了
3.顶部的导航栏在DetailNavBar组件中设置相对定位层级关系和背景颜色
4.仍然选择better-scroll,引用之前封装好的Scroll,把要滚动的东西用scroll包裹住,替换Scroll里面的插槽
5.scroll需要有固定的高度,让父元素有100%的视口高度

一、滚动的问题

推荐数据使用goodslistitem展示时,用了load监听,图片加载完了会通知首页,但是我们不需要通知首页。我们需要区分。发出事件的时候做一下路由判断。

imageLoad(){if(this.$router.path.indexOf('/home')){this.$bus.$emit('homeItemImageLoad')} else if(this.$router.path.indexOf('/detail')){this.$bus.$emit('detailItemImageLoad')}},

再在详情页监听图片是否加载完成,但是最后离开的时候还是要取消

详情数据请求

1.保存从首页商品展示传入的iid
2.根据iid请求详情数据
** 在network的detail.js中封装getDetail,发出网络请求

一、轮播图的封装

  • 在childComps中创建组件DetailSwiper.vue,在组件中引入公共组件Swiper,SwiperItem,在详情页Detail中引入封装好的DetailSwiper
  • 根据请求到的数据topImages轮播展示商品,定义了一个变量,把topImages进行保存,图片太大了,给swiper设置固定的高度

二、商品基本信息的封装

  • 抽离组件需要的数据,再把抽离的数据传给组件,把杂乱的数据整合成一个对象,导出class类对象Goods保存的一些商品信息
  • 在childComps中创建组件DetailBaseInfo.vue,封装一些商品基本信息,在详情页Detail中引入封装好的DetailBaseInfo
    • 要先判断是否有商品信息,有再渲染,怎么判断呢?
    • v-if="Object.keys(goods).length !== 0" 看goods是不是一个空的对象

三、商家基本信息的封装

  • 导出class类对象Shop保存的一些商品信息
  • 在childComps中创建组件DetailShopInfo.vue,封装一些商家信息,在详情页Detail中引入封装好的DetailShopInfo
  • 在显示总销量时,有个过滤器
filters: {sellCountFilter: function (value) {if (value < 10000) return value;return (value/10000).toFixed(1) + '万'}}

四、商品详情的封装

  • 在childComps中创建组件DetailGoodsInfo.vue,封装一些商品详细信息,在详情页Detail中引入封装好的DetailGoodsInfo
  • 在滚动的过程中,可能出现不能滚动的现象,是因为better-scroll在计算滚动区域时,图片还没加载出来,所以需要先监听图片是否加载完成
    • 首页要获取图片的个数,然后定义一个计数变量,当两者相等时,就可以发出图片加载完成的事件,
    • 在详情页面中,对滚动区域进行刷新
// 监听detailInfo这个对象的变化watch:{detailInfo(){//获取图片的个数this.imageLength=this.detailInfo.detailImage[0].list.length}},methods: {imageLoad(){// 先判断一下,只发出一次事件,不然有几张图片就发出几次事件// 所有的图片都加载完成之后,进行一次回调if(++this.counter===this.imageLength){this.$emit('imageLoad')}}},

五、商品参数的封装

  • 导出class类对象GoodsParam保存的一些商品参数信息
  • 在childComps中创建组件DetailParamInfo.vue,封装一些商品参数信息,在详情页Detail中引入封装好的DetailParamInfo
  • 参数用table布局

六、商品评论信息的封装

  • 评论信息的获取
    ** 在接口的result->rate里面
    ** cRate 当前商品一共有多少评论 点击更多按钮跳转到另一个页面 展示更多评论信息
    ** list[0] 取出一条评论信息在详情页进行展示
    ** 定义commentInfo对象 保存取出来的评论信息 有可能没有评论信息 先判断
  • 评论信息的展示
    ** 在childComps中创建组件DetailCommentInfo.vue,封装一些评论信息,在详情页Detail中引入封装好的DetailCommentInfo
    ** 过滤器将时间格式化 formatDate 从utils中引入
filters: {showDate: function (value) {// 将时间戳转成Date对象let date = new Date(value*1000);// 将date进行格式化return formatDate(date, 'yyyy/MM/dd')}}

七、商品推荐信息的封装

  • 推荐数据的获取
    ** 在detail.js中弄一个接口,不用传参数
export function getRecommend() {return request({url: '/recommend',})
}

** 在详情页中将接口函数导入,定义一个recommends数组,在created中请求推荐数据

  • 推荐数据的展示
    ** 不需要创建一个新的子组件,可以直接用之前的GoodsList组件,
    ** 在详情页中导入GoodsList组件并注册使用
    ** 弄个计算属性computed,取展示的图片数据

首页和详情页监听全局事件的mixin的使用

** mixin 混入

底部工具栏

一、底部工具栏的封装

二、将商品添加到购物车

** 1.给“加入购物车”添加点击事件,发送一个事件,因为是在子组件中监听,

<div class="cart" @click="addToCart">加入购物车</div>
methods: {addToCart(){this.$emit('addCart')}},

** 2.在详情页中监听点击,先获取商品的信息,这些信息要展示在购物车页面中;

<detail-bottom-bar @addCart="addToCart"/>addToCart(){// 1.获取购物车需要展示的信息const product={}product.image=this.topImages[0]product.title=this.goods.titleproduct.desc=this.goods.descproduct.cartPrice=this.goods.cartPriceproduct.iid=this.iid}

** 3.将商品添加进购物车,在详情页将商品添加到某个位置,在购物车界面将信息进行展示,用到vuex管理购物车数据

三、将商品添加到store中

** 0.安装vuex npm install vuex --save
** 1.在文件夹store中新建一个文件,导入vue,vuex,安装插件,创建store对象,挂载到Vue实例上,在main.js中导入store
** 2.定义一个数组变量cartList在其中存放商品,修改任何state中的状态都要通过mutations,mutations中每一个方法完成的事件尽可能单一。
在index.js中

const store = new Vuex.Store({state:{cartList: []},mutations:{addCart(state,payload){state.cartList.push(payload);}}
});

在Detail.vue中

addToCart(){// 2.将商品添加到购物车//这样做不好,修改vuex中的数据要通过mutations//this.$store.cartList.push(product);this.$store.commit('addCart',product)
}

此时应该做一个判断,如果添加的是同一个商品的话,cartList的长度不应该变化,而是变化数量。
用iid来判断。将一个商品添加进购物车,需要根据iid来判断它是不是在原来的cartList里面,如果是,则把该商品数量加1,如果不是,则添加进cartList里面。

mutations:{addCart(state,payload){let oldProduct=null;for(let item of state.cartList){if(item.iid===payload.iid){oldProduct=item;}}// 判断oldProductif(oldProduct){oldProduct.count+=1;}else{payload.count=1;state.cartList.push(payload);}}},
[ADD_COUNTER](state, payload) {payload.count++;},
[ADD_TO_CART](state, payload) {state.cartList.push(payload);}

** 3.逻辑判断在actions中

addCart(context, payload) {// 1.查找之前的数组中是否有该商品let oldProduct = context.state.cartList.find(item => item.iid === payload.iid);// 2.判断oldProductif (oldProduct) {context.commit(ADD_COUNTER, oldProduct);} else {payload.count = 1;context.commit(ADD_TO_CART, payload);}}

四、添加购物车弹窗


1.在components的common文件夹中新建一个toast文件夹,因为还可以在其他项目中使用,创建一个Toast组件,
2.让弹窗垂直水平居中布局,
3.控制弹窗的显示和隐藏,v-show定义一个变量isShow,默认不显示,属性值设置为false,还定义个弹窗显示内容的变量message,点击“加入购物车”后显示,过一会儿就隐藏,使用定时器
4.在Detail组件中导入,注册并使用
5.点击“加入购物车”后显示,过一会儿就隐藏,使用定时器

if (oldProduct) {context.commit(ADD_COUNTER, oldProduct);resolve('当前的商品数量+1')} else {payload.count = 1;context.commit(ADD_TO_CART, payload);resolve('添加购物车成功')}
this.$store.dispatch('addCart',product).then(res=>{this.isShow=true;this.message=ressetTimeout(() => {this.isShow=false;this.message=''}, 1500);

另一种封装:
0.把这个组件封装在一个插件里面,先创建这个组件,最开始的时候就把这个组件添加进body里面,然后安装这个插件,安装这个插件就预备好了
1.在main.js文件里面导入toast,安装插件,执行install函数,

import toast from "components/common/toast"
// 安装toast插件
Vue.use(toast)

2.在toast文件夹里面新建index文件,在index中导入Toast组件,在install函数里面把需要的东西预备好

obj.install=function(Vue){// 1.创建组件构造器const toastContrustor = Vue.extend(Toast)// 2.new的方式,根据组件构造器,可以创建一个组件对象const toast = new toastContrustor()// 3.将组件对象,手动挂载到某一个元素上toast.$mount(document.createElement('div'))// 4.toast.$el对应的就是divdocument.body.appendChild(toast.$el)Vue.prototype.$toast = toast
}

3.在Toast组件中写一个show方法

data(){return{message:'',isShow:false}
},
methods: {show(message,duration=2000){// duration=duration || 3000this.isShow=true;this.message=messagesetTimeout(() => {this.isShow=false;this.message=''}, duration);}
}

4.在Detail组件中调用show方法

this.$store.dispatch('addCart',product).then(res=>{this.$toast.show(res,2000)})

Vue商城——详情页功能相关推荐

  1. 高仿淘宝和聚美优品商城详情页实现《IT蓝豹》

    高仿淘宝和聚美优品商城详情页实现 android-vertical-slide-view高仿淘宝和聚美优品商城详情页实现,在商品详情页,向上拖动时,可以加载下一页. 使用ViewDragHelper, ...

  2. vue ---05 分页和详情页功能的实现

    课程列表页 分页显示数据 rest_framework 里面封装了有分页功能的组件,直接可以拿来即用 在courses/views.py 中新建一个分页器类 (类的嵌套) from rest_fram ...

  3. Vue.js框架简单读取数据库信息并渲染完成news新闻文章列表以及detail详情页功能(小试牛刀)

    项目结构 news.html(新闻列表文件) <!doctype html> <html lang="en"> <head><meta c ...

  4. vue实现商品详情页功能之商品选项卡

    用户点击商品进入商品详情页,默认显示第一个小图对应的大图,然后鼠标滑到小图上,大图也会发生改变,实现效果如下: 实现代码: shopitem.vue的template(HTML),上面是大图,下面是小 ...

  5. vue页面详情页返回列表页_vue列表页进入详情页,返回列表项不刷新

    功能 像搜索功能,在点击某项进入详情页,再回到搜索界面,如果不做特殊处理,初始化到原来的状态,在vue中可以使用keep-alive缓存搜索界面,达到数据不刷新的结果. 思路 在搜索路由对象的meta ...

  6. vue页面详情页返回列表页_vue 详情页返回列表页,保留列表页之前的筛选条件...

    需求背景 再列表页进行一系列的筛选条件之后,点击某一个进入详情页,当从详情页返回列表页的时候,需要保留之前的筛选条件. 之前的实现方法 路由跳转的时候,把筛选条件json对象放到query中去,传到详 ...

  7. vue实现详情页返回列表页,数据不加载且页面原有位置不变

    常见的需求: 列表页 ====>点击跳转到列表详情页面 ======> 返回列表页(希望页面不重新加载,且保留原来浏览的位置). 1.实现页面的不重新加载 使用vue的keep-alive ...

  8. 前端Vue书籍翻页功能利用turn.js来完成以及知识点(源码)

    目录 下载 文档 开始 构造方法 可配置项 方法 语法 事件 两种方式添加事件 自动翻页loading加载功能 案例 CSS basic.css源码如下 JS里面代码太多了,直接官网下载 index. ...

  9. 【vue】详情页数据请求

    项目场景: 请求详情页数据 问题描述 请求不到,log没有打印 控制台报错 debugg过程 读报错信息 detail.js?c28a:3 Uncaught (in promise) TypeErro ...

最新文章

  1. PCA、碎石图、PCA+正确的维度个数、增量PCA(IncrementalPCA)、随机PCA(Randomized PCA)、KernelPCA
  2. ubuntu安装 ftpd server(vsftpd)
  3. python内建时间模块 time和datetime
  4. ubuntu下查看进程端口
  5. ibatis的简介与初步搭建应用
  6. python中以下关于列表描述错误的_10. 以下关于列表操作的描述,错误的是:_学小易找答案...
  7. 玩转DB里的数据—阿里云DMS任务编排之简介和实操
  8. 设计模式学习笔记——代理(Proxy)模式
  9. asp.net oracle 问号,ASP.NET中文变问号问题解决方案
  10. IIS URLReWrite URL 重写模块 下载地址
  11. [六省联考2017]分手是祝愿
  12. 数据结构与算法python语言描述第三章课后答案_《数据结构与算法Python语言描述》习题第二章第三题(python版)...
  13. Windows 内核会换为 Linux 吗?
  14. fat,uat,pre等环境含义
  15. Windows XP精简版无添加删除组件选项而无法安装IIS的解决之道
  16. Spring中的AOP原理
  17. [wp] HITB CTF 2017 website
  18. Xmind 8 pro 软件破解版
  19. 发qq邮件被对方服务器拒绝,QQ被对方拉黑了。我发QQ邮件对对方能收到吗?
  20. html中padding在ie8兼容性,怎么解决bootstrap在各版本IE浏览器中的兼容性问题?

热门文章

  1. 《ABP Framework 极速开发》 - 教程首发
  2. 北京龙泉寺,学霸寺院,低于985好意思进吗?
  3. 哔哩哔哩html5播放器,哔哩哔哩(Bilibili)播放器扩展_v2.0.4
  4. 如何在Android Studio里下载模拟器
  5. 第四战,三打祝家庄(注意,此三打是统称一打、二打、三打祝家庄这几仗)
  6. 企业级监控平台如何选择?
  7. 【哈佛积极心理学笔记】第2讲 为什么要学习积极心理学
  8. 有向图强连通分量的Tarjan算法
  9. 汽车与生活方式:3D打印机彩色部件系列
  10. Arxiv论文速览--LAformer: Trajectory Prediction for Autonomous Driving with Lane-Aware Scene Constraints