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

    一, 对商品的数量输入框做限制,change事件,对输入框修改数据后,失去焦点后,对于负数控制

     <input autocomplete="off" class="itxt" v-model="skuNum" @change="$event.target.value*1 > 1? skuNum = $event.target.value*1 : skuNum = 1"/>

    二,连接路由到去购物车结算页面

     <router-link to="/shopcart">去购物车结算</router-link>

    三,封装请求购物车列表数据函数

    //请求购物车列表数据  /api/cart/cartList  get
    
    export const reqShopCartList = () => Ajax.get('/cart/cartList')

    四,在shopcart.js的 vuex的actions发送请求,然后在state存储响应数据

    五,在ShopCart组件中dispatch到vuex中,但是此时,响应数据是空的,因为到购物车列表页面,此时是没有登录的,

    需要搞一个临时身份信息标识uuid,后台存储后,可以识别身份信息

     
    1.新建utils--userabout.js, 封装uuid的函数(用于配置工具函数),在本地localStorage存储一份,向外暴露该函数,安装uuid包,
    import { v4 as uuidv4 } from 'uuid';
    
    function getUserTempId(){
    //这个是工具函数,它是专门用来生成或者得到用户的临时id的
      let userTempId = localStorage.getItem('USERTEMPID_KEY')
      //如果获取不到,证明用户之前没有生成过临时id
      if(!userTempId){
        userTempId = uuidv4()  // ⇨ '9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d'
        localStorage.setItem('USERTEMPID_KEY',userTempId)
      }
      //如果存在就直接返回原来的,不存在返回的是新创建的
      return userTempId
    }
    
    export {
      getUserTempId
    }
     
    2,新建store--users.js, 引入uuid的函数,存储uuid必须用userTempId存储, 让临时id在vuex中存储,比存储在本地更快
     
    import {} from '@/api'
    import {getUserTempId} from '@/utils/userabout'
    const state = {
      userTempId:getUserTempId()
    }
    const mutations = {
    }
    
    const actions = {
      
    }
    
    const getters = {
    }
    
    export default {
      state,
      mutations,
      actions,
      getters
    }
    3.在请求拦截器当中携带uuid,传送给后台,(从vuex中传递)引入import store from '@/store',
    //请求拦截器内部一般不会处理错误的信息
    service.interceptors.request.use(config => {
      //config是发送请求的配置对象,必须处理完返回这个配置对象
      //开启我们的进度条
      NProgress.start()
    
      //在请求头当中添加用户的临时id,让每个ajax请求都带着这个userTempId
      let userTempId = store.state.user.userTempId
      if(userTempId){
        config.headers.userTempId = userTempId
      }
    
      return config
    });
    注;此时未登录状态下,在ShopCart组件中dispatch到vuex中,响应是有数据的
     
    4,shopcart组件从vuex中获取数据,从模板中填充数据
    import { mapState } from 'vuex'
     computed:{
          ...mapState({
            shopCartList:state => state.shopcart.shopCartList
          }),
     
    5,购物车动态数据计算属性数据的展示
    模板填充数据
      <ul class="cart-list"  v-for="(shopcart, index) in shopcartList" :key="shopcart.id">
              <li class="cart-list-con1">
                <input type="checkbox" name="chk_list" :checked="shopcart.isChecked">
              </li>
              <li class="cart-list-con2">
                <img :src="shopcart.imgUrl">
                <div class="item-msg">{{shopcart.skuName}}</div>
              </li>
           
              <li class="cart-list-con4">
                <span class="price">{{shopcart.skuPrice}}</span>
              </li>
              <li class="cart-list-con5">
                <a href="javascript:void(0)" class="mins">-</a>
                <input autocomplete="off" type="text" :value="shopcart.skuNum" minnum="1" class="itxt">
                <a href="javascript:void(0)" class="plus">+</a>
              </li>
              <li class="cart-list-con6">
                <span class="sum">{{shopcart.skuPrice* shopcart.skuNum}}</span>
              </li>
              <li class="cart-list-con7">
                <a href="#none" class="sindelet">删除</a>
                <br>
                <a href="#none">移到收藏</a>
              </li>
            </ul>
     
     
    5.1 , 计算购物车商品的总数
    <div class="chosed">已选择
              <span>{{checkedNum}}</span>件商品</div>
            <div class="sumprice">

    js代码

     checkedNum(){
            //统计的数组方法
            return this.shopCartList.reduce((pre,item,index)=>{
              //已经选中的商品
              if(item.isChecked){
                pre += item.skuNum
              }
              // console.log(pre)
              return pre
            },0)
          },

    5.2, 计算购物车商品的总价

     <div class="sumprice">
              <em>总价(不含运费) :</em>
              <i class="summoney">{{allMoney}}</i>
            </div>

    js代码

    allMoney(){
            return this.shopCartList.reduce((pre,item,index) => {
              if(item.isChecked){
                pre += item.skuNum * item.skuPrice
              }
              return pre
            },0)
          },
     5.3,点击单选框,需要发送请求,更改单选框状态,响应体数据是空
       所有单选框选中,全选框自动选上,
      点击全选按钮框,所有的单选框都要选上
     
    封装请求修改购物车选中状态函数
    //请求修改购物车选中状态 /api/cart/checkCart/{skuID}/{isChecked}  get
    export const reqUpdateIsChecked = (skuID,isChecked) => Ajax.get(`/cart/checkCart/${skuID}/${isChecked}`)

    在vuex中发送该请求

     async updateIsChecked({commit},{skuId,isChecked}){
        const result = await reqUpdateIsChecked(skuId,isChecked)
        if(result.code === 200){
          return '修改选中状态成功'
        }else{
          return Promise.reject(new Error('修改选中状态失败'))
        }
      },

    点击单选框,组件dispatch到vuex,发送请求,修改选择框的状态

      <li class="cart-list-con1">
                <input type="checkbox" name="chk_list" :checked="cart.isChecked" @click="updateOneIscheck(cart)">
              </li>
     //修改单个购物车选中状态信息,isChecked状态,1是选中,0是没选中
          async updateOneIscheck(cart){
            try {
              await this.$store.dispatch('updateIsChecked',{skuId:cart.skuId,isChecked:cart.isChecked === 1? 0 : 1})
              //重新发送请求,获取新的数据
              this.getShopCartList()
            } catch (error) {
              alert(error.message)
            }
          }
      1.所有单选框选中,全选框自动选上,get方法
      2.点击全选按钮框,所有的单选框都要选上, set方法
     
    在组件shopCart点击全选按钮,改变选择框的状态

    1.在组件shopCart改变选择框的状态,拿到改变后值,set(ischecked),dispatch到veux的actions的getReqUpdateIsAllChecked,
    2.遍历每个选择框的状态,如果有选择框的状态和全选框的状态一致,就不用发送请修改状态的请求了
    3.如果有选择框的状态和修改后的全选框的状态不一致,那么dispatch到getReqUpdateIsChecked,修改选择框的状态
    4.初始化一个空数组promises, 如果每次dispatch到getReqUpdateIsChecked,那么往数组中添加这个promise
    5.然后整体返回一个promsie return Promise.all(promises)
    6.在组件中然后在发送请求,获取新的数据, this.getreqShopCartList()

    在组件中计算全选按钮的状态

    <div class="select-all">
            <input class="chooseAll" type="checkbox" v-model="isAllChecked">
            <span>全选</span>
          </div>
    js代码
     isAllChecked:{
            get(){
              //返回布尔值,所有单选框选中后,全选框也会跟着选中
              return this.shopCartList.every((item,index) => item.isChecked === 1)
            },
            async set(val){
              //点击全选之后,会进入这个set逻辑
              try {
                const result = await this.$store.dispatch('updateAllIsChecked',val?1:0)
                // 重新发送请求,获取新的数据
                this.getShopCartList()
              } catch (error) {
                alert(error.message)
              }
            }
          }

    在vuex中处理全选框选中后,单选框的状态变化

      //单选框选中发送请求
      async updateIsChecked({commit},{skuId,isChecked}){
        const result = await reqUpdateIsChecked(skuId,isChecked)
        if(result.code === 200){
          return '修改选中状态成功'
        }else{
          return Promise.reject(new Error('修改选中状态失败'))
        }
      },
    
      //选中全选框的逻辑
      updateAllIsChecked({commit,state,dispatch},isChecked){
        //定义数组存储每一项去发请求返回的promise对象
        let promises = []
        state.shopCartList.forEach(item => {
          //如果修改后全选按钮的状态和单选的状态一样,不用发送请求,更改状态
          if(item.isChecked === isChecked) return
          //如果不一致
          let promise = dispatch('updateIsChecked',{skuId:item.skuId,isChecked:isChecked})
          promises.push(promise)
        })
        
        //Promise.all 传递的参数必须是一个promise对象的数组,返回值也是一个promise 
        //返回的promise对象的成功和失败  看数组内部所有的promise对象是否成功,如果都成功,那么它就成功,如果有一个失败,那它就失败
        //成功的返回值promise的数据是一个数组 【每个成功的promise的数据】
        return Promise.all(promises)
      }
     
     
    5.4,点击数量加减号,输入框输入数量,发送请求,输入的数量和后台数据库的商品数量做加法,才是修改后的数量
     
     
           <li class="cart-list-con5">
                <a href="javascript:void(0)" class="mins" @click="updateCartNum(cart,-1)">-</a>
                <input autocomplete="off" type="text" :value="cart.skuNum" minnum="1" class="itxt" @change="updateCartNum(cart,$event.target.value*1)">
                <a href="javascript:void(0)" class="plus" @click="updateCartNum(cart,1)">+</a>
              </li>
     js代码
      // 修改购物车某个商品的数量
          async updateCartNum(cart,changeNum){
            //changeNum是后面要发请求的参数,代表的是一个改变的数量
            if(cart.skuNum + changeNum < 1){
              changeNum = 1 - cart.skuNum
            }
            
            try {
              //请求修改购物车的商品数量   用原有的数量和改变的数量计算
              // await后是同步代码,必须他发送请求,修改数量后,才会立刻执行后面的请求
              await this.$store.dispatch('addorUpdateShopCart',{skuId:cart.skuId,skuNum:changeNum})
              //请求成功之后,重新获取购物车的列表信息,页面展示的就是最新的
              this.getShopCartList()
            } catch (error) {
              alert(error.message)
            }
          },

    vuex发送的请求

    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('添加购物车失败'))
        }
      },
     
     
     
     
  • 相关阅读:
    关于 Unity WebGL 的探索(二)
    关于 Unity WebGL 的探索(一)
    Ghostscript 中 ps2pdf 命令在 windows msys 下的运行错误问题。
    编译 Windows 版本的 Unity Mono(2017-03-12 20:59)
    Windows 下使用 mingw+msys 交叉编译 Android Unity Mono
    关于 UGUI 字体花屏或乱码。
    从 NavMesh 网格寻路回归到 Grid 网格寻路。
    Unity光照图UV显示
    2DPlatformer-SLua 编辑器 UI 美化
    SnapDragon Profiler 学习
  • 原文地址:https://www.cnblogs.com/fsg6/p/13404592.html
Copyright © 2011-2022 走看看