vue3中使用二次封装函数式loading-button组件(vue组件模式)

238 阅读1分钟

一、单文件组件 loading-button

第一种

<template>
  <el-button ref="btnRef" v-bind="$attrs" :loading="loading">
    <slot>异步按钮</slot>
  </el-button>
</template>
<script setup lang="ts">
import { defineOptions, onMounted, ref, useAttrs } from 'vue'
defineOptions({
  name: 'AsyncButton',
})
const btnRef = ref()
const attrs = useAttrs()
const loading = ref(false)
const clickHandler = async () => {
  try {
    loading.value = true
    attrs?.onClick && (await (attrs as any)?.onClick?.())
    loading.value = false
  } catch (error) {
    loading.value = false
  }
}
onMounted(() => {
  const el = btnRef.value.ref
  el.addEventListener(
    'click',
    async (e: any) => {
      e.stopPropagation()
      await clickHandler()
    },
    { capture: true },
  )
})
</script>

第二种

<template>
  <el-button v-self-loading v-bind="$attrs" :loading="loading">
    <slot>异步按钮</slot>
  </el-button>
</template>
<script setup lang="ts">
import { defineOptions, ref, useAttrs } from 'vue'
defineOptions({
  name: 'AsyncButton',
})
const attrs = useAttrs()
const loading = ref(false)
const vSelfLoading = {
  created: (el: HTMLElement) => {
    el.addEventListener(
      'click',
      async (e) => {
        e.stopPropagation()
        await clickHandler()
      },
      { capture: true },
    )
  },
}
const clickHandler = async () => {
  try {
    loading.value = true
    attrs?.onClick && (await (attrs as any)?.onClick?.())
    loading.value = false
  } catch (error) {
    console.log(error)
    loading.value = false
  }
}
</script>