【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组件开发 实现轮播图和放大镜效果的更多相关文章
- vue大型电商项目尚品汇(前台篇)day02
现在正式回归,开始好好做项目了,正好这一个项目也开始慢慢的开始起色了,前面的准备工作都做的差不多了. 而且我现在也开始慢慢了解到了一些项目才开始需要的一些什么东西了,vuex.router这些都是必备 ...
- vue大型电商项目尚品汇(前台篇)day04
这几天一直都在做项目,只是没有上传上来,即将把前台项目完结了.现在开始更新整个前台的部分 一.面包屑处理 1.分类操作 点击三级联动进入搜索产生面包屑,直接取参数中的name即可 点击x怎么干掉这个面 ...
- vue大型电商项目尚品汇(后台篇)day05
今天继续是对后台管理部分的一个操作,但是快要结束了,今天结束,明天会进入一个从Vue以来,另外一个名声显著的东西了,一只耳闻从未见识,而且十分的炫酷 他就是------数据可视化Echarts,迫不及 ...
- Flutter学习五之网络请求和轮播图的实现
上期讲到了,怎样实现一个下拉刷新和加载更多的列表,数据更新,需要使用到网络请求,在flutter中,怎样实现一个网络请求呢?官方使用的是dart io中的HttpClient发起的请求,但HttpCl ...
- vue大型电商项目尚品汇(前台篇)day01
学完vue2还是决定先做一个比较经典,也比较大的项目来练练手好一点,vue3的知识不用那么着急,先把vue2用熟练了,vue3随时都能学. 这个项目确实很经典包含了登录注册.购物车电商网站该有的都有, ...
- vue大型电商项目尚品汇(前台篇)day05
紧急更新第二弹,然后就剩下最后一弹,也就是整个前台的项目 一.购物车 1.加入购物车(新知识点) 加入到购物车是需要接口操作的,因为我们需要将用户的加入到购物车的保存到服务器数据库,你的账号后面才会在 ...
- vue大型电商项目尚品汇(前台篇)day05终结篇
前台部分到此结束,一路走来还挺怀念,今天主要是对整个项目的完成做一个最后的收尾工作,对于功能上的需求没有什么了,主要就是项目上线的一些注意事项. 一.个人中心二级路由 当我们点击查看订单应该跳转到个人 ...
- vue大型电商项目尚品汇(后台终结篇)day06 重磅!!!
自此整个项目前后台,全部搭建完毕. 今天是最后一天,内容很多,而且也比较常用,一个图标类数据可视化,一个后台的权限管理,都是很经典的类型. 一.数据可视化 1.简介 专门的一门学科,有专门研究这个的岗 ...
- vue大型电商项目尚品汇(后台篇)day03
今天把平台属性的管理基本完成了,后台管理做到现在基本也开始熟悉,确实就是对ElementUI的一个熟练程度. 一.平台属性管理 1.动态展示数据 先把接口弄好,应该在第三级标题选择后进行发请求 静态页 ...
- vue大型电商项目尚品汇(后台篇)day01
开始我们后台篇的内容,前面处理了一些事情,去学校完成授位仪式,由校长授位合影,青春不留遗憾,然后还换了一个电脑,征战了四年的神船终于退役了,各种各样的小毛病是真的烦人. 现在正式开始后台篇的内容,做了 ...
随机推荐
- 06 HBase安装与伪分布式配置
1.下载压缩文件 2.解压 3.修改文件夹名 4.修改文件夹权限 5.配置环境变量 6.伪分布式配置文件 7.启动HDFS,启动Hbase 8.进入shell界面 9.停止Hbase,停止HDFS运行
- Python笔记(5)——if 语句一:条件测试(Python编程:从入门到实践)
每条if语句的核心都是一个值为True或False的表达式.Python根据条件测试的值为True还是False来决定是否执行if语句中的代码.如果条件测试的值为True,Python就执行紧跟在if ...
- Redis5.0.4-集群(单机版)搭建
最近尝试搭建了一下redis集群,这里记录一下,最后附上的是参考的博客地址. 安装C语言编译环境GCC yum install -y gcc-c++ 下载redis并编译安装 下载: wget htt ...
- animation 和 transition 的区别
Transition 提供了从一种状态过渡到另一种状态的改变. Animation 则可以从不同关键帧(@keyframes)上设置多个过渡点. Transition 关注的是元素指定css属性的变化 ...
- JSP中动态include和静态include的区别
a.静态include:语法:<%@ include file="文件名" %>,相当于复制,编辑时将对应的文件包含进来,当内容变化时,不会再一次对其编译,不易维护. ...
- Java定时器Timer和TimerTask
方式一:设定指定任务task在指定时间time执行 schedule(TimerTask task, Date date) public static void main(String[] arg ...
- How to enable CIFS in kernel 4.9
kernel config 要打开这几项
- java 多线程 数据通信
1.司机等乘客全部上车后再启动车子 import java.util.concurrent.CountDownLatch;public class A { public static void mai ...
- ios装包
一.下载爱思助手 二.找到本机设备 注:如果未弹出允许.拒绝调试选项可尝试换根数据线解决 三.将对应包体文件拖入本机设备
- c#调用键盘输入
[code]csharpcode: /// <summary> /// 键盘输入模拟 /// </summary> [DllImport("user32.dll&qu ...