【Vue项目】尚品汇(五)Detail组件开发 实现轮播图和放大镜效果
2022/9/3 23:25:03
本文主要是介绍【Vue项目】尚品汇(五)Detail组件开发 实现轮播图和放大镜效果,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
1 基本准备工作
1.1 组件路由及数据准备
- 编写请求接口
api/index.js
export const reqGetDetailInfo = (skuId ={}) => { return requests(({ url:`/item/${skuId}`, method: 'get' })) }
- 编写组件路由
{ path: '/detail/:skuId', component: Detail, name: 'detail', meta: { showFooter: true } }
这里为了实现路由跳转滚动条置顶效果以及简化代码文件结构,将路由信息写入routes其他信息仍在index.js
import Vue from 'vue' import VueRouter from 'vue-router' import routes from "@/router/routes"; Vue.use(VueRouter) export default new VueRouter({ routes, scrollBehavior(to, from, savePosition) { return {y : 0} } }) // 保存原型push方法 let orignPush = VueRouter.prototype.push; let orignReplace = VueRouter.prototype.replace; // 修改VueRouter的push // 第一个参数告诉原来的push方法往哪里跳(传递了那些参数) // resolve reject参数传递了成功失败参数 VueRouter.prototype.push = function(location, resolve, reject){ if(resolve && reject) { orignPush.call(this, location, resolve, reject) } else { // this为VueRouter,call将上下文修改为了Vuerouter orignPush.call(this, location, ()=>{}, ()=>{}) } } VueRouter.prototype.replace = function(location, resolve, reject){ if(resolve && reject) { orignReplace.call(this, location, resolve, reject) } else { orignReplace.call(this, location, ()=>{}, ()=>{}) } }
- vuex
编写vuex三大件,/store/detail/index.js
import {reqGetDetailInfo} from "@/api"; const actions = { async getDetailInfo(context, skuId) { let result = await reqGetDetailInfo(skuId); if(result.code === 200) { context.commit('GETDETAILINFO', result.data); } } } const state = { detailInfo: {} } const mutations = { GETDETAILINFO(state, detailInfo) { state.detailInfo = detailInfo } } const getters = { } export default { actions, state, mutations, getters }
在总仓库中引入,/store/index.js
import vue from 'vue' import vuex from 'vuex' import home from './home' import search from './search' import detail from "./detail"; vue.use(vuex) export default new vuex.Store({ modules: { home, search, detail } })
- 在Search组件实现路由跳转
/pages/Search/index.vue
goDetail(skuId) { this.$router.push({name: 'detail', params: {skuId: skuId}}) },
1.2 使用getters简化数据
/store/detail/index.js
const getters = { categoryView(state) { return state.detailInfo.categoryView || {} }, skuInfo(state) { return state.detailInfo.skuInfo || {} } }
在组件中使用mapGetter生成计算属性
computed: { ...mapGetters(['categoryView', 'skuInfo']) },
1.3 产品售卖属性的排他操作
效果为点击一个售卖属性会变为高亮,其他高亮取消的效果。
<div class="chooseArea"> <div class="choosed"></div> <dl v-for="(spuSaleAttr, index1) in spuSaleAttrList" :key="spuSaleAttr.id"> <dt class="title">{{ spuSaleAttr.saleAttrName }}</dt> <dd changepirce="0" :class="{active : spuSaleAttrValue.isChecked == '1'}" @click="isCheckedHandle(spuSaleAttrValue.saleAttrValueName, spuSaleAttr.spuSaleAttrValueList)" v-for="(spuSaleAttrValue, index2) in spuSaleAttr.spuSaleAttrValueList" :key="spuSaleAttrValue.id"> {{ spuSaleAttrValue.saleAttrValueName }} </dd> <!-- <dd changepirce="0" class="active">金色</dd>--> <!-- <dd changepirce="40">银色</dd>--> <!-- <dd changepirce="90">黑色</dd>--> </dl> </div>
这里我直接拿的名字和数组进行map修改,和老师直接传入要修改的元素不同,感觉他的更好一点。
isCheckedHandle(saleAttrValueName, attr) { attr.map(item => { if(item.saleAttrValueName === saleAttrValueName) { item.isChecked = '1' } else { item.isChecked = '0' } return item }) }
2 轮播图
目的是轮播显示ImageList组件的skuImageList的图片,因此通过ImageList监视数据创建轮播图实现实时更新。
<div class="swiper-container"> <div class="swiper-wrapper"> <div class="swiper-slide" v-for="(banner, index) in skuImageList" :key="banner.id"> <img :src="banner.imgUrl"/> </div> </div> <!-- 如果需要导航按钮 --> <div class="swiper-button-prev"></div> <div class="swiper-button-next"></div> </div>
watch: { // 监听得到数据时,保证轮播图for循环结构完整 skuImageList(newValue, oldValue) { this.$nextTick(() => { new Swiper('.swiper-container', { slidesPerView: 7, slidesPerGroup: 1, // 如果需要前进后退按钮 navigation: { nextEl: '.swiper-button-next', prevEl: '.swiper-button-prev', }, }) }) } }
使用nextTick的原因是服务器返回数据的时候可能浏览器的for循环还没有渲染完,因此需要nextTick等下次页面结构完整才能完成轮播图的渲染。
slidesPerView表示一页的图片量
slidesPerGroup表示一次滑动需要滑动几个图片
2.1 实现点击ImageList组件图片更改Zoom组件图片
分析:两个组件属于兄弟关系,因此使用全局事件总线进行通信
首先在ImageList组件创建图片点击函数以及时间总线触发
methods: { changeCurIndex(index) { this.curIndex = index this.$bus.$emit('changeImg', index) } }
在Zoom组件创建事件总线响应
<script> export default { name: "Zoom", props: ['skuImageList'], data() { return { curIndex: 0 } }, computed: { imgObj() { return this.skuImageList[this.curIndex] || {} }, }, mounted() { this.$bus.$on('changeImg', (index) => { this.curIndex = index }) } } </script>
3 放大镜
<template> <div class="spec-preview"> <img :src="imgObj.imgUrl" /> <div class="event" @mousemove="handle()"></div> <div class="big"> <img :src="imgObj.imgUrl" ref="big" /> </div> <div class="mask" ref="mask"></div> </div> </template>
<script> export default { name: "Zoom", props: ['skuImageList'], data() { return { curIndex: 0 } }, computed: { imgObj() { return this.skuImageList[this.curIndex] || {} }, }, mounted() { this.$bus.$on('changeImg', (index) => { this.curIndex = index }) }, methods: { handle() { // console.log(event) let mask = this.$refs.mask let big = this.$refs.big let left = event.offsetX - mask.offsetWidth / 2 let top = event.offsetY - mask.offsetHeight / 2 if(left < 0) left = 0 if(top < 0) top = 0 if(left > mask.offsetWidth) left = mask.offsetWidth if(top > mask.offsetHeight) top = mask.offsetHeight mask.style.left = left + 'px' mask.style.top = top + 'px' big.style.left = -2 * left + 'px' big.style.top = -2 * top + 'px' } } } </script>
这篇关于【Vue项目】尚品汇(五)Detail组件开发 实现轮播图和放大镜效果的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-16Vue3资料:新手入门必读教程
- 2024-11-16Vue3资料:新手入门全面指南
- 2024-11-16Vue资料:新手入门完全指南
- 2024-11-16Vue项目实战:新手入门指南
- 2024-11-16React Hooks之useEffect案例详解
- 2024-11-16useRef案例详解:React中的useRef使用教程
- 2024-11-16React Hooks之useState案例详解
- 2024-11-16Vue入门指南:从零开始搭建第一个Vue项目
- 2024-11-16Vue3学习:新手入门教程与实践指南
- 2024-11-16Vue3学习:从入门到初级实战教程