zoukankan      html  css  js  c++  java
  • vue前台(七)

    一,在detail组件中,向子组件zoom和 imglist传递数据,属性传递,

    1.父组件detail

      computed: {
        ...mapGetters(["categoryView", "skuInfo", "spuSaleAttrList",'imgList'])
      },

    向子组件传递数据

    <div class="previewWrap">
              <!--放大镜效果-->
              <Zoom :imgList="skuInfo.skuImageList" />
              <!-- 小图列表 -->
              <ImageList  :imgList="skuInfo.skuImageList" />
            </div>

     子组件接收

     props:['imgList'],
    2. ,ImageList组件填充数据,底部轮播图
     <div class="swiper-container">
        <div class="swiper-wrapper">
          <div class="swiper-slide" v-for="(img, index) in imgList" :key="img.id">
            <img :src="img.imgUrl">
          </div>
        </div>
        <div class="swiper-button-next"></div>
        <div class="swiper-button-prev"></div>
      </div>

    3.zoom子组件填充数据,默认呈现第一张图,data中初始化一个index

     data(){
          return {
            defaultIndex : 0
          }

    大图填充数据

    <div class="spec-preview">
        <img :src="imgList[defaultIndex].imgUrl" />
        <div class="event"></div>
        <div class="big">
          <img :src="imgList[defaultIndex].imgUrl"  />
        </div>
        <div class="mask"></div>
      </div>

    注;此时控制台会报错, a.b.c假报错问题, 

    解决方式,此时需要判断imglist

     computed:{
          //计算它的可能值,不然出现a.b.c
          defaultImg(){
            if(this.imgList){
              return this.imgList[this.defaultIndex]
            }else{
              return {}
            }
          }
        }

     再次填充数据

      <div class="spec-preview">
        <img :src="defaultImg.imgUrl" />
        <div class="event"  @mousemove="move"></div>
        <div class="big">
          <img :src="defaultImg.imgUrl" ref="bigImg"/>
        </div>
        <div class="mask" ref="mask"></div>
      </div>

    二,小图列表点击,切换类

    1.在imageslist组件中定义初始索引,当点击轮播图的图片时,index赋值给currentIndex,类名也跟着动态展示,此时将轮播图的index传递给大图组件,轮播图展示哪张图,大图也跟着

    展示哪张图

      data() {
        return {
          currentIndex: 0
        };
      },

    类名

    .active {
            border: 2px solid #f60;
            padding: 1px;
          }

    2.点击小图,切换类

     <div class="swiper-slide" v-for="(img, index) in imgList" :key="img.id">
            <img :src="img.imgUrl" @click="changeIndex(index)" :class="{active:currentIndex === index}" />
          </div>

    回调函数,跟新索引,

      methods: {
        changeIndex(index) {
          this.currentIndex = index;

    三,点击小图,切换一样的中图

    1.在imagelist中点击小图,回调中传递index,用全局事件总线传递index,传递给兄弟组件zoom

    <div class="swiper-slide" v-for="(img, index) in imgList" :key="img.id">
            <img :src="img.imgUrl" @click="changeIndex(index)" :class="{active:currentIndex === index}" />
          </div>

    点击事件回调函数,搞事件总线,$emitc触发,传递index给zoom大图组件

      methods: {
        changeIndex(index) {
          this.currentIndex = index;
          this.$bus.$emit("changeDefaultIndex", index);
        }
      },

    在zoom组件中,监听

      mounted(){
          this.$bus.$on('changeDefaultIndex',this.changeDefaultIndex)
        },

    回调函数,跟新当前索引

     methods:{
          changeDefaultIndex(index){
            this.defaultIndex = index
          },

    四,小图片的轮播图处理

    1.html模板

     <div class="swiper-container" ref="imglist">
        <div class="swiper-wrapper">
          <div class="swiper-slide" v-for="(img, index) in imgList" :key="img.id">
            <img :src="img.imgUrl" @click="changeIndex(index)" :class="{active:currentIndex === index}" />
          </div>
        </div>
        <div class="swiper-button-next"></div>
        <div class="swiper-button-prev"></div>
      </div>

    2.引入swiper

    import Swiper from "swiper";
    import "swiper/css/swiper.min.css";

    3. 在实例化swiper

      watch: {
        imgList: {
          handler() {
            //Vue.nextTick或者vm.$nextTick是一样的功能
            //在最近的一次dom更新之后执行nextTick里面传的回调函数
            this.$nextTick(() => {
              new Swiper(this.$refs.imglist, {
                // direction: "vertical", // 垂直切换选项
                // autoplay:true,//等同于以下设置
                // loop: true, // 循环模式选项
    
                // // 如果需要分页器
                // pagination: {
                //   el: ".swiper-pagination"
                // },
    
                // 如果需要前进后退按钮
                navigation: {
                  nextEl: ".swiper-button-next",
                  prevEl: ".swiper-button-prev"
                },
                slidesPerGroup:5, //点击一下滑动一组有多少张
                slidesPerView:5 //一屏显示多少张
                // 如果需要滚动条
                // scrollbar: {
                //   el: ".swiper-scrollbar"
                // }
              });
            });
          },
          immediate: true //立即执行,在最近dom更新之前就会执行
        }
      }

     五,放大镜逻辑

    1.在图片中添加移动事件,获取鼠标的坐标,并且确定遮罩mask需要移动的距离,以及对应的大图移动的距离

    在zoom组件中, html中

    <template>
      <div class="spec-preview">
        <img :src="defaultImg.imgUrl" />
        <div class="event"  @mousemove="move"></div>
        <div class="big">
          <img :src="defaultImg.imgUrl" ref="bigImg"/>
        </div>
        <div class="mask" ref="mask"></div>
      </div>
    </template>

    js代码

     // 图片移动事件
          move(event){
            let target = event.target    //拿的是事件源元素
            let mouseX = event.offsetX   //鼠标相对事件源本身的x位置
            let mouseY = event.offsetY   //鼠标相对事件源本身的y位置
            let mask = this.$refs.mask
            let bigImg = this.$refs.bigImg
            //求mask 要走的位置
            let maskX = mouseX - mask.offsetWidth / 2
            let maskY = mouseY - mask.offsetHeight / 2
    
            if(maskX < 0){
              maskX = 0
            }else if(maskX > target.clientWidth - mask.offsetWidth){
              maskX = target.clientWidth - mask.offsetWidth
            }
    
            if(maskY < 0){
              maskY = 0
            }else if(maskY> target.clientHeight- mask.offsetHeight){
              maskY = target.clientHeight - mask.offsetHeight
            }
    
    
            //设置mask的位置
            mask.style.left = maskX + 'px'
            mask.style.top = maskY + 'px'
    
            //设置大图的移动位置,mask移动相反的两倍
            bigImg.style.left = -2 *maskX + 'px'
            bigImg.style.top = -2 *maskY + 'px'
          }

    六, 对产品的属性的方框进行选中处理

    1.  isChecked属性为选中的标识,‘1’为选中, ‘0’为不选中

    在detail组件中

    html代码

      <dl v-for="(item, index) in spuSaleAttrList" :key="index">
                    <dt class="title">{{item.saleAttrName}}</dt>
                    <dd
                      changepirce="0"
                      :class="{active:attrValue.isChecked === '1'}"
                      v-for="(attrValue, index) in item.spuSaleAttrValueList"
                      :key="attrValue.id"
                      @click="changeIsCheck(item.spuSaleAttrValueList,index)"
                    >{{attrValue.saleAttrValueName}}</dd>
                  </dl>

    2.对选中的方框排他处理

    js代码

      changeIsCheck(attrValueList,index){
          //排它
          attrValueList.forEach(item => {
            item.isChecked = '0'
          })
          attrValueList[index].isChecked = '1'
        },

    七, 修改购买的数量的v-model的应用,收集数量,点击加号,减号,增减数量

    <div class="controls">
                    <input autocomplete="off" class="itxt" v-model="skuNum"/>
                    <a href="javascript:" class="plus" @click="skuNum++">+</a>
                    <a href="javascript:" class="mins" @click="skuNum <= 1 ? 1 : skuNum-- ">-</a>
                  </div>

    八, 点击添加购物车时发送请求,是否添加成功

    1.封装请求添加购物车的请求

    //请求添加购物车  /api/cart/addToCart/{ skuId }/{ skuNum }    post
    
    export const reqAddOrUpdateShopCart = (skuId,skuNum) => Ajax.post(`/cart/addToCart/${ skuId }/${ skuNum }`)

    2.配置shopcart.js的vuex

    import {reqAddOrUpdateShopCart} from '@/api'
    
    const state = {
    }
    const mutations = {
    }
    
    const actions = {
      async addorUpdateShopCart({commit},{skuId,skuNum}){
        const result = await reqAddOrUpdateShopCart(skuId,skuNum)
        if(result.code === 200){
          return '添加购物车成功'
        }else{
          // return '添加购物车失败' 返回的还是成功的promise
          //返回的是失败的promise
          return Promise.reject(new Error('添加购物车失败'))
        }
      }
    }
    
    const getters = {
    }
    
    export default {
      state,
      mutations,
      actions,
      getters
    }

    3.在总vuex中注册

    4.在添加购物车按钮中,添加点击事件
     <div class="add">
                    <a href="javascript:" @click="toSuccess">加入购物车</a>
                  </div>

    5, js代码,添加商品请求成功后,需要把商品存储在本地浏览器sessionStorage, 商品的数量用路由传参,然后路由组件

    跳转到产品添加成功页面

     
     async toSuccess(){
          //先发请求,判定是否成功
          //调用我们actions内部的异步函数(async),这个调用的返回值一定是一个promise
          try {
            const result = await this.$store.dispatch('addorUpdateShopCart',{skuId:this.skuInfo.id,skuNum:this.skuNum})
            alert(result)
            //在添加成功跳转到添加成功页面之前,把相应的商品存储在sessionStorage当中,用来在添加成功页面去使用
            //本地存储传参
            sessionStorage.setItem('SKUINFO_KEY',JSON.stringify(this.skuInfo))
    
            this.$router.push(`/addcartsuccess?skuNum=${this.skuNum}`)  //如果添加购物车成功,那么就跳转到添加购物车成功的页面
    
             //路径传参给路由组件
            // this.$router.push({name:'addcartsuccess', query:{skuNum:this.skuNum,skuInfo:this.skuInfo }})
          } catch (error) {
            alert(error.message)
          }
          
          //成功
          //失败
        }

    6,跳转到商品添加成功页面AddCartSuccess,填充传递过来的数据

    <div class="right-info">
                <p class="title">{{skuInfo.skuName}}</p>
                <p class="attr">颜色:WFZ5099IH/5L钛金釜内胆 数量:{{$route.query.skuNum}}</p>
              </div>
    data(){
          return {
            skuInfo: JSON.parse(sessionStorage.getItem('SKUINFO_KEY')) || {}
          }
        },
    7.路由连接到查看商品详情页
    <router-link :to="`/detail/${skuInfo.id}`" class="sui-btn btn-xlarge">查看商品详情</router-link>
     
  • 相关阅读:
    一个网络传输框架——zeroMQ 调研笔记
    Node.js的cluster模块——Web后端多进程服务
    boost::spirit unicode 简用记录
    HTTP的长连接和短连接——Node上的测试
    MongoDB 驱动以及分布式集群读取优先级设置
    Lua知识备忘录
    MongoDB使用小结:一些常用操作分享
    此项目与Visual Studio的当前版本不兼容的报错
    @Controller和@RestController的区别
    SQLSERVER中计算某个字段中用分隔符分割的字符的个数
  • 原文地址:https://www.cnblogs.com/fsg6/p/13357028.html
Copyright © 2011-2022 走看看