VUE前台项目day_06

一、购物车ShopCart的数据处理

(一)批量删除

  1. 找到total,加一个逻辑进行判断

  1. 找到按钮,绑定点击事件

  1. 找到api文件,编写批量删除的接口

//该函数专门用于:获取删除一些商品的状态
export const reqBatchDeleteCart = (idList) => ajax.post('/cart/batchDeleteCart',idList)
  1. 找到methods编写批量删除商品的回调方法

  1. 别忘了在import中引入reqBatchDeleteCart

(二)购物车数量的修改

  1. 因为携带给服务器的是差值,不是我们最终想要的值,而且购物车是要向服务器发送请求的

  1. 获取用户输入的数量以及商品的skuId

  1. 在methods中校验输入的是否合法的逻辑(难点

// 修改数量的一些回调
    async handleChangeGoodNum(type, cartInfo,e) {
      // 若此时不可操作购物车数量,则停掉逻辑,否则正常执行
      if(!this.isExecute) return
      // 即将操作购物车数量,立刻锁掉逻辑
      this.isExecute = false
      switch (type) {
        // 若是点击了+号
        case "increment":
          if (cartInfo.skuNum === 200) {
            alert("最大购买数量为200!");
          } else {
            // 发送请求让服务器+1
            let result = await reqAddGood2Cart(cartInfo.skuId, 1);
            // 根据服务器返回的结果,来维护本地数据
            if (result.code === 200) {
              // 本地加1
              cartInfo.skuNum++;
              // 勾选
              cartInfo.isChecked = 1;
            } else {
              alert(result.message);
            }
          }
          break;
        // 若是点击了-号
        case "decrement":
          if (cartInfo.skuNum === 1) {
            alert("最小购买数量为1!");
          } else {
            // 发送请求让服务器+1
            let result = await reqAddGood2Cart(cartInfo.skuId, -1);
            // 根据服务器返回的结果,来维护本地数据
            if (result.code === 200) {
              // 本地减1
              cartInfo.skuNum--;
              // 勾选
              cartInfo.isChecked = 1;
            } else {
              alert(result.message);
            }
          }
          break;
        // 若是直接修改
        case "input":
          // 获取用户输入的数量
          const { value } = e.target;
          // 获取当前的数量以及商品的skuId
          const { skuId, skuNum } = cartInfo;
          // 校验输入
          if (goodNumReg.test(value)) {
            // 合法
            // 计算差值
            const disNum = value - skuNum;
            // 发请求联系服务器
            let result = await reqAddGood2Cart(skuId, disNum);
            // 判断业务逻辑是否成功
            if (result.code === 200) {
              // 修改数量成功了
              cartInfo.skuNum = value * 1;
              // 只要修改数量成功,必须勾选
              cartInfo.isChecked = 1;
            } else {
              // 修改数量失败了
              alert(result.message);
              // 亲手操作DOM,将值变为输入前的值
              e.target.value = skuNum;
            }
          }
          // 用户输入的太多了
          else if (value > 200) {
            // 计算差值
            const disNum = 200 - skuNum;
            // 如果差值是0,直接将DOM置为200,逻辑停止,请求根本无需发送
            if (disNum === 0) {
              return (e.target.value = 200);
            }
            // 发请求联系服务器
            const result = await reqAddGood2Cart(skuId, disNum);
            // 判断业务逻辑是否成功
            if (result.code === 200) {
              // 若成功,则更新本地数据,同时直接操作DOM,将内容变为200
              cartInfo.skuNum = e.target.value = 200;
              // 只要修改数量成功,必须勾选
              cartInfo.isChecked = 1;
            } else {
              // 若失败,更新本地数据
              alert(result.message);
              // 亲手操作DOM,将值变为输入前的值
              e.target.value = skuNum;
            }
          }
          // 用户输入的不合法
          else {
            // 打回原来的值
            e.target.value = skuNum;
          }
      }
      // 释放数量修改逻辑
      this.isExecute = true
    }
  },

补充:函数的防抖与节流

函数的防抖

什么是函数的防抖?

事件被触发后等n秒后再执行逻辑,若这n秒内事件又被触发,则重新计时n秒,之前的逻辑不再执行。简单来说就是生活中我们要做的事情总是被改来改去,那这样就等下发指令后的n秒,再做,免得再改来改去。也就是等那最后一下。

什么是抖?

就是发送了太多次的没用的请求,用专业的话来说就是服务器太累了。

怎么防抖?

等获得完整的输入之后再发送请求,可以先进入一段判断,再包一个定时器,但这样写过于麻烦,可以使用lodash库,引入相对应的文件之后,利用._debounce方法,正常书写指定的回调,正常发送请求就好了。

具有代表性的应用场景:实时搜索

代码片段:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!-- 引入lodash:lodash全部的功能引入 -->
    <script src="./js/lodash.js"></script>
</head>
<body>
    <p>
        请你输入搜索的内容:<input type="text">
    </p>
</body>
</html>
<script>
    //防抖:前面的所有的触发都被取消,最后一次执行在规定的时间之后才会触发,也就是说如果连续快速的触发,只会执行一次
    let input = document.querySelector('input');
    //文本发生变化立即执行
    input.oninput = _.debounce(function(){
        console.log('ajax发请求')
    },1000);
    //lodash插件:里面封装函数的防抖与节流的业务【闭包+延迟器】
    //1.lodash函数库对外暴露_函数
</script>

函数的节流

什么是函数的节流?

在规定的间隔时间范围内不会重复触发回调,只有大于这个时间间隔才会触发回调,把频繁触发变为少量触发。

例子:玩游戏。例如在玩王者荣耀,当人物放大招时,会有技能冷却时间,如果说不点的话就不会进入冷却期;或者也可以比喻成在车站等车吃面,吃一口面的时间是60s,不管车是不是到站了,吃面的时间还是60s。再或者是射击游戏中的射速,就算是一直点着鼠标射击,也只会在规定射速内射出子弹。

为什么要使用函数节流?

因为在前端开发当中,有一些事情或者是函数,会频繁地触发,例如onresize、scroll、mousemove等,这些事件的触发频率很高,如果不做限制的话,很可能会触发n次,服务器会很累。

解决思路

主要解决思路是包一个定时器(setTimeout),通过设置延时时间,在第一次调用时,创建定时器,先设定一个变量true,写入需要执行的函数。第二次执行这个函数时,会判断变量是否true,是则返回。当第一次的定时器执行完函数最后会设定变量为false。那么下次判断变量时则为false,函数会依次运行。目的在于在一定的时间内,保证多次函数的请求只执行最后一次调用。(本段原文链接如下)

原文链接:https://blog.csdn.net/ZiChen_Jiang/article/details/121163381

代码片段:这里是使用了_.throttle这一属性,throttle本身就有节流阀的意思。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="./js/lodash.js"></script>
</head>
<body>
    <div>
        <h1>我是计数器<span>0</span></h1>
        <button>点我加上1</button>
    </div>
</body>
</html>
<script>
    //节流:在规定的间隔时间范围内不会重复触发回调,只有大于这个时间间隔才会触发回调,把频繁触发变为少量触发
    //获取节点
    let span = document.querySelector('span');
    let button = document.querySelector('button');
    let count = 0;
    //计数器:在一秒以内,数字只能加上1
    button.onclick = _.throttle(function(){
        //节流:目前这个回调函数5s执行一次
        //假如这里面有很多业务代码,是不是可以给浏览器很充裕的时间去解析
        count++;
        span.innerHTML = count;
        console.log('执行');
    },5000)
</script>

使用场景

懒加载、滚动加载、加载更多或监听滚动条位置;防止高频点击提交、防止表单重复提交

防抖与节流的区别

防抖:用户操作很频繁,但只会执行一次

节流:用户操作很频繁,但会把频繁操作变为少量操作

(三)使用标识解决购物车的bug

代码如下

二、element-ui的基本使用

  1. 控制台输入命令npm i element-ui进行安装

  1. 引入并应用插件,在main.js中输入以下代码

import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';

Vue.use(ElementUI);

但这样引入,资源内存过大,这时候需要按需引入

  1. 按需引入:控制台输入命令npm install babel-plugin-component -D进行安装

  1. 找到babel文件,进行如下的修改

  1. 因为在register和login组件中要使用提示框,所以需要我们在main.js文件中引入如下代码

三、注册组件的完成

(一)静态组件

  1. 将手机号、验证码、密码、确认密码、同意协议都绑定一个v-model

  1. 在data里进行定义,存储它们的值

(二)获取验证码+完成注册

  1. 在api/index.js文件中编写获取验证码的接口

// 该函数专门用于:获取验证码的状态
export const reqSendCode = (phone) => ajax.get(`/user/passport/sendCode/${phone}`)

2.回到组件文件里,在获取验证码的按钮上绑定点击事件,然后利用methods定义方法,import引入reqSendCode

3.完成注册

在api/index.js文件中编写完成注册的接口

// 该函数专门用于:完成注册
export const reqRegister = (paramsOdj) => ajax.post('user/passport/register',paramsOdj)

回到Registar组件里,在methods中编写完成注册的回调

四、登录组件的完成

(一)静态组件

copy准备好的文件,在手机号还有输入密码的input框都绑定v-model

在data里面赋予它们意义

(二)完成登录

回到api/index.js文件中编写登录的接口

// 该函数专门用于:用户登录
export const reqLogin = (paramsOdj) => ajax.post('/user/passport/login',paramsOdj)

回到Login组件里,在methods中编写完成登录的回调

在登录按钮上绑定点击事件,别忘了引入reqLogin

<button class="btn" @click="handleLogin">登&nbsp;&nbsp;录</button>

import { reqLogin } from "@/api";

五、token的理解

  1. token的本质就是字符串,唯一的;只有在用户登录成功后,服务器才会为用户生成一个token。

  1. token是用户真正的标识,最好是在localStorage中存储下。

为什么?为了能让用户打开浏览器后是自动登录状态

3.服务器在用户登录成功后,会向浏览器返回用户昵称、用户真实姓名、还有token,但我们只存token。

为什么?因为我们可以根据token找到用户更多的信息,而且服务器不会给多余的东西,只给一个token。

4.如果不允许多端登录,服务器要在用户登录之后,将之前的token销毁,再生成一个新的token。

5.token并不是长期有效的,到了过期时间,服务器就不再认可token了。

6.如果用户主动触发退出登录,那么服务器就会销毁该用户的token。

7.在utils/auth.js文件中编写代码存储token、读取token

login.vue方法里编写代码读取到用户唯一的token

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值