关注作者 ,取消关注作者逻辑
使用场景:登录,一直点击登录按钮,发送了很多的请求 ; 抢购 ; 关注,取消关注行为 ; 操作多次,必须要等待请求结果后在执行下一次
解决办法:节流 ;
设置变量 isLoading 控制发送请求的次数 ,这一次的请求结果没有返回就不会发送下一次的请求 ;
html :
<van-button v-if="articleInfo.is_followed" class="follow-btn" round size="small" @click="clickHandler" :loading="loading" >已关注</van-button > <van-button v-else :loading="loading" class="follow-btn" type="info" color="#3296fa" round @click="clickHandler" size="small" icon="plus" >关注</van-button >
按钮的loadign未false 的时候是加载转圈圈状态此时按钮是静止点击的,所以不能发送请求 ;
// 取消,关注作者 async clickHandler() { // console.log("发送"); /** * 按钮的loadign未false 的时候是加载转圈圈状态此时按钮是静止点击的,所以不能发送请求 */ this.loading = true; try { if (this.articleInfo.is_followed) { // 已关注,则取消 await delFollowAuthorApi(this.articleInfo.aut_id); } else { // 未关注,要关注 await getFollowAuthorApi({ target: this.articleInfo.aut_id, }); }
// 跟新视图(按钮的显示状态) this.articleInfo.is_followed = !this.articleInfo.is_followed; } catch (error) { console.log(error); // 请求失败 this.$toast.fail("请求失败"); } this.loading = false; },
切换到慢 3 g 网络查看 ;
把关注、取消关注作者封装一个组件 ;
components 的区分 : 多个页面使用的组件,和一个页面使用的组件(为了便于维护)
传给关注作者组件 2 个参数 , 是否被关注(请求返回的结果) ,作者 id ;
ps:自定义事件(子组件传递父组件传递值)的 $event 就是子组件的传递的数据值 ;
isFollow组件 :
<template> <van-button v-if="isFollow" class="follow-btn" round size="small" @click="clickHandler" :loading="loading" >已关注</van-button > <!-- 按钮的loading属性加载的时候是不允许再次点击的,从而控制了发送请求的频率 --> <van-button v-else :loading="loading" class="follow-btn" type="info" color="#3296fa" round @click="clickHandler" size="small" icon="plus" >关注</van-button > </template> <script> import { getFollowAuthorApi, delFollowAuthorApi } from "@/api/Article"; export default { name: "isFollow", props: { // 万一复用的那个组件的数据结构不是这样, // 是否被关注 isFollow: { type: Boolean, required: true, }, // 作者 id authorId: { // 规定类型是 数字或者字符串 type: [Number, String], required: true, }, }, data() { return { loading: false, // 节流阀 }; }, methods: { // 取消,关注作者 async clickHandler() { // console.log("发送"); /** * 按钮的loadign未false 的时候是加载转圈圈状态此时按钮是静止点击的,所以不能发送请求 */ this.loading = true; try { if (this.isFollow) { // 已关注,则取消 await delFollowAuthorApi(this.authorId); } else { // 未关注,要关注 await getFollowAuthorApi({ target: this.authorId, }); } // 跟新视图(更新按钮的显示状态),但是props的值不能直接修改,自定义事件给父组件修改然后再把值传递过来 // vue 的单向数据传递 // this.isFollow = !this.isFollow; // 错误的 ,违反了vue 的单向数据传递 // 每次修改值 this.$emit("updateFollow", !this.isFollow); } catch (error) { console.log(error); // 请求失败 this.$toast.fail("请求失败"); } this.loading = false; }, }, }; </script> <style> </style>
再父组件 传值 :
方式一:
<!-- 简写 --> <!-- 正常的事件click不写参数(实参)的时候,methods犯法写形参的时候就是 事件对象$event --> <!-- ps:$event 就是子组件传过来的数据值 --> <isFollow :isFollow="articleInfo.is_followed" :authorId="articleInfo.aut_id" @updateFollow="articleInfo.is_followed = $event" ></isFollow>
方式二 :
组件传值 :
<isFollow :isFollow="articleInfo.is_followed" :authorId="articleInfo.aut_id" @updateFollow="updateHandler" ></isFollow>
自定义事件方法:
// 更新关注状体 updateHandler(newState) { // newState 是子组件传递过来的数据 this.articleInfol.is_followed = newState; },
方法三:v-model的使用 (就是简化了写法)
使用场景:子组件既要使用某个变量,也要修改这个变量 ;
<isFollow :authorId="articleInfo.aut_id" v-model="articleInfo.is_followed" ></isFollow>
等价于:
ps:把组件的 props的 isFollow换成 value ,把自定义事件 updateFollow 换成 input ;
<isFollow :value="articleInfo.is_followed" v-on:input="articleInfo.is_followed = $event" :authorId="articleInfo.aut_id" ></isFollow>