欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

對于防止按鈕重復(fù)點(diǎn)擊的嘗試詳解

 更新時(shí)間:2019年04月22日 11:48:43   作者:Idiot  
這篇文章主要介紹了對于防止按鈕重復(fù)點(diǎn)擊的嘗試,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

導(dǎo)語:隨著接觸的項(xiàng)目增加,很多項(xiàng)目都是遇到同樣的問題,而每次都是使用一貫的手法進(jìn)行處理。有時(shí)候有些方法并不是那么的優(yōu)雅甚至有些冗余,所以自己也想開始嘗試不同的方法去解決同樣的問題。

我經(jīng)常在項(xiàng)目中會(huì)遇到按鈕重復(fù)點(diǎn)擊后引起表單的重復(fù)點(diǎn)擊問題。所以針對這個(gè)問題,自己嘗試了幾種辦法分別去解決。直接上代碼。

1.粗暴簡單辦法

直接定義一個(gè)變量,每次點(diǎn)擊過后等所有操作結(jié)束后釋放變量?;蚴褂胠oading防止用戶點(diǎn)擊

//* 部分代碼
<script>
export default {
  methods: {
    onSubmit() {
      if (this.lock) return;
      this.lock = true;
      // const load = this.$loading();
      this.$http.create().then((res) => {
        // do something
        this.lock = false;
        // load.close();
      }).catch(() => {
        this.lock = false;
        // load.close();
      })
    }, 
  },
}
</script>

這種辦法簡單粗暴,但是每次需要防止重復(fù)點(diǎn)擊的地方,都要去關(guān)注lock或者loading的重置,總覺的很啰嗦。也沒辦法好好的抽離出來。(PS:能力有限,自己也沒有想到比較好的辦法在上層優(yōu)雅的封裝出來)

2.直接把loading放到http請求中去做,統(tǒng)一封裝方法

//* 部分代碼
...
let load;
http.interceptors.request.use((config) => {
  load = Loading();
  ...
  return config;
}, error => {
  load.close();
  return Promise.reject(error)
});

http.interceptors.response.use((response) => {
  load.close();
  ...
  return response; 
},error => {
  load.close();
  return Promise.reject(error);
});

這種辦法在實(shí)際中也用過了一段時(shí)間,一開始挺好用的,但是在后面自己弱網(wǎng)測試的時(shí)候發(fā)現(xiàn)也是會(huì)導(dǎo)致重復(fù)點(diǎn)擊的情況。而且在有些時(shí)候loading圖并不是所有請求都需要,還要去做個(gè)是否顯示loading的配置,這樣感覺http請求又笨重了,也沒有讓重復(fù)點(diǎn)擊功能抽離出來。

3.裝飾器方法

說到裝飾器,最經(jīng)典的應(yīng)用場景就是面向切片編程(AOP),《前端常用設(shè)計(jì)模式(1)--裝飾器(decorator)》juejin.im/post/5cb415… 做出了很棒的理解與應(yīng)用。得益于ES7和TS,裝飾器在Angular和react中都有很多案例,因?yàn)閂ue中Class不是必選,所以在Vue中很少看到使用裝飾器的,得益于官方有vue-class-component來使用Class進(jìn)行創(chuàng)建組件的方法,開始了自己的嘗試之路。

lock.js

export function lock(target, key, desc) {
  const fn = desc.value;
  //* 沒有使用箭頭函數(shù)是為了讓this能指回到vue,這樣就可以獲取到vue的data,從而做更多的事情,下面會(huì)講到
  desc.value = async function() {
    if (this.$lock) return;
    this.$lock = true;
    await fn.apply(this).catch(() => {
      this.$lock = false;
    });
    this.$lock = false;
    return target;
  };
}

index.vue

<template>
  <!-- do something -->
</template>
<script>
import Vue from 'vue';
import Component from 'vue-class-component';
import { lock } from './lock';

@Component
export default class extends Vue {
  @lock
  async onSubmit() {
    await this.$http.create();
    // do something
  }
}
</script>

感覺這樣就完全抽離了重復(fù)點(diǎn)擊的功能(PS:好像是這樣的),也能獨(dú)立測試,想在哪里用就在哪里用。感覺不足的是,裝飾器里需要讓this重新指回vue才能獲取到vue的data

4.舉一反三

既然重復(fù)點(diǎn)擊可以從業(yè)務(wù)代碼中抽離出來,那我們提交表單的字段驗(yàn)證也就同樣可以抽離出來了。(PS:所有UI框架都有成熟的form表單驗(yàn)證組件,就當(dāng)我是瞎折騰)

validate.js

export function validate(target, key, desc) {
 const fn = desc.value;

 desc.value = async function () {
  const {
   name, phone,
  } = this.data;
  
  if (!name) {
   return confirm('請輸入您的姓名');
  }
  if (name.length > 20) {
   return confirm('您的姓名不能超過20個(gè)字');
  }
  if (!phone) {
   return confirm('請輸入您的電話');
  }
  if (!((/^\d{11}$/.test(phone)))) {
   return confirm('請輸入11位的電話號碼');
  }
  
  await fn.apply(this);
  return target;
 };
}

index.vue

<template>
  <!-- do something -->
</template>
<script>
import Vue from 'vue';
import Component from 'vue-class-component';
import { validate } from './validate';

@Component
export default class extends Vue {
  data = {
    name: '',
    phone: '',
  }
  
  @validate
  async onSubmit() {
    await this.$http.create();
    // do something
  }
}
</script>

5.防抖方法(補(bǔ)充)

有小伙伴說可以使用防抖,個(gè)人覺得還是需要看場景,這里也就列出防抖的方法。

防抖方法是一個(gè)很好限制重復(fù)事件頻繁觸發(fā)的,經(jīng)常用在scroll、resize事件上,也可以嘗試用在重復(fù)點(diǎn)擊上面。但是如果點(diǎn)擊事件后需要有異步處理,單單使用防抖方法也會(huì)沒辦法限制弱網(wǎng)(PS:吐槽一下成都地鐵上移動(dòng)經(jīng)常網(wǎng)絡(luò)不好)下重復(fù)點(diǎn)擊的情況。如:防抖時(shí)間為1秒,但是請求花掉了2秒才返回?cái)?shù)據(jù)給前端進(jìn)行處理,中間產(chǎn)生了時(shí)間差,導(dǎo)致用戶有時(shí)間重復(fù)點(diǎn)擊。所以個(gè)人覺得還是需要配合其它辦法。同樣列出防抖的列子:

throttle.js

const throttle = function(fn, wait, scope) {
  clearTimeout(throttle.timer);
  throttle.timer = setTimeout(function() {
    fn.apply(scope);
  }, wait);
};

index.vue

<template>
  <!-- do something -->  
</template>
<script>
export default {
  onSubmit() {
    throttle(() => {
      this.$http.create().then((result) => {
        // do something
      });
    }, 1000);
  },
};
</script>

以上所述是小編給大家介紹的對于防止按鈕重復(fù)點(diǎn)擊的嘗試詳解整合,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!

相關(guān)文章

最新評論