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