이 기사는 매우 실용적인 vueLoadingButton 구성 요소를 개발하는 과정을 단계별로 안내할 것입니다. 모든 사람에게 도움이 되기를 바랍니다.
일상 작업에서 다음과 같은 시나리오에 자주 직면합니다.
버튼을 클릭할 때 일부 인터페이스 데이터를 요청하고 사용자의 반복 클릭을 피하기 위해 일반적으로 이러한 버튼을 제공합니다. 추가 로딩으로. 로딩
을 추가하는 기능은 변수를 정의하고 Button
컴포넌트에서 사용하기만 하면 매우 간단하지만, 백그라운드 관리 프로젝트를 수행할 때 이러한 버튼이 있을 수 있습니다. 하나의 구성 요소에서 많은 변수가 xxx_loading
될 수 있으며 이는 시간이 많이 걸리고 노동 집약적이며 충분히 우아하지 않습니다. loading
的功能本身时非常简单的,只要我们定义一个变量使用在Button
组件中即可,但在做后台管理类项目时,这样的按钮可能会有非常非常多,可能一个组件中,很多变量都是xxx_loading
,耗时耗力又不够优雅。
接下来,我们对Button
组件做一个简单的封装来解决这个耗时耗力又不够优雅的loading
问题。(学习视频分享:vue视频教程)
我们在使用Antd的
Modal
对话框时,当我们的onOk
为异步函数
时,此时Modal
的确定按钮会自动添加loading
效果,在函数执行完成后关闭弹窗,就像这样:
此时,代码如下:
asyncFunc() { return new Promise(resolve => { setTimeout(() => { resolve() }, 2000) }) }, handleTestModal() { const that = this this.$confirm({ title: '测试异步函数', content: '异步函数延迟两秒结束', async onOk() { await that.asyncFunc() } }) },
看到这种效果后,就想到,如果可以封装一个
Button
组件,将需要执行的函数传入,组件中自动根据函数执行情况添加loading
效果岂不是非常的方便。
定义组件参数
这边就定义几个大家会常用到的参数: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 'ant-design-vue' export default { components: { Button }, methods: { handleClick() {} } } </script>
判断异步函数<span style="font-size: 18px;">asyncFunc</span>
这一部分为整个组件最重要的一个部分,即我们如何去判断传入的函数是异步函数,当我们传入的
asyncFunc
函数是异步函数时,组件才需要添加loading的动画,那么我们应该如何去判断一个函数是否为异步函数呢?
参考antd
是如何实现的?
上面我们刚介绍了antd
的Modal
对话框中有类似的逻辑,那么不妨去阅读一下这部分相关的源码,看下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'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 './LoadingButton.vue' export default { data() { return { loading: false } }, components: { LoadingButton }, methods: { asyncFunc() { return new Promise(resolve => { setTimeout(() => { resolve() }, 2000) }) } } } </script>
我们写了一个异步函数asyncFunc
用来模拟实际业务中的异步请求,现在可以看下效果:
符合之前的预期效果,这样我们再有类似需要loading
的场景时,就可以直接使用LoadingButton
组件,将点击需要执行的异步函数传入即可,不需要再去定义loading
로딩
문제를 해결하기 위해 Button
구성 요소를 간단히 캡슐화합니다. (학습 영상 공유: vue video tutorial🎜)🎜🎜🎜영감 출처 🎜🎜🎜저희는 Antd🎜의🎜🎜LoadingButton 구현🎜🎜🎜🎜구성요소 매개변수 정의🎜🎜🎜다음은 일반적으로 사용되는 매개변수입니다.< 코드>텍스트(버튼 텍스트 ),를 사용하고 있습니다. 모달
대화 상자에서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;"><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></pre><div class="contentsignin">로그인 후 복사</div></div><div class="contentsignin">로그인 후 복사</div></div><blockquote>🎜 이 효과를 보고 생각한 것은, <code>Button
구성요소를 캡슐화하여 실행해야 하는 함수를 전달할 수 있는데, 함수에 따라 구성요소에로딩
효과를 자동으로 추가하는 것이 매우 편리하지 않을까요? 실행 상태. 🎜
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
는 어떻게 구현되나요? 🎜🎜🎜방금 antd
의 Modal
대화 상자에도 비슷한 논리가 있다고 소개했으니, 이 부분의 관련 소스 코드를 읽고 < code>antd 구현 방법: 🎜rrreee🎜 antd
소스 코드 구현을 읽어보세요. 함수가 비동기 함수인지 판단하려면 함수에 < code>.then (ret && ret.then
) 메서드를 사용하면 비슷한 판단을 내릴 수도 있습니다. 코드는 다음과 같습니다. 🎜rrreee🎜🎜LoadingButton<을 테스트하세요. /code> 컴포넌트🎜🎜<blockquote>🎜to 여기서 핵심 컴포넌트 로직이 개발되었습니다. 나중에 <code>LoadingButton
컴포넌트가 기대치를 충족하는지 테스트하기 위해 데모를 작성하겠습니다. 데모 코드는 다음과 같습니다. 🎜 rrreee🎜실제 비즈니스에서 비동기 요청을 시뮬레이션하는 데 비동기 함수 asyncFunc
를 사용했습니다. 이제 그 효과를 확인할 수 있습니다. 🎜🎜🎜🎜는 이전에 예상했던 효과와 일치하므로 로드
가 필요한 유사한 시나리오에서는 LoadingButton
구성 요소를 직접 사용하고 클릭 시 실행되어야 하는 비동기 함수를 전달할 수 있습니다. >로드 중 변수. 🎜这个组件其实核心的代码非常少,也很容易读懂。由于最近在做一些业务这类场景比较多,感觉这个小组件还是挺实用的所以分享给大家,这里也是只对最重要的部分做了一个介绍,相信大家学会了之后也可以通过这个方式封装出符合自己实际场景需求的组件。最后,附上这个组件的完整代码:
<template> <Button :type="type" :loading="loading" @click="handleClick"> {{ text }} </Button> </template> <script> import { Button } from 'ant-design-vue' 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: () => {} } }, components: { Button }, computed: { isFunc() { return typeof this.asyncFunc === 'function' } }, 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
위 내용은 Vue 구성 요소 실습: 로딩 버튼 구성 요소 개발--LoadingButton의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!