Vue2/3封装按钮Loding
1、Vue3
基于如下平常代码,我们可以发现,两个按钮逻辑中,有很多重复代码(开启loding
,关闭loding
),并且正式项目中会有很多按钮会发送请求
< template>
< el-button @click = " test" :loading = " loading" type = " primary" > test</ el-button>
< el-button @click = " test" :loading = " loading22" type = " primary" > test2</ el-button>
</ template>
< script setup >
import { ref } from "vue" ;
const loading1 = ref ( false ) ;
const loading2 = ref ( false ) ;
function test ( ) {
loading1. value = true ;
try {
fetch ( "http://localhost:8888/getUser?userName=''" )
. then ( ( res ) => {
return res. json ( ) ;
} )
. then ( ( res ) => {
console. log ( res) ;
} ) ;
} finally {
loading1. value = false ;
}
}
function test ( ) {
loading2. value = true ;
try {
fetch ( "http://localhost:8888/getUser2?userName=" )
. then ( ( res ) => {
return res. json ( ) ;
} )
. then ( ( res ) => {
console. log ( res) ;
} ) ;
} finally {
loading2. value = false ;
}
}
</ script>
1.1、组件代码
< template>
< el-button :loading = " loading" v-bind = " $attrs" @click = " handleClick" >
< slot> </ slot>
</ el-button>
</ template>
< script setup >
import { ref, useAttrs } from "vue" ;
const loading = ref ( false ) ;
const attrs = useAttrs ( ) ;
const { onClick } = defineProps ( {
onClick: Function,
} ) ;
async function handleClick ( ) {
console. log ( "click" ) ;
loading. value = true ;
try {
await onClick?. ( ) ;
} finally {
loading. value = false ;
}
}
</ script>
1.2、使用组件
< template>
< MyLoadingBtn @click = " test" type = " primary" > test</ MyLoadingBtn>
</ template>
< script setup >
import { ref } from "vue" ;
import MyLoadingBtn from "./components/MyLoadingBtn.vue" ;
async function test ( ) {
await fetch ( "http://localhost:8888/getUser?userName=" )
. then ( ( res ) => {
return res. json ( ) ;
} )
. then ( ( res ) => {
console. log ( res) ;
} )
. catch ( ( err ) => {
console. log ( err) ;
} ) ;
}
</ script>
1.3、效果
2、Vue2
Vue2
中和Vue3
中逻辑基本一致,不过要稍微麻烦一点因为Vue2
中父组件传递的所有方法,并不会一起放到$attrs
中,而是会放到$listeners
中 ,使用不了**在props中声明,
a
t
t
r
s
对象中不存在的特性
∗
∗
,那么我们就需要对
‘
attrs对象中不存在的特性**,那么我们就需要对`
a tt rs 对象中不存在的特性 ∗ ∗ ,那么我们就需要对 ‘ listeners对象单独处理一下再绑定到
v-on=“xxx”`中 如果不处理$listeners.click
函数的话,那么父组件绑定的点击事件函数就会调用两遍!!
2.1、组件代码
< template>
< el-button
:loading = " loading"
v-bind = " $attrs"
v-on = " listeners"
@click = " handleClick"
>
< slot> </ slot>
</ el-button>
</ template>
< script>
export default {
name: "MyLoadingBtn" ,
data ( ) {
return {
loading: false ,
} ;
} ,
computed: {
listeners ( ) {
const copy = { ... this . $listeners } ;
delete copy. click;
return copy;
} ,
} ,
methods: {
async handleClick ( ) {
console. log ( "click" ) ;
const fun = this . $listeners;
this . loading = true ;
try {
await fun. click?. ( ) ;
} finally {
this . loading = false ;
}
} ,
} ,
} ;
</ script>
2.2、使用组件
< template>
< div class = " test1" >
< MyLoadingBtn type = " primary" @click = " handleClick" > 测试 </ MyLoadingBtn>
</ div>
</ template>
< script>
import MyLoadingBtn from "@/components/MyLoadingBtn.vue" ;
export default {
components: {
MyLoadingBtn,
} ,
methods: {
async handleClick ( ) {
await fetch ( "http://localhost:8888/getUser?userName=" )
. then ( ( res ) => {
return res. json ( ) ;
} )
. then ( ( res ) => {
console. log ( res) ;
} ) ;
} ,
} ,
} ;
</ script>
2.3、效果