Vue开源项目记录二

本文记录了Vue项目中详情页的开发过程,包括通过路由动态跳转实现详情页,构建导航栏,轮播图展示,商品信息与商家店铺信息的处理,评论信息展示,推荐栏展示以及导航联动和回到顶部功能的实现。涉及到组件复用、数据提取、事件监听、DOM操作等技术。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Vue项目开发二-详情页

  1. 详情页跳转

    项目需求:点击首页商品,跳转到商品的详情页

    项目实现

    —通过路由跳转实现详情页的切换,另外点击事件需要绑定在商品列表项目GoodsItemList组件上;

    —因此需要在路由映射文件下创建详情页的映射,并且这里需要注意我们使用的是动态跳转路由,因为需要携带id信息,方便请求不同详情页的数据信息;

    —这里通过push完成路由跳转,因为需要通过back返回首页;

  2. 详情页导航栏

    项目需求:详情页导航栏,包括商品的相关参数和一个返回首页的图标;

    项目实现

    —复用之前我们封装的顶部导航组件,这里可在data()中传入导航内容;

    —分别为导航内容和返回首页图标添加点击监听事件,实现点击样式的改变和路由跳转this.router.back()返回首页的效果;

  3. 详情页轮播图

    项目需求:详情页中实现轮播图效果

    项目实现

    —设计网络请求函数,从服务器请求详情页相关数据信息,这里需要注意要运用动态跳转路由,不同详情页携带不同id,请求到的数据也有所不同;因此路由映射中设置动态路由:path:'/detail/:id';根据跳转路由的id信息请求不同详情页的数据;

    —详情页数据解构分析,我们一般请求到数据结构十分复杂,需要对请求到的数据进行结构分析,拿到我们所需要的数据信息;

    —这里轮播图复用轮播图组件,并通过props拿到详情页组件请求到的数据;

    —这里需要注意,之前包裹动态组件,在进行组件切换过程中将状态缓存,更好的实现DOM渲染;在详情页中,我们点击商品需要跳转到不同的详情页,所以需要通过exclude属性指定详情页不进行状态缓存,每次都需要重新创建组件;如果缓存或者不缓存没有生效,需要在路由映射中添加name属性,可能还需要添加meta属性:meta:{keepAlive:false/true}表示不被缓存/缓存;

  4. 商品基本信息和商家店铺信息展示

    项目需求:商品的详细信息和相关价格描述,商家店铺信息的展示

    项目实现

    这两个组件的实现重点在于:数据提取整合!!

    —这里网络请求的数据需要进行提取处理,不同信息整合为一个对象,传递给我们封装的商品展示组件,这样方便组件开发的过程中只面向一个对象实现数据信息的展示;面向类开发:这里我们把多个数据封装到类里面,这样可以实现一个类封装多组数据,创建类对象,让组件面向类对象实现数据处理!!

    v-for语法:可以使用数字进行遍历,例如:v-for = "n in 10"这样会产生1-10的数字;

    —如何判断对象是空对象,可以使用Object.keys判断是否存在键:Objec.keys(onj).length === 0

  5. 详情页商品页详细展示

    项目需求:详情页下拉商品的详细展示

    项目实现

    —请求数据进行组件封装即可,这里涉及的重点是图片加载完毕后,滚动长度的计算,在之前轮播图中设计的图片加载完毕实现滚动条长度计算,只需要监听轮播图中一张图片的加载,这里我们需要将所有的图片加载都进行监听,因为它是竖向展示!

    —为了减少回调函数向父组件的传递,需要进行一次判断,判断所有图片都加载完毕后,传递回调,设置计数器,计数图片加载次数,当加载次数等于图片长度,说明加载完毕,这样传递回调即可:

    if(++this.counter === this.imagesLength)

    —图片长度的获取:因此数据默认传递的是空值,获取的数值是0,我们可以通过watch进行监听数据变化,当网络请求数据后(create生命周期中数据请求完成后),再获取请求完毕后最新的图片列表的大小;

    watch:{detailInfo(){this.imagesLength = this.detailInfo.detailImage[0].list.lenght}}

  6. 详情页评论信息展示

    项目需求:实现用户评论信息的展示

    项目实现

    —重点是评论时间的显示,向服务器请求返回时间不会是2021/11/23这种形式进项展示的,它是以Unix时间元年为起点,返回对应的时间戳;因此这里需要将时间戳转换为时间格式化字符串!

    时间戳转换为时间格式化字符串

    【1】将时间戳转换为Date对象:const date = new Date(时间戳*1000),注意这里时间戳是以秒为单位,date是以毫秒为单位!!

    【2】将date格式化转换为对应的字符串,因为转换十分常用,已经封装为一个函数,分别传入date和格式化形式:fmt.format(date,'yyyy-MM-dd hh:mm:ss'),其中y表示年份,M表示月份,d表示日,h(12小时制)/H(24小时制),m表示分钟,s表示秒钟;这里是Java中提供的一种转换方式,原生JS中没有提供,可以自己封装一个时间戳格式化转换函数或者使用插件jutils-src、dayjs;

    —在我们这个项目中,我们可以将时间戳转换为格式化字符串封装在过滤器中,在时间显示上使用过滤器进行时间戳转换;但是Vue3中已经移除了filters

  7. 详情页推荐栏的展示

    项目需求:详情页中推荐栏的展示,类似于首页的推荐栏展示;

    项目实现

    —这里直接使用首页推荐栏的组件GoodList实现详情页的推荐栏展示,但是由于首页推荐栏组件进行了@load监听,图片加载完毕后通过事件总线向Home组件传递一个监听事件,而现在我们需要在详情页中图片加载完成后,将事件不应该传递给Home,在详情页下应该将事件提交给详情页;

    思路一:通过判断当前活跃路由实现不同跳转:

    imgLoad(){
     if(this.$route.path.indexOf('/home')){
         this.$bus.$emit('homeItemImagLoad')
     }else if(this.$route.path.indexOf('/detail')){
         this.$bus.$emit('detailItemImagLoad')
     }
    }
    

    思路二:在首页离开的生命周期函数中取消首页中事件总线里图片监听事件,this.$bus.off('itemImgLoad',this.itemImgListener),这里需要注意不能直接传入监听事件,这样的话就取消所有页面下的改监听事件,需要传入哪个函数下的监听事件进行取消;

    mixin混入:官方表述,Mixin 提供了一种非常灵活的方式,来分发Vue组件的可复用功能。一个 mixin 对象可以包含任意组件选项。当组件使用 mixin 对象时,所有 mixin 对象的选项将被“混合”进入该组件本身的选项。

    因为这里首页和详情页都有使用图片加载监听事件,可以使用mixin混入实现抽取,完成组件复用能能;

  8. 详情页导航联动效果

    项目需求:点击详情页导航可以跳转到对应的页面,或者页面滚动到一定位置,跳转对应的导航标题,实现导航标题与内容的联动

    项目实现

    点击标题,滚动到对应的主题内容:通过导航组件传递出来的点击事件,在点击事件中实现点击对应的导航标题,this.$refs.scroll.scrollTo()滚动到对应主题内容的位置,可以通过滚动条offsetTop属性获取滚动位置;

    —获取滚动位置offsetTop的大小:这里需要在图片加载完毕获取滚动大小,

    【1】created函数中不能获取DOM元素,未挂载;

    【2】mounted函数中,挂载完毕DOM元素,但是数据未更新,数据获取不到;

    【3】在获取数据的回调函数也不行,因为DOM未渲染完毕;

    【4】因此需要将计算函数放在updated生命周期函数中,此时数据更新完毕,完成虚拟的DOM的渲染和打补丁,组件DOM已完成更新,可以执行依赖DOM的操作,但是此时获取的依旧是图片未加载的数据;另外,需要注意,每次更新都需要清空数组,否则会将更新的数据不断拼接在数组后面;

    this.nextTick():无法直接在created周期函数中获取DOM相关数据,如果要在此阶段实现DOM操作,要放在nextTick()回调函数中,因为created初始化数据后,不会立即更新数据,需要进行渲染后在更新DOM, 因此无法在created函数中获取到相关值,必须等到渲染完毕获取值, 可以使用nextTick等到DOM渲染完毕回调函数;

    —需要注意:在上述nextTick中获取滚动位置依旧不正确,因为虽然拿到最新数据,DOM渲染完毕,但是图片依然没有加载完成,所以目前获取的是未加载图片的数据!!

    —最终获取高度:在图片加载完毕监听事件中获取offsetTop的值,这里可以对获取函数实现防抖操作,避免图片加载多次请求;

    滚动到主题内容,导航切换对应的主题项

    —这里需要需要监听滚动事件,并通过判断当前滚动位置与对应的导航索引进行判断,实现主题项的切换;

    —由Scroll组件传递出的滚动监听事件下,获取当前的y值,注意这里要取负值,因为滚动监听获取的值是负数;

    —对当前y值与对应索引进行映射,并通过this.$refs.nav.currentIndex = this.currentIndex将当前索引传递给导航下的索引;

    —判断条件,hack方案:在进行相邻区间判断时,为了防止遍历索引溢出,我们可以分两步判断,最后一项单独判断;但是这种判断很繁琐,因此可以在数组最后一项后面添加一个最大值Number.MAX_VALUE,将判断合并判断;

    for(let i = 0;i<this.themeTopYs.length-1;i++){
     if((this.currentIndex !== i) && (positionY >= this.themeTopYs[i] && positionY < this.themeTopYs[i+1]))
    }
    
  9. 回到顶部混入封装

    项目需求:因为返回顶部在首页和详情页都有用到,可以进行混合封装,实现组件的可复用;

    项目实现

    —将组件可复用功能和共同数据抽取h饿放置mixin.js文件中实现封装;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值