Vue2电商项目(四) Detail模块

news2024/9/24 19:54:42

文章目录

  • 一、配置Detail路由
    • 1. 将Detail组件配置为路由组件
    • 2. 将路由配置文件拆分
    • 3. 声明式导航跳转到Detail
      • 跳转时存在的问题:页面滚动条还在下边
  • 二、配置API及vuex
  • 三、放大镜及下方轮播图
    • 1. Detail组件传递放大镜数据
    • 2. 读取vuex数据的经典错误undefined
    • 3. 放大镜放大效果
    • 3. 放大镜下方的轮播图
      • 数据
      • 轮播图
      • 点击高亮
    • 4. 放大镜与轮播图联动
  • 四、 选择售卖属性
    • 1. 渲染页面
    • 2. 排他思想
  • 五、购买产品个数的加减操作

一、配置Detail路由

1. 将Detail组件配置为路由组件

在这里插入图片描述
当点击某个商品调转到详情页时,需要将这个商品的id传递过去。所以这里配置了params占位。

2. 将路由配置文件拆分

就是将路由配置项里的内容提取到另一个文件中,这样更清晰。
在这里插入图片描述

3. 声明式导航跳转到Detail

Search组件中,将原来的a标签替换为router-link,记得携带params参数,将商品Id传过去。
在这里插入图片描述


在跳转路径上可以检查传递的参数是否正确:
在这里插入图片描述

跳转时存在的问题:页面滚动条还在下边

正常情况,跳转到新页面时,应该处于新页面的最前面。
从图中可以看出,页面跳转前滚动条处于底部。页面跳转后滚动条还是处于底部。所以这是个问题:
在这里插入图片描述

解决方法:查看官网:滚动行为
在这里插入图片描述
在路由配置里添加一个新的配置项:

// router/index.js
export default new VueRouter({
  routes,
  scrollBehavior (to, from, savedPosition) {
    // return 期望滚动到哪个的位置
    return { y: 0 }
  }
})

二、配置API及vuex

根据接口文档,写获取商品详情的api

//api/index.js
// 获取商品详情 url:/api/item/{商品id} 请求方式 get
export const reqGoodsInfo = (goodsId) => {
  return requests({ url: `/item/${goodsId}`, method: 'get' })
}

获取来的数据依然是存在仓库里,detail又是一个模块。建立detail小仓库存储这个模块的信息

// store/detail/index.js
import { reqGoodsInfo } from "@/api";

export default {
  namespaced: true,
  state: {
    goodsInfo: {}
  },
  actions: {
    async getGoodsInfo (context, goodsId) {
      const result = await reqGoodsInfo(goodsId)
      if (result.code === 200) {
        context.commit('GETGOODSINFO', result.data)
      }
    }
  },
  mutations: {
    GETGOODSINFO (state, goodsInfo) {
      state.goodsInfo = goodsInfo
    }
  },
  getters: {  }
}

不要忘记把这个小仓库放在大仓库里
在这里插入图片描述

三、放大镜及下方轮播图

1. Detail组件传递放大镜数据

在vuex中,通过getters简化获取到goodsList里的skuInfo。Detail组件获取到后,将该信息传递给子组件Zoom

// store/detail/index.js
getters: {
  skuInfo (state) {
    return state.goodsInfo.skuInfo
  }}

左边Detail父组件,右边Zoom子组件.(这里先写死数据,后续再改)
在这里插入图片描述

2. 读取vuex数据的经典错误undefined

在这里插入图片描述
问题:根据提示可知是Zoom组件里的skuImageList[0]有问题。skuImageList是父组件传递的。经过mounted函数测试发现,父组件传递过来的是undefined

因为请求数据是异步操作,如果还没有数据,getters中的数据skuInfo返回的是空对象。去读空对象身上的属性,则会报错为undefined。所以skuInfo.skuImageList是undefined。

解决

<!--如果不存在这个数据,就给子组件Zoom传递一个空数组-->
 <Zoom :skuImageList="skuInfo.skuImageList || []" />

然后又报错
在这里插入图片描述

在Zoom组件中读取了skuImageList[0].imageUrlskuImageList是空数组,那么skuImageList[0]就已经是undefined了 ,所以读取imageUrl也会报错了。

在这里插入图片描述
解决
思路同上,这里给一个空对象

// Zoom组件
 computed: {
   imgObj () {
     return this.skuImageList[0] || {}
   }
 }

在这里插入图片描述

3. 放大镜放大效果

offsetX:鼠标坐标到元素的左侧的距离
offsetY:鼠标坐标到元素的顶部的距离
offsetLeft: 元素与定位父级元素的左侧的距离
offsetTop:元素与定位父级元素的顶侧的距离
offsetWidth: 元素自身宽度(width + padding+border)
offsetHeight: 元素自身高度 (height + padding+border)

回顾博客:WebAPI(二) offset
在这里插入图片描述

这里主要包含两个步骤:
(1)、鼠标移动,mask跟着移动
(2)、右侧的放大效果实时变化

首先给mask加一个鼠标移动事件,为了后续方便对节点操作,同时加上ref属性。(为什么给event加鼠标移动事件?)
在这里插入图片描述
具体业务逻辑看代码吧,结合注释计算一下,注意不要忘了修改属性的时候加单位px
处理第二个步骤时,需要注意,鼠标的移动与右侧大图呈现的方向是相反的。所以要加负号(加负号注意)。

<script>
  handlerMask (event) {
    // 1. 获取mask节点
    let mask = this.$refs.mask

    // 2. 修改位置,不要忘了加单位!(可以用鼠标的位置是因为鼠标总位于mask    的中心)
    let x = event.offsetX - mask.offsetWidth / 2  // x水平方向,确定位置,看左侧
    let y = event.offsetY - mask.offsetHeight / 2 // y垂直方向,确定位置,看上边

    // 3. 加限制
    if (x < 0) x = 0 // 小于0,mask就从左边出去了
    if (x > mask.offsetWidth) x = mask.offsetWidth // mask的宽是父级元素的一半,如果x坐标超过了这一半,说明右边出去了

    if (y < 0) y = 0 // 小于0,mask就从下边出去了
    if (y > mask.offsetHeight) y = mask.offsetHeight // mask的高是父级元素的一半,如果y坐标超过了这一半,说明上边出去了


    // 4. 修改绿色mask的位置 
    mask.style.left = x + 'px'
    mask.style.top = y + 'px'

    // 放大图的地方
    let big = this.$refs.big
    big.style.top = -2 * y + 'px'
    big.style.left = -2 * x + 'px'
  }
 </script>

3. 放大镜下方的轮播图

回顾之前做过的轮播图(和之前的有点不一样(同时展示三张图片),所以这里不用当初定义的全局组件了):Vue2电商项目(二)、Home模块轮播图

在这里插入图片描述

数据

由于这里用到的数据和Zoom(放大镜)一样,所以同样由Detail组件传递给ImageList组件。

 <!-- Detail组件,小图列表 -->
 <ImageList :skuImageList="skuInfo.skuImageList || []" />

轮播图

引包、引样式、创建实例。创建实例仍然在watch中。
在这里插入图片描述
注意v-for应该加在哪,ref应该加在哪!!!

  watch: {
    // 监听数据:可以保证数据一定ok,但是不能保证v-for遍历结构是否完事儿
    //监听skuImageList数据的变化,会有一个从空数组变成有数据的过程(一切都因为请求数据是一个异步操作)
    skuImageList () {
      this.$nextTick(() => {
        new Swiper(this.$refs.mySwiper, {
          // 如果需要前进后退按钮
          navigation: {
            nextEl: '.swiper-button-next',
            prevEl: '.swiper-button-prev',
          },
          slidesPerView: 3, // 设置能够同时显示的slides数量
          slidesPerGroup: 1, // 每一次切换图片的个数
        })
      })
    }
  }

点击高亮

不用css,改用js实现点击高亮效果。这个和TypeNav组件里的情况一致。
高亮时,添加active这个class类。
在这里插入图片描述

  <div
    class="swiper-slide"
    v-for="(slide, index) in skuImageList"
    :key="slide.id"
  >
    <img
      :src="slide.imgUrl"
      :class="{ active: currentIndex === index }"
      @click="changeCurrentIndex(index)"
    />
  </div>
 <script>
	 data () {
	   return {
	     currentIndex: 0 // 默认是第0张图
	   }
	 },
	 methods: {
	   changeCurrentIndex (index) {
	     this.currentIndex = index
	   }
	 },
 </script>

4. 放大镜与轮播图联动

点击轮播图里的某张图,放大镜的主图里就展示某张图。很明显,这两个组件是兄弟组件,所以涉及到组件间通信。采用全局事件总线的方式。

传递数据:ImageList组件,传递的是被点击的图片对象的id。
接收数据:Zoom组件。

在这里插入图片描述
ImageList组件中用到了之前高亮写的函数。当点击图片时,显示高亮,并通过事件总线 将该图片的索引值传递过去。
在这里插入图片描述

四、 选择售卖属性

在这里插入图片描述

1. 渲染页面

在这里插入图片描述

// vuex小仓库里
getters: {
  spuSaleAttrList (state) {
    return state.goodsInfo.spuSaleAttrList || []
  }
}

在这里插入图片描述

2. 排他思想

需求:点击某一个属性时,该属性高亮,其他属性都是灰的。
在这里插入图片描述

排他思想:(有同一组元素,想要某一个元素实现某种样式,需要用到循环的排他思想)
(1) 所有的元素全部清除样式(干掉其他人)
(2) 给当前元素设置样式(留下自己)
(3) 注意顺序不能颠倒,首先干掉其他人,再设置自己。
参考博客:JS排他思想

添加点击事件:
在这里插入图片描述
数据结构:

[
// 第一个属性
 {
  id:1
  saleAttrName:'颜色'// 属性值对象数组
  spuSaleAttrValueList:[
    {id:1,valueName:'亮黑色',isChecked:'0'},
    {id:2,valueName:'粉色',isChecked:'1'},
    {id:3,valueName:'白色',isChecked:'1'},
  ]
 },
 //第二个属性
...
]

思路分析: 首先要获取到当前选中的元素对象(比如值为白色的对象),给该对象的isChecked赋值,使其高亮。其次还要获取到这个元素对象所在的数组(即spuSaleAttrValueList),对该数据里的其他对象进行遍历,将isChecked赋值,使其不高亮。

methods: {
  // 售卖属性的排他操作
  // 第一个参数是选中的对象,第二个是这个对象所在的数组
  changeActive (currentValue, spuValueList) {
    spuValueList.forEach(el => {
    // 先都赋值为0,不高亮
      el.isChecked = '0'
    });
    // 选中的赋值为1,高亮
    currentValue.isChecked = '1'
  }
}

五、购买产品个数的加减操作

需求:点击+:数字加1;点击-:数字减1;输入框里可输入产品数量。
在这里插入图片描述
data里定义商品数量属性skuNum,默认值是1;+和- 需要注意的就是减的时候商品数量不能小于1。
在这里插入图片描述
输入框的回调函数里需要处理用户一些非法的输入。非法输入有这样几种情况:输入文本,负数,小数;

 // 改变商品个数
 changeSkuNum (e) {
   // 文本*1 是NaN
   let value = e.target.value * 1
   // 非法情况: 出现NaN或者小于1
   if (isNaN(value) || value < 1) {
     this.skuNum = 1
   } else {
     // 正常大于1 【不能出现小数】
     this.skuNum = parseInt(value)
   }
 }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2161276.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

个人如何做量化?我想进行量化交易需要哪些条件?QMT/PTrade量化软件?

个人如何做量化&#xff1f;我想进行量化交易需要哪些条件&#xff1f;QMT&#xff0c;PTrade量化软件&#xff1f; 量化交易策略是一种基于数学模型和统计分析的交易方法&#xff0c;通过计算机程序自动执行交易指令&#xff0c;以实现稳定、可持续的收益。这种策略的核心思想…

【研赛E题成品论文】24华为杯数学建模研赛E题成品论文+可运行代码丨免费分享

2024华为杯研究生数学建模竞赛E题成品论文已出&#xff01; E题 高速公路应急车道紧急启用模型 一、问题一模型建立与求解 1.1 问题一求解思路 赛题要求我们基于四个观测点的视频数据&#xff0c;提取交通流参数并分析这些参数随时间的变化规律。交通流参数包括&#xff1a;…

【秋招笔试题】多多排序

解法&#xff1a;简单语法题 package com.sky;import java.util.*;public class Test1 {public static void main(String[] args) {Scanner sc new Scanner(System.in);int N sc.nextInt();int M sc.nextInt();List<String> words new ArrayList<>(N);for (in…

[系统设计总结] - Proximity Service算法介绍

问题描述 Proximity Service广泛应用于各种地图相关的服务中比如外卖&#xff0c;大众点评&#xff0c;Uber打车&#xff0c;Google地图中&#xff0c;其中比较关键的是我们根据用户的位置来快速找到附近的餐厅&#xff0c;司机&#xff0c;外卖员也就是就近查询算法。 主流的…

再论单源最短路径-SPFA

之前只是背了SPFA的算法模板&#xff0c;但是没有真正理解其中含义。这里复习时再次进行理解。 首先&#xff0c;正常的单源最短路径都会由下面的一个结构来维护“距离”&#xff0c;这个结构可以用一个数字dist[N]来描述&#xff0c;其中下标为顶点编号&#xff0c;值为“暂时…

期盼已久!通义灵码 AI 程序员开启邀测,全流程开发仅用几分钟

在 AI 程序员的帮助下&#xff0c;一个几乎没有专业编程经验的初中生&#xff0c;在人头攒动的展台上从零开始&#xff0c;两分钟就做出了一个倒计时网页。 他需要做的&#xff0c;只是输入包含几句话的提示词。数秒钟后&#xff0c;大模型就生成了代码&#xff0c;还列出了环…

Redis6.0.9配置redis集群

写在前面 最近在完成暑期大作业&#xff0c;期间要将项目部署在云服务器上&#xff0c;其中需要进行缓存的配置&#xff0c;决定使用Redis&#xff0c;为了使系统更加健壮&#xff0c;选择配置Redis-Cluster。由于服务器资源有限&#xff0c;在一台服务器上运行6个Redis Instan…

Springboot-多数据源

文章目录 一、架构二、实现过程2.1 第一步&#xff1a;引入依赖pom2.2 第二步&#xff1a;创建application.yml配置2.3 第三步&#xff1a;创建架构的文件夹MybatisPlusConfigFirstDataSourceConfigSecondDataSourceConfig 实现功能&#xff0c;在不同的文件夹使用不同的库 一、…

【软件测试】金九银十,APP面试题经验分享

Web 端测试和 App 端测试有何不同? ① 系统架构方面 Web 项目&#xff0c;b/s架构&#xff0c;基于浏览器的&#xff1b;Web 测试只要更新了服务器端&#xff0c;客户端就会同步会更新&#xff1b; App 项目&#xff0c;c/s架构的&#xff0c;必须要有客户端&#xff1b;App…

基于Ambari搭建大数据分析平台(30分钟速成)全网最全最详细的Ambari搭建大数据分析平台:

全网最全最详细的Ambari搭建大数据分析平台&#xff1a; 方法一适合详细自己独立安装&#xff0c;方法二超级详细具体&#xff0c;是根据方法一搭建成功的&#xff0c;方法三是另外的方法&#xff0c;安装包有不同&#xff0c;实践也能安装成功。 方法一&#xff1a; 1.搭建安…

halcon单目相机标定

1.参考这边文章https://blog.csdn.net/weixin_60275604/article/details/139068423 2.代码 dev_close_window() dev_open_window(0, 0, 512, 512, black, WindowHandle) dev_set_draw(margin)***创建一个标定板参数 xNum,yNum标定板中行列标定点个数 MarkDist标定点中心距离 d…

Vue|插件

在 Vue.js 中&#xff0c;插件是用来扩展 Vue 功能的一种方式&#xff0c;能够帮助开发者扩展和复用功能。通过合理使用插件&#xff0c;可以提高代码的组织性和可维护性 目录 如何使用插件?插件的定义创建及使用插件插件的参数插件的扩展 总结 如何使用插件? 插件的定义 插…

洛汗2保姆级辅助教程攻略:VMOS云手机辅助升级打怪!

在《洛汗2》中&#xff0c;玩家将进入一个充满魔幻色彩的西方世界&#xff0c;体验多种族文明的兴衰与冒险。为了更好地享受这款由普雷威&#xff08;Playwith&#xff09;开发的角色扮演动作手游&#xff0c;使用VMOS云手机将是一个明智的选择。VMOS云手机专为游戏打造了定制版…

Gartner最新指南:如何通过开展红队演习提高网络弹性

由于事件和监管要求不断增加&#xff0c;安全和风险管理领导者努力建立网络弹性并有效管理网络威胁。本研究指导这些领导者制定红队计划以支持弹性及其关键组件。 主要发现 根据 2024 年 Gartner 设计和构建现代安全运营调查&#xff0c;73% 的组织认为红队角色对安全运营目标的…

【资源一号04A卫星(中巴地球资源卫星04A星)】

资源一号04A卫星&#xff08;中巴地球资源卫星04A星&#xff09; 资源一号04A卫星&#xff0c;全称为中巴地球资源卫星04A星&#xff08;CBERS-04A&#xff09;&#xff0c;是中国与巴西两国合作研制的第六颗地球资源卫星。以下是对该卫星的详细介绍&#xff1a; 一、基本信…

解决Nodify框架因自带放大缩小、平移功能导致拖拽添加的控件无法准确在鼠标放下的位置显示控件

ViewModel中写具体关键的几段代码&#xff1a; var editor sender as NodifyEditor; Point p e.GetPosition(editor);//放大缩小比例double scale editor.ViewportZoom;//经过放大缩小、平移后获得坐标点位置p new Point(Math.Round((p.X - editor.ViewportT…

搜维尔科技:OptiTrack采集到的平衡数据,并对人形机器人进行编程,可以确保机器人的动作精度和准确性

OptiTrack具备高精度以及远追踪距离的双层特点&#xff0c;其捕捉范围最远可达91m&#xff0c;是大型场地&#xff08;如体育馆、足球场、虚拟拍摄制作棚等&#xff09;捕捉的最佳选择。 OptiTrack光学动作捕捉系统是目前全球市占率较高的全身动捕产品&#xff0c;可实现精度误…

第十六章 Javamail发送邮件

目录 一、邮件发送原理和流程图 二、Java发送邮件基本步骤 三、QQ邮箱授权码获取 四、示例代码 注&#xff1a;本章内容仅作为了解JavaMail邮件收发的基本原理&#xff0c;不建议作为实际项目使用&#xff0c;项目中建议通过SpringBoot项目加入mail的starter依赖来构建&am…

2.2 信道的极限容量

奈奎斯特定理 香农定理 &#x1f30f;总结

怎么抠图把杂乱的人全部擦除?分享1个简单方法

前言 在图像编辑中&#xff0c;抠图是一项基本而重要的技能。它允许我们从一张图片中提取出想要的部分&#xff0c;或者去除不需要的元素。今天&#xff0c;我将分享一个简单而有效的方法来抠图&#xff0c;特别是如何擦除图片中杂乱的人物。 工具介绍 在众多的抠图工具中&a…