element-ui 的 Switch 組件封裝異步實現

需求場景

近期需求中,要作一個列表。列表中每項數據會有一個快捷啓用禁用入口。
clipboard.pngelement-ui

目前,項目使用的是 element-ui,裏邊有 Switch 組件,畫界面是很是容易的。緩存

問題

大概的邏輯是:用戶點擊這個 Switch 組件後,會發送一個請求。請求得到正確結果後,再切換 Switch 組件的狀態。
其中一種場景:用戶會快速連續點擊這個 Switch 組件,這樣請求就會連續被髮送。
還一種場景:請求結果是異常的,狀態不該該被改變。post

思考和方案

第一個問題處理方式能夠是:發送一個請求的時候,吧這個請求緩存起來,若是請求發送成功,再把這個緩存值清空。每次發請求以前都檢查這個緩存值是否爲空。若是緩存值存在,就取消上一次的請求。
還一種方法:添加一個disable的狀態,發送請求前把 Switch 組件變成 disable 狀態,請求發送有結果後,再把組件變成正常狀態。
第二個問題:element-ui 中其實要變動當前 Switch 按鈕狀態就是改變綁定值就能夠了。可是咱們再一個數據條數不肯定的列表中,並不合適去手動設定一個可控的綁定值。因此須要有一個做用域來控制變動單個 Switch 組件的狀態。因此想到了再次封裝 Switch 組件。ui

實現與編碼

首先,確認咱們組件要傳入:this

  • val: 當前狀態
  • reqUrl: 改變狀態 接口url
  • id: 標識這個狀態的id 要傳數據的 值
  • idName: 改變狀態要傳的數據字段名

其次,咱們再組建中建立一個變量,來綁定改組件的值。在建立這個組件的時候,把傳進來的狀態賦值給組件內的變量值。這樣就實現了局部控制。同時,用了一個 isDisabled 變量來控制組件的可用狀態。
固然,用了禁用方案,就不會怕用戶連續發送變動組件狀態了,因此檢測請求重複就取消上一個請求的操做是多餘的。不過這裏既然講了,就再組件中寫了實現的方法。
封裝後的組件源碼以下:編碼

<template>
  <div>
    <el-switch
            :value="value"
            @change="changeStatus"
            active-color="#13ce66" :disabled="isDisabled"
            inactive-color="#ff4949">
    </el-switch>
  </div>
</template>

<script>
  /**
   * val: 當前狀態
   * reqUrl: 改變狀態 接口url
   * id: 標識這個狀態的id 要傳數據的 值
   * idName: 改變狀態要傳的數據字段名
   * */
  export default {
    name:'switchItem',
    props:[
      'val',
      'reqUrl',
      'id',
      'idName',
    ],
    data() {
      return {
        value:false,
        setStatusHttp: null,
        isDisabled: false,
      }
    },
    created() {
      let self = this;
      self.value = self.val
    },
    methods:{
      changeStatus(){
        let self = this;
        self.isDisabled=true
        self.setStatus()
      },
      // setStatus
      setStatus(){
        let self = this;
        if (!self.setStatusHttp) {    // 判斷是否已經有請求正在發送
          self.setStatusHttpReq();
        } else {
          // abort 正在發送的請求 而後再次發送請求
          self.setStatusHttp()
          self.setStatusHttpReq();
        }
      },
      setStatusHttpReq(){
        let self = this;
        let CancelToken = self.$http.CancelToken
        let postData = {}
        postData[self.idName] = self.id
        self.$http.post(self.reqUrl,postData,{
          cancelToken: new CancelToken(function executor(c) {
            // An executor function receives a cancel function as a parameter
            self.setStatusHttp = c;
          })
        }).then(res => {
          if(res.data.error_code == '00000'){
            self.$message({
              type: 'success',
              message: '操做成功!'
            });
            self.value = !self.value
          }else{
            self.$message({
              type: 'error',
              message: res.data.message
            });
          }
          self.isDisabled=false
        })
      },
    }
  }
</script>

總結

當一個列表中,某個組件須要一個局部做用域來操做或者控制一些狀態的的時候,能夠對該組件再次進行封裝,這樣就會有一個組件的做用域,再這個做用域裏邊,咱們就能夠作一些騷操做來實現特殊場景的需求了。url

相關文章
相關標籤/搜索