ホームページ  >  記事  >  ウェブフロントエンド  >  Vue コンポーネントの実践: 読み込みボタン コンポーネントの開発 -- LoadingButton

Vue コンポーネントの実践: 読み込みボタン コンポーネントの開発 -- LoadingButton

青灯夜游
青灯夜游転載
2022-05-23 20:24:524410ブラウズ

この記事では、非常に実用的な vueLoadingButton コンポーネント -- LoadingButton の開発を段階的に説明します。皆様のお役に立てれば幸いです。

Vue コンポーネントの実践: 読み込みボタン コンポーネントの開発 -- LoadingButton

#コンポーネントの背景

日々の業務では、次のような場面に遭遇することがよくあります。

Vue コンポーネントの実践: 読み込みボタン コンポーネントの開発 -- LoadingButton

ボタンをクリックするときにいくつかのインターフェイス データをリクエストします。ユーザーによる繰り返しのクリックを避けるために、通常、これらのボタンに読み込みを追加します。

loadingを追加する機能自体は非常に単純で、変数を定義してButtonコンポーネント内で使用するだけですが、バックグラウンド管理プロジェクトを行う場合には、このようなボタンが存在する可能性があります。 1 つのコンポーネント内の非常に多くの変数が xxx_loading になる可能性がありますが、これは時間と労力がかかり、十分に洗練されていません。

次に、

Button コンポーネントの単純なカプセル化を作成して、この時間と労働集約的で洗練されていない loading 問題を解決します。 (学習ビデオ共有: vue ビデオ チュートリアル )

インスピレーション ソース

使用しているのは

AntdModal ダイアログ ボックス、onOk非同期関数 の場合、Modal の [OK] ボタンは自動的に loading Effect を追加します。関数の実行が完了したら、次のようにポップアップ ウィンドウを閉じます。

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 の実装

コンポーネント パラメータの定義<span style="font-size: 18px;"></span>

ここでいくつか定義するだけです使用パラメータ:

text (ボタンのテキスト) , type (ボタンの種類) , asyncFunc (ボタンがクリックされたときに実行される非同期関数) , lay(読み込み遅延)、さらに、Button コンポーネントの状態を制御するには、コンポーネント内の loading 変数が必要です。コードは次のとおりです:

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: () => {}
        }
    },
}

<span style="font-size: 18px;"></span>antd<span style="font-size: 18px;"></span> で <span style="font-size: 18px;"></span>Button<span style="font-size: 18px;"></span> コンポーネントを使用します2 番目のステップのサブカプセル化を実行するには、<span style="font-size: 18px;"></span>#カスタム

LoadingButton

コンポーネントで、上で定義したパラメータを使用し、click イベントをバインドします。コードは次のとおりです: <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 { components: { Button }, methods: { handleClick() {} } } &lt;/script&gt;</pre>

Judge 非同期関数<span style="font-size: 18px;"></span>asyncFunc<span style="font-size: 18px;"></span>

Thisコンポーネント全体の最も重要な部分は、受信関数が非同期関数であるかどうかをどのように判断するかです。渡した
asyncFunc

関数が非同期関数である場合、コンポーネントは読み込みアニメーションを追加する必要があります。関数が非同期関数かどうかを判断するにはどうすればよいですか?

参考

antdどのように実装されますか? 上で

antd

Modal ダイアログ ボックスを紹介しました。このダイアログ ボックスにも同様のロジックがあるため、関連するドキュメントのこの部分を読むことをお勧めします。 antd の実装方法: <pre class="brush:js;toolbar:false;">// 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 &amp;&amp; ret.then) { this.setState({ loading: true }); ret.then( (...args) =&gt; { // It&amp;#39;s unnecessary to set loading=false, for the Modal will be unmounted after close. // this.setState({ loading: false }); closeModal(...args); }, e =&gt; { // 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(); } },</pre>

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
    })
  }
}
Test

LoadingButton

Componentこの時点で、コア コンポーネント ロジックは開発されました。後で、これが

LoadingButton
コンポーネントは期待どおりです: デモ コードは次のとおりです:

<pre class="brush:js;toolbar:false;">&lt;template&gt; &lt;div&gt; &lt;LoadingButton :delay=&quot;500&quot; :asyncFunc=&quot;asyncFunc&quot; /&gt; &lt;/div&gt; &lt;/template&gt; &lt;script&gt; import LoadingButton from &amp;#39;./LoadingButton.vue&amp;#39; export default { data() { return { loading: false } }, components: { LoadingButton }, methods: { asyncFunc() { return new Promise(resolve =&gt; { setTimeout(() =&gt; { resolve() }, 2000) }) } } } &lt;/script&gt;</pre> 実際のビジネスでの非同期リクエストをシミュレートするために、非同期関数

asyncFunc
を作成しました。効果を参照してください:

は以前に予想された効果と一致しているため、Vue コンポーネントの実践: 読み込みボタン コンポーネントの開発 -- LoadingButtonloading

を必要とする同様のシナリオがある場合は、

LoadingButton コンポーネントを使用して、実行する必要がある非同期関数をクリックします。これを渡すだけで、loading 変数を定義する必要はありません。

写在最后

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

<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 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はjuejin.cnで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。