> 웹 프론트엔드 > View.js > Vue 구성 요소 실습: 로딩 버튼 구성 요소 개발--LoadingButton

Vue 구성 요소 실습: 로딩 버튼 구성 요소 개발--LoadingButton

青灯夜游
풀어 주다: 2022-05-23 20:24:52
앞으로
4418명이 탐색했습니다.

이 기사는 매우 실용적인 vueLoadingButton 구성 요소를 개발하는 과정을 단계별로 안내할 것입니다. 모든 사람에게 도움이 되기를 바랍니다.

Vue 구성 요소 실습: 로딩 버튼 구성 요소 개발--LoadingButton

구성 요소 배경

일상 작업에서 다음과 같은 시나리오에 자주 직면합니다.

Vue 구성 요소 실습: 로딩 버튼 구성 요소 개발--LoadingButton

버튼을 클릭할 때 일부 인터페이스 데이터를 요청하고 사용자의 반복 클릭을 피하기 위해 일반적으로 이러한 버튼을 제공합니다. 추가 로딩으로. 로딩을 추가하는 기능은 변수를 정의하고 Button 컴포넌트에서 사용하기만 하면 매우 간단하지만, 백그라운드 관리 프로젝트를 수행할 때 이러한 버튼이 있을 수 있습니다. 하나의 구성 요소에서 많은 변수가 xxx_loading될 수 있으며 이는 시간이 많이 걸리고 노동 집약적이며 충분히 우아하지 않습니다. loading的功能本身时非常简单的,只要我们定义一个变量使用在Button组件中即可,但在做后台管理类项目时,这样的按钮可能会有非常非常多,可能一个组件中,很多变量都是xxx_loading,耗时耗力又不够优雅。

接下来,我们对Button组件做一个简单的封装来解决这个耗时耗力又不够优雅的loading问题。(学习视频分享:vue视频教程

灵感来源

我们在使用AntdModal对话框时,当我们的onOk异步函数时,此时Modal的确定按钮会自动添加loading效果,在函数执行完成后关闭弹窗,就像这样:

Vue 구성 요소 실습: 로딩 버튼 구성 요소 개발--LoadingButton

此时,代码如下:

asyncFunc() {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve()
    }, 2000)
  })
},
handleTestModal() {
  const that = this
  this.$confirm({
    title: '测试异步函数',
    content: '异步函数延迟两秒结束',
    async onOk() {
      await that.asyncFunc()
    }
  })
},
로그인 후 복사

看到这种效果后,就想到,如果可以封装一个Button组件,将需要执行的函数传入,组件中自动根据函数执行情况添加loading效果岂不是非常的方便。

实现LoadingButton

定义组件参数

这边就定义几个大家会常用到的参数:text(按钮文字)type(按钮类型)asyncFunc(按钮点击时执行的异步函数)delay(loading延迟),另外,还需要一个组件内部的loading变量来控制我们Button组件的状态,代码如下:

export default {
    data() {
        return {
          loading: false
        }
    },
    props: {
        text: {
          type: String,
          default: '确定'
        },
        type: {
          type: String,
          default: 'primary'
        },
        delay: {
          type: Number,
          default: 0
        },
        asyncFunc: {
          type: Function,
          default: () => {}
        }
    },
}
로그인 후 복사

使用<span style="font-size: 18px;">antd</span>中的<span style="font-size: 18px;">Button</span>组件进行二次封装

在我们的自定义LoadingButton组件中,将上面定义的参数使用起来,并绑定一个click事件,代码如下:

<template>
  <Button :type="type" :loading="loading" @click="handleClick">
    {{ text }}
  </Button>
</template>

<script>
import { Button } from &#39;ant-design-vue&#39;

export default {
    components: {
        Button
    },
    methods: {
        handleClick() {}
    }
}
</script>
로그인 후 복사

判断异步函数<span style="font-size: 18px;">asyncFunc</span>

这一部分为整个组件最重要的一个部分,即我们如何去判断传入的函数是异步函数,当我们传入的asyncFunc函数是异步函数时,组件才需要添加loading的动画,那么我们应该如何去判断一个函数是否为异步函数呢?

参考antd是如何实现的?

上面我们刚介绍了antdModal对话框中有类似的逻辑,那么不妨去阅读一下这部分相关的源码,看下antd的实现方式:

// components/modal/ActionButton.jsx

onClick() {
  const { actionFn, closeModal } = this;
  if (actionFn) {
    let ret;
    if (actionFn.length) {
      ret = actionFn(closeModal);
    } else {
      ret = actionFn();
      if (!ret) {
        closeModal();
      }
    }
    if (ret && ret.then) {
      this.setState({ loading: true });
      ret.then(
        (...args) => {
          // It&#39;s unnecessary to set loading=false, for the Modal will be unmounted after close.
          // this.setState({ loading: false });
          closeModal(...args);
        },
        e => {
          // Emit error when catch promise reject
          // eslint-disable-next-line no-console
          console.error(e);
          // See: https://github.com/ant-design/ant-design/issues/6183
          this.setState({ loading: false });
        },
      );
    }
  } else {
    closeModal();
  }
},
로그인 후 복사

阅读antd源码的实现,我们知道,判断一个函数是否是异步函数,可以通过判断函数是否有.then(ret && ret.then)方法,那么我们也可以类似的做一个判断,代码如下:

async handleClick() {
  const asyncFunc = this.asyncFunc
  if (!this.isFunc) {
    return
  }
  const ret = asyncFunc()

  // 如果是异步函数,则显示loading
  if (ret && ret.then) {
    this.loading = {
      delay: this.delay
    }
    ret.finally(() => {
      this.loading = false
    })
  }
}
로그인 후 복사

测试LoadingButton组件

到这里我们的最核心的组件逻辑就开发完成了,后面我们写一个demo来测试一下这个LoadingButton组件是否符合预期:demo代码如下:

<template>
  <div>
    <LoadingButton :delay="500" :asyncFunc="asyncFunc" />
  </div>
</template>

<script>
import LoadingButton from &#39;./LoadingButton.vue&#39;

export default {
  data() {
    return {
      loading: false
    }
  },
  components: {
    LoadingButton
  },
  methods: {
    asyncFunc() {
      return new Promise(resolve => {
        setTimeout(() => {
          resolve()
        }, 2000)
      })
    }
  }
}
</script>
로그인 후 복사

我们写了一个异步函数asyncFunc用来模拟实际业务中的异步请求,现在可以看下效果:

Vue 구성 요소 실습: 로딩 버튼 구성 요소 개발--LoadingButton

符合之前的预期效果,这样我们再有类似需要loading的场景时,就可以直接使用LoadingButton组件,将点击需要执行的异步函数传入即可,不需要再去定义loading

다음으로, 시간이 많이 걸리고 노동 집약적이며 우아하지 않은 로딩 문제를 해결하기 위해 Button 구성 요소를 간단히 캡슐화합니다. (학습 영상 공유: vue video tutorial🎜)🎜🎜🎜영감 출처 🎜🎜
🎜저희는 Antd🎜의 를 사용하고 있습니다. 모달 대화 상자에서 onOk비동기 함수인 경우 Modal의 확인 버튼을 누르면 자동으로 로딩<이 추가됩니다. /code> 효과를 적용하려면 다음과 같이 함수 실행이 완료된 후 팝업 창을 닫습니다. 🎜</blockquote>🎜<img src="https://img.php.cn/upload/image/830/468/ 888 /1653308365937765.gif" title="1653308365937765.gif" alt="Vue 구성 요소 실습: 로딩 버튼 구성 요소 개발--LoadingButton"/>🎜🎜 이때 코드는 다음과 같습니다. 🎜<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false;">&lt;template&gt; &lt;Button :type=&quot;type&quot; :loading=&quot;loading&quot; @click=&quot;handleClick&quot;&gt; {{ text }} &lt;/Button&gt; &lt;/template&gt; &lt;script&gt; import { Button } from &amp;#39;ant-design-vue&amp;#39; export default { data() { return { loading: false } }, props: { text: { type: String, default: &amp;#39;确定&amp;#39; }, type: { type: String, default: &amp;#39;primary&amp;#39; }, delay: { type: Number, default: 0 }, asyncFunc: { type: Function, default: () =&gt; {} } }, components: { Button }, computed: { isFunc() { return typeof this.asyncFunc === &amp;#39;function&amp;#39; } }, methods: { async handleClick() { const asyncFunc = this.asyncFunc if (!this.isFunc) { return } const ret = asyncFunc() // 如果是异步函数,则显示loading if (ret &amp;&amp; ret.then) { this.loading = { delay: this.delay } ret.finally(() =&gt; { this.loading = false }) } } } } &lt;/script&gt;</pre><div class="contentsignin">로그인 후 복사</div></div><div class="contentsignin">로그인 후 복사</div></div><blockquote>🎜 이 효과를 보고 생각한 것은, <code>Button 구성요소를 캡슐화하여 실행해야 하는 함수를 전달할 수 있는데, 함수에 따라 구성요소에 로딩 효과를 자동으로 추가하는 것이 매우 편리하지 않을까요? 실행 상태. 🎜
🎜🎜LoadingButton 구현🎜🎜🎜🎜구성요소 매개변수 정의🎜🎜🎜다음은 일반적으로 사용되는 매개변수입니다.< 코드>텍스트(버튼 텍스트 ), type(버튼 유형), asyncFunc(버튼을 클릭할 때 실행되는 비동기 함수), delay(로딩 지연) 또한 Button 구성 요소의 상태를 제어하려면 구성 요소 내부에 loading 변수도 필요합니다. 코드는 다음과 같습니다. 🎜rrreee🎜🎜사용<span style="font-size: 18px;">antd</span><span style="font-size: 18px;">버튼</span> 구성요소가 다시 캡슐화되었습니다. 🎜🎜🎜사용자 정의 LoadingButton 구성 요소에서 위에 정의된 매개 변수를 사용하고 click 이벤트를 바인딩합니다. 코드는 다음과 같습니다. 🎜rrreee 🎜🎜비동기 함수 판단<span style="font-size: 18px;">asyncFunc</span>🎜🎜< blockquote>🎜This 부분은 전체 구성 요소 중 가장 중요한 부분입니다. 즉, 전달된 함수가 비동기 함수인지 어떻게 확인합니까? 구성 요소는 우리가 전달하는 asyncFunc 함수가 다음과 같은 경우에만 추가되어야 합니까? 비동기 함수 로딩 애니메이션이라면 함수가 비동기 함수인지 어떻게 판단해야 할까요? 🎜🎜🎜참고: antd는 어떻게 구현되나요? 🎜🎜🎜방금 antdModal 대화 상자에도 비슷한 논리가 있다고 소개했으니, 이 부분의 관련 소스 코드를 읽고 < code>antd 구현 방법: 🎜rrreee🎜 antd 소스 코드 구현을 읽어보세요. 함수가 비동기 함수인지 판단하려면 함수에 < code>.then (ret && ret.then) 메서드를 사용하면 비슷한 판단을 내릴 수도 있습니다. 코드는 다음과 같습니다. 🎜rrreee🎜🎜LoadingButton<을 테스트하세요. /code> 컴포넌트🎜🎜<blockquote>🎜to 여기서 핵심 컴포넌트 로직이 개발되었습니다. 나중에 <code>LoadingButton 컴포넌트가 기대치를 충족하는지 테스트하기 위해 데모를 작성하겠습니다. 데모 코드는 다음과 같습니다. 🎜 rrreee🎜실제 비즈니스에서 비동기 요청을 시뮬레이션하는 데 비동기 함수 asyncFunc를 사용했습니다. 이제 그 효과를 확인할 수 있습니다. 🎜🎜Vue 구성 요소 실습: 로딩 버튼 구성 요소 개발--LoadingButton🎜🎜는 이전에 예상했던 효과와 일치하므로 로드가 필요한 유사한 시나리오에서는 LoadingButton 구성 요소를 직접 사용하고 클릭 시 실행되어야 하는 비동기 함수를 전달할 수 있습니다. >로드 중 변수. 🎜

写在最后

这个组件其实核心的代码非常少,也很容易读懂。由于最近在做一些业务这类场景比较多,感觉这个小组件还是挺实用的所以分享给大家,这里也是只对最重要的部分做了一个介绍,相信大家学会了之后也可以通过这个方式封装出符合自己实际场景需求的组件。最后,附上这个组件的完整代码:

<template>
  <Button :type="type" :loading="loading" @click="handleClick">
    {{ text }}
  </Button>
</template>

<script>
import { Button } from &#39;ant-design-vue&#39;

export default {
  data() {
    return {
      loading: false
    }
  },
  props: {
    text: {
      type: String,
      default: &#39;确定&#39;
    },
    type: {
      type: String,
      default: &#39;primary&#39;
    },
    delay: {
      type: Number,
      default: 0
    },
    asyncFunc: {
      type: Function,
      default: () => {}
    }
  },
  components: {
    Button
  },
  computed: {
    isFunc() {
      return typeof this.asyncFunc === &#39;function&#39;
    }
  },
  methods: {
    async handleClick() {
      const asyncFunc = this.asyncFunc
      if (!this.isFunc) {
        return
      }
      const ret = asyncFunc()

      // 如果是异步函数,则显示loading
      if (ret && ret.then) {
        this.loading = {
          delay: this.delay
        }
        ret.finally(() => {
          this.loading = false
        })
      }
    }
  }
}
</script>
로그인 후 복사
로그인 후 복사

原文地址:https://juejin.cn/post/7099234795720278046

作者:liangyue

(学习视频分享:web前端开发编程基础视频

위 내용은 Vue 구성 요소 실습: 로딩 버튼 구성 요소 개발--LoadingButton의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:juejin.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿