vue项目- 仿京东-功能整理

1.封装 axios

思路:

1.安装插件 axios
2.引入
3.封装
4.使用

// 单独创建一个页面  全局配置
import axios from 'axios'
// axios的全局配置
const instance = axios.create({
 	 baseURL: 'http://localhost:3000/api  api为数据接口中共同出现的',
  	 timeout: 10000
})
export default instance
import axios from "全局配置的地址";
export function getBanner(){
	return axios.then("/banner   为接口中不同的地方")
}

使用

import getBanner from "封装的地址";

mounted(){
	getBanner().then(data =>{
		data为数据
	})
}

2.上拉加载更多,下拉刷新

上拉加载思路:

1.引入vant 组件 上拉list
2.后端数据做了分页处理,获取接口数据,渲染到页面上,(此处只会显示一页的数据)
3.设置属性去实现效果,loading,finished为vant组件中提供的
4.每次滚动到底部后把页面数+1,发送一次请求获取新分页数据.
5.获取完数据,将新获取的数据跟上一页获取的数据做一个合并,
6.判断加载完毕,数据的长度小于1,则finished设置为true,表示所有数据加载完毕

代码:

      <!-- 上拉加载 -->
      <van-list
        v-model="loading"
        :finished="finished"
        finished-text="没有更多了"
        @load="onLoad"
      >
        <!-- 下拉刷新 -->
        <van-pull-refresh
          v-model="isLoading"
          success-text="刷新成功"
          @refresh="onRefresh"
        >
          <!-- 内容 -->
          <ul >
            <li v-for="item in prolist" 
            :key="item.proId" 
            class="commin-box" 
            @click="godetail(item.proId)">
              <img :src="item.img" />
              <p class="proName">{{ item.proName }}</p>
              <p class="price">¥ {{ item.price }}</p>
            </li>
          </ul>
        </van-pull-refresh>
      </van-list>

上拉加载:

初始设置loading 为true,数据加载成功,设置为false。
所有数据加载完设置 finished为false
(loading,finished为vant组件中提供的)
判断数据加载完毕:
数据的长度小于1 则判断数据加载完毕,

  onLoad() {
      // 开始异步请求数据
      this.loading = true;
      // 本次数据更新成功后,将loading设置为false
      getpro({
        num: this.num,  //num,一页获取多少个
        index: this.index++,   //index初始为0,页码
      }).then((data) => {
        this.loading = false;
        this.prolist = [...this.prolist, ...data.data.msg]; // 上一页数据跟新加载的数据做合并
        // 判断数据是否加载完毕
        if (data.data.msg.length < 1) {
          // 将finished设置为true,表示所有数据加载完毕
          this.finished = true;
        }
      });
    },

下拉刷新思路

1.引入vant 组件 下拉 PullRefresh
2.设置相对应属性,(vant中有提示)
3.相当于重新加载一遍数据
4.请求成功后覆盖重新渲染的数据,isLoading设置为false表示加载完毕,将页码初始化,设置为0
5.bug:原先老数据未被清除,新数据直接覆盖,内容中key值相同,组件被复用了,

** 解决:刷新这个路由 this.$router.go(0)**

代码:

   // 下拉刷新
    onRefresh() {
      getpro({
        num: this.num,
        index: this.index,
      }).then((data) => {
        this.prolist = data.data.msg;
        this.isLoading = false;
        this.index = 0; //页码也需要初始化
        this.finished = false //
      })
    },

3.回到顶部

思路:

1.设置图标,设置ref,设置点击事件 @click=“goToTop”
2.找到滚动的区域,设置ref,以及绑定滚动事件,@scroll=“onScroll”
3.获取滚动条top值,做判断。根据距离设置显示或隐藏,
4.点击图标,设置滚动距离为0,则回到顶部。

代码:

    onScroll() {
      // top 页面的滚动条值
      let top = this.$refs.main.scrollTop;
      if (top > 500) {
        // top大于 500 再显示,否则 隐藏
        this.$refs.toTop.style.display = "block";
      } else {
        this.$refs.toTop.style.display = "none";
      }
    },
    // 点击回到顶部
    goToTop() {
      // 点击后,滚动条距离为0
      this.$refs.main.scrollTop = 0;
    },

4.点击放大图片

思路:

1,vant中提供函数 ImagePreview,
2,给原每一个图片子元素设置点击事件,api中提供 initial-swipe 索引,拿到原图索引
3.设置change事件,保存大图切换的对应索引给到自己的 initial-swipe索引中
4,设置图片预览切换时,根据切换后的索引,设置原图的位置,大图原图同步
5.原图片 swipeTo(i) 切换到指定位置,

代码:

  <!-- 轮播图 -->
      <van-swipe
        class="my-swipe"
        :autoplay="3000"
        indicator-color="white"
        :initial-swipe="index" //自己定义的index值
        @change="onChange"
        ref="mySwipe"
      >
        <van-swipe-item
          v-for="item in imgList"
          :key="item"
          @click="onImgPreView"
        >
          <van-image 
            width="100vw" 
            height="3rem" 
            fit="contain" 
            :src="item" />
        </van-swipe-item>
      </van-swipe>

放大图片

    // 放大图片
    onImgPreView() {
      // 点击轮播图时,通过数据拿到当前索引,根据当前索引创建图片预览,设置默认图片
      const that = this;
      ImagePreview({
        images: this.imgList, //点击后的图片。
        startPosition: this.index, //index默认为0,提供的起始位置
        onChange(i) { 
          // 当图片预览切换时,根据切换后的索引,设置轮播图的位置
          that.$refs.mySwipe.swipeTo(i);
        },
      });
    },
   onChange(index) { //vant提供的索引值
      // 在轮播图切换时,将索引保存到数据中
      this.index = index;
   },

5,登录注册

注册思路:

1.设置正则判断,设置发送验证码,
发送验证码:

1.初始设置不可点击,输入手机号则可点击,
2.获得接口,发送用户输入的手机号到后端,后端判断手机号是否注册过,
3.设置点击后按钮的字样,多少秒后可再次发送。时间过去则更改按钮字样
4,设置是否可以点击,根据是否输入手机号,以及按钮内容
2.调用接口,获取数据,vant提交表单提供@submit可以直接获取到数据.发送用户输入的数据

代码:

<!-- 发送验证码 -->
<template #button>
  <van-form @submit="onSubmit">
     <van-button type="primary" 
        size="small" 
        :disabled="telsms" 
        @click="onSendSms">
        {{smsTitle}}
      </van-button>
<!-- 提交 -->
      <van-button round block
        type="info"
        class="but"
        native-type="submit"
        :disabled="alltest"
        >注册</van-button
      >
   </van-form>
</template>

// 设置发送按钮的时间
    onSendSms(){
       // 设置发送验证码间隔事件
      let time = 10
      // 修改按钮的提示文字
      this.smsTitle = time + 's后重新发送'
      // 开启计时器
      const t = setInterval(() => {
        // 判断时间是否走完
        if (time === 1) {
          // 清除计时器
          clearInterval(t)
          // 修改按钮文字
          this.smsTitle = '发送验证码'
        } else {
          // 一秒减1
          time--
          // 修改按钮文字
          this.smsTitle = time + 's后重新发送'
        }
      }, 1000)
//发送验证码
      sendSms({
        tel:Number(this.tel)
      }).then(data => {
        switch (data.data.code){
            case 200:
              Toast('验证码发送成功')
              break
            case 201:
              Toast('验证码再次发送成功')
              break
            case 202:
              Toast('手机号已被注册')
              break
            case 203:
              Toast(data.data.title)
              break
        }
      })
    },
  //设置 发送验证码。可点不可点,是否输入手机号,按钮内容
    telsms () {
     return this.teltest === '' || this.smsTitle !== '发送验证码'
    }

提交

    onSubmit (v) {
      const that = this
      register({
        username: v.username,
        password: v.password,
        tel: v.tel,
        code: v.sms
      }).then(data => {
        switch (data.data.code) {
          case 200:
            Toast({
              message: '注册成功',
              onClose () {
                that.$router.push('/login')//注册成功跳转到登录
              }
            })
            break
          case 201:
            Toast('用户名重复')
            break
          case 202:
            Toast('请先发送验证码')
            break
          case 203:
            Toast('手机号已被注册')
            break
          case 204:
            Toast('用户名已被注册')
            break
        }
      })
    },
 computed: {
    // 提交
    alltest() {
       return this.untest === '' || 
      this.pwtest === '' || 
      this.teltest === '' || 
      this.smstest === ''
    }
}

登录思路:

1.页面布局
2.调用接口,将用户输入数据发送后端,做验证,
3.验证成功,存储(后端发出的token,用户id,以及临时的登录状态)存储到本地。

代码:

    onSubmit1 (v) {
      const that = this
      login({
        username: v.username,
        password: v.password1
      }).then(data => {
        switch (data.data.code) {
          case 200:
            // 存储登录状态:token
            sessionStorage.setItem('token', data.data.token)
            // 存储用户id:msg
            sessionStorage.setItem('userId', data.data.msg)
            // 前端的临时的登录状态:isLogin:ok
            sessionStorage.setItem('isLogin', 'ok')
            Toast({
              message: '登录成功',
              onClose () {
                that.$router.push('/home')
              }
            })
            break
          case 201:
            Toast('用户名不存在')
            break
          case 202:
            Toast('密码错误')
            break
        }
      })
    },

拦截:

(麻烦,不安全,不使用)
1.在需要登录才可以近的页面设置拦截,
2.判断本地中存储的登录状态,‘isLogin’ !==‘ok’ 不OK 则拦截,直接跳转到登录。
3.则验证token是否有效,若’isLogin’ ==‘ok’,调用验证token的接口,向后端发送存储的token
4.验证失败则跳转登录页面

beforeCreate(){
  if(sessionStorage.getItem('isLogin')!=='ok'){
    this.$router.push('/login')
  }else{
    test({
      token.sessionStorage.getItem('token')
    }).then(data=>{
      if(data.data.code === 201){
        this.router.push('/login')
      }
    })
  }
}

axios拦截器:

1.请求拦截器的作用是在请求发送前进行一些操作,响应拦截器的作用是在接收到响应后进行一些操作
统一配置:
2.请求发送前给每个请求都添加token
3.接收到响应后,后台登录状态验证,不通过跳转到登录

// 单独创建一个页面  全局配置
import axios from 'axios'
// axios的全局配置
const instance = axios.create({
 	 baseURL: 'http://localhost:3000/api  api为数据接口中共同出现的',
  	 timeout: 10000 //超时
})
// 添加请求拦截器
instance.interceptors.request.use(function (config) {
  // 在发送请求之前做些什么
  // 给每个请求都添加,token
  config.headers.token = sessionStorage.getItem('token')
  // console.log('发送之前的配置对象:', config)
  // 添加loading
  return config
}, function (error) {
  // 对请求错误做些什么
  return Promise.reject(error)
})

// 添加响应拦截器
instance.interceptors.response.use(function (response) {
  // 对响应数据做点什么
  // 后台登录状态的验证,不通过,跳转到登录
  // 后台验证登录信息失败后的返回数据一定要统一:code:400
  if (response.data.code === 400) {
    location.href = 'http://localhost:8080/login'
  }
  // 删除loading
  return response
}, function (error) {
  // 对响应错误做点什么
  return Promise.reject(error)
})
export default instance
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王小王和他的小伙伴

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值