详情页
在goodsItem里 加上@click=“itemClick”
在route文件夹index.js里和之前写的一样 复制粘贴path component
这样 点击图片时就会跳转到新的页面详情页 之前views只有四个 新增一个Detail.vue
使用push可以点击浏览器back 回到首页
获取到商品id
导航栏
也封装一下 childComps
接着就要请求
图片轮播展示
所以在network文件夹下新建detail.js 和home.js 一样 都需要引入request.js
然后写上url和参数
import {request} from "./request"
export function getDetail(iid) {
return request({
url:'/detail',
params:{
iid
}
})
}
然后在Detatil里就要面向刚才封装的函数getDetail 所以就导入,然后在created里因为刚才保存了传入的iid,现在就根据iid请求详情数据
和之前一样 写个空数组 保存数据
因为这些图片也是要用轮播图 而且swiper就是公共组件 但是还是封装下 DetatilSwiper
这样比较好找 在这里导入swiper,swiperItem 之前这两个组件又封装在index.js里 这样就更方便一点
然后用props 传轮播图的数据 因为是数组 所以v-for遍历数组 在图片里动态绑定item
ps:如果报错什么node before whice a new node 就是类名重复了 虽然style 是scoped属性 但是如果在swiper里使用的是querySelector的话 那就不知道选择哪个类 就会冲突
点返回重新点击图片 发现详情页没变 iid还是原来的 是因为之前在App.vue里使用了keep-alive 这样created只会调用一次 iid没变 需要每次返回时都重新created 所以在keep-alive 后 exclude="Detail"就好
接着商品标题 价格 之类的
商品信息
因为有很多信息 所以从服务器返回的这么多东西应该先封装到一个类里面
然后再创建类对应的对象 用这个对象传到组件里 这个组件再显示
然后导入Goods
然后根据实际数据名称写
然后使用它 这里绑定goods 是在DetailBaseInfo.vue里的props
样式都在DetailBaseInfo
columns包括销量、收藏
商家信息
如上差不多的
滚动也使用bs
导入注册
然后 因为在scroll组件里 是使用了slot插槽 所以这些 detail就是替换插槽的位置
但scroll 要设置固定高度才能滚动 所以加个类content
有两种方法 一种是定位 一种是calc
这里用calc(100% - 44px) -10px感觉一样
在他的父级元素#detail要 设置高度100vh 这样calc的100%才能实现
同时在滚动是导航栏要显示出来的话 也是用相对定位比较好 因为占位置不会脱标
详情图片
展示DetailGoodsInfo
和之前一样的图片加载完再发生一次imageLoad 不过这里不是用防抖 而是判断图片的个数
评论展示
将时间戳(秒) 转为 时间格式化字符串
Date对象
export function formatDate(date, fmt) {
if (/(y+)/.test(fmt)) {
fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length));
}
let o = {
'M+': date.getMonth() + 1,
'd+': date.getDate(),
'h+': date.getHours(),
'm+': date.getMinutes(),
's+': date.getSeconds()
};
for (let k in o) {
if (new RegExp(`(${k})`).test(fmt)) {
let str = o[k] + '';
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? str : padLeftZero(str));
}
}
return fmt;
}
function padLeftZero (str) {
return ('00' + str).substr(str.length);
}
推荐信息
因为布局和GoodsListItem一样
所以直接用 但有时候接口名称不一样
所以可以在computed计算属性里加判断
比如
原本是show.img 这里推荐里的名称没有show 直接image
详情页滚动和之前滚动一样有的卡
而且推荐数据是使用goodsListItem组件 在里面用load监听图片加载完通过事件总线发射itemImgLoad事件 然后在Home里对这事件监听
所以在详情页里的推荐数据里图片加载完了 要告诉Home 刷新
但是 这里Home不需要刷新 这是共用组件的不好地方
所以需要再判断区分下
也就是发出事件时先if判断下 路径是不是/home 是才发
这是一种思路
也可以都发出itemImageLoad 就是原本的
但是在Home里 当离开Home 时 就取消全局事件监听
但需要传入函数,也就是mounted里的 监听这个事件的函数
这个函数需要抽取出来 再用
在detail里也可以用debounce 然后跟上述一样 不过因为之前keep-alive exclude 了 detail 所以取消全局监听不能用deactived 只能用destroyed 只有keep-alive缓存的才能使用actived和deactivated
既然有代码重复 那肯定要封装一下
(继承是类里面的)
用mixin 混入
在common文件下新建mixin.js
把mounted里的代码剪切过来
然后在detail里导入
同时mixins:[这里放mixin.js里的对象]
在mounted里打印 验证一下
可以打印mixin里的 也可以打印mounted的
然后在home里也是一样的操作
这样打开首页时会打印 mixin-- 点进详情页也会打印 mixin–
deactivated或者destroyed里取消全局事件监听里的函数itemImgListener 也要放进mixin里
mixin里可以放components、methods等
点击图片进入详情页
GoodsListItem 点击 获取商品ID 跳转到详情页 传入$route.params.iid
首页保持状态
deactivated 记录离开时的位置 Y
actived scrollTo 设置Y值
导航栏 返回按钮 slot=“left” slot=“center”
请求数据 接口/detail params:{iid}
轮播图 swiper swiperItem topImages
商品信息 放在一个对象中 Goods {}导入到子组件 new 这个对象
店铺信息 Shop
详情信息 detailInfo
参数信息 paramInfo
评论信息 commentInfo
推荐信息 recommends 使用GoodsList组件
混入 mixin 共享代码
创建混入对象 const mixin = {}
在组件对象中 mixins:[mixin]