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

Vue中$once的兩個實用小技巧分享

 更新時間:2022年04月27日 09:41:30   作者:江小皮  
$once是一個函數(shù),可以為Vue組件實例綁定一個自定義事件,但該事件只能被觸發(fā)一次,觸發(fā)之后隨即被移除,下面這篇文章主要給大家介紹了關(guān)于Vue中$once的兩個實用小技巧,需要的朋友可以參考下

前言

在 Vue 中有很多 API 都有很實用的地方,只是需要挖掘適用的場景,這里整理出了 $once 的兩個小技巧,也是在平常工作中用的比較多的,分享給大家,希望對大家能有幫助。

清除定時器

定時器大家用的應該也不少,像我一開始一般都是這樣寫的,在 created 中創(chuàng)建定時器,在 beforeDestroy 中銷毀定時器。

<script>
export default {
  name: "Timer",
  data() {
    return {
      timer: null,
      count: 0,
    };
  },
  created() {
    this.timer = setInterval(() => {
      this.count++;
    }, 1000);
  },
  beforeDestroy() {
    clearInterval(this.timer);
  },
};
</script>

開始的時候也沒有發(fā)現(xiàn)有什么問題,沒啥毛病。

后面慢慢的了解了更多,才發(fā)現(xiàn)里面確實是有幾個問題存在的:

  • 定時器的創(chuàng)建和銷毀放在了兩個生命周期中,很容易就忘記在 beforeDestroy 中去銷毀,從而導致內(nèi)存的不必要消耗,并且可讀性太差了,后續(xù)維護變困難;
  • 如果定時器的創(chuàng)建和銷毀在同一個生命周期中的話,那么 timer 其實也就沒必要使用響應式了,可以減少性能的浪費,直接在 created 中定義一個變量即可;
  • 在要銷毀的時候,只是清空了定時器,但是卻沒有把 timer 重置為 null,用完重置是個好習慣(定時器返回的值可以理解為這個定時器的 ID,通過這個 ID 來銷毀這個定時器)。

優(yōu)化后的版本是這樣的,可讀性好了很多,有點 composition API 那味兒了:),示例可以戳這里

export default {
  name: "OnceTimer",
  data() {
    return {
      count: 0,
    };
  },
  created() {
    let timer = setInterval(() => {
      this.count++;
    }, 1000);
    this.$once("hook:beforeDestroy", () => {
      clearInterval(timer);
      timer = null;
    });
  },
};

$once/$emit + async/await 實現(xiàn) Dialog 同步執(zhí)行

需求背景是這樣的:在全局有一個配置項showDialog,在點擊 查詢 的時候,如果這個配置項為 true,則需要 dialog 彈框讓用戶填寫一些數(shù)據(jù),當這個 dialog 彈框關(guān)閉之后,才能發(fā)出 confirm 的接口給后端,配置項為 false 時,則直接發(fā)送 confirm 的請求。

這里會有兩個問題:

  • 這個彈框和 confirm 這個操作并不是強相關(guān),我不能把 confirm 的請求邏輯放置在 dialog 彈框里;
  • 當控制彈框顯示的變量 visible 設為 true 時,js 邏輯會繼續(xù)往下執(zhí)行,即把 confirm 的請求邏輯執(zhí)行完了,請求就發(fā)送出去了,這不是我想要的結(jié)果。

我們來模擬一下這個過程,如下圖所示:

在點擊查詢之后,先輸出了 form submit(用來模擬點擊查詢后的發(fā)出請求),然后在點擊 dialog 彈框的確定之后,才輸出了 dialog confirm??梢钥吹近c擊查詢的接口先發(fā)出,點擊 dialog 彈框 確認的接口后發(fā)出。

解決這個問題可以從以下兩個方面入手:

  • dialog 的確認邏輯 與 confirm 發(fā)送請求的邏輯要解耦,不能寫在一起,不利于復用
  • confirm 的發(fā)送請求邏輯,要等 dialog 關(guān)閉之后,才能執(zhí)行,那我們就需要知道 dialog 彈框是什么時候關(guān)閉的。

有了這兩點之后,就可以想到可以利用 $once/$emit + promise + async/ await 來實現(xiàn)這一邏輯。

通過 $once/$emit 來進行通信,告知 dialog 關(guān)閉,通過 promise + async/ await 來使邏輯從異步變同步

我們來看下具體的代碼:

// dialog 組件
<template>
  <el-dialog
    title="提示"
    :visible.sync="dialogVisible"
    width="30%"
    :before-close="close"
  >
    <span>這是一段信息</span>
    <span slot="footer" class="dialog-footer">
      <el-button @click="close">取 消</el-button>
      <el-button type="primary" @click="confirm">確 定</el-button>
    </span>
  </el-dialog>
</template>

<script>
export default {
  props: ["dialogVisible"],
  data() {
    return {};
  },
  methods: {
    close() {
      this.$emit("before-dialog-close");
      this.$emit("update:dialogVisible", false);
    },
    confirm() {
      console.log("dialog confirm");
      this.close();
    },
  },
};
</script>
<template>
  <div>
    <el-form :inline="true" :model="formInline" class="demo-form-inline">
      <el-form-item label="審批人">
        <el-input v-model="formInline.user" placeholder="審批人"></el-input>
      </el-form-item>
      <el-form-item label="活動區(qū)域">
        <el-select v-model="formInline.region" placeholder="活動區(qū)域">
          <el-option label="區(qū)域一" value="shanghai"></el-option>
          <el-option label="區(qū)域二" value="beijing"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="onSubmit">查詢</el-button>
      </el-form-item>
    </el-form>
    <Dialog
      :dialogVisible.sync="visible"
      @before-dialog-close="() => this.$emit('beforeDialogClose')"
    />
  </div>
</template>
<script>
import Dialog from "./dialog";
export default {
  name: "Promise",
  components: {
    Dialog,
  },
  data() {
    return {
      formInline: {
        user: "",
        region: "",
      },
      // 控制 dialog 的展示
      visible: false,
      // 在業(yè)務中這是一個配置項
      showDialog: true,
    };
  },
  methods: {
    awaitDialogClose() {
      return new Promise((resolve) => {
        if (!this.visible) {
          resolve(null);
        }
        this.$once("beforeDialogClose", () => {
          resolve(null);
        });
      });
    },
    async onSubmit() {
      if (this.showDialog) {
        this.visible = true;
      }
      await this.awaitDialogClose();
      setTimeout(() => {
        console.log("form submit!");
      }, 1000);
    },
  },
};
</script>

效果如下:

在點擊查詢之后,我刻意的停留的一下,就是為了顯示點擊dialog確認的邏輯點擊查詢的請發(fā)邏輯之前執(zhí)行。

詳細代碼具體分析,可以看到主要的邏輯就是在 dialog 關(guān)閉之前,$emit 出一個事件,來告訴父組件,dialog 要關(guān)閉了。

// dialog 組件
close() {
  // 通知父組件dialog要關(guān)閉了
  this.$emit("before-dialog-close");
  // 關(guān)閉 dialog
  this.$emit("update:dialogVisible", false);
},

在父組件中,創(chuàng)建一個 promise,通過 $once 來等到 dialog 關(guān)閉的信號 。

// 發(fā)出信號
<Dialog
  :dialogVisible.sync="visible"
  @before-dialog-close="() => this.$emit('beforeDialogClose')"
/>
// 接收信號
awaitDialogClose() {
  return new Promise((resolve) => {
    // 當 dialog 沒彈框的時候,走這個邏輯,promise 直接結(jié)束
    if (!this.visible) {
      resolve(null);
    }
    // 當 dialog 要關(guān)閉的時候,$once 接收到了信號,promise 結(jié)束
    this.$once("beforeDialogClose", () => {
      resolve(null);
    });
  });
},

在 confirm 的點擊邏輯中,用一個 await 來保證 promsie 結(jié)束后,才往下繼續(xù)執(zhí)行。

async onSubmit() {
  // 當配置為 true 時,需要 dialog 彈框
  if (this.showDialog) {
    this.visible = true;
  }
  // promise 結(jié)束后,才會繼續(xù)往下執(zhí)行,否則就一直等待
  await this.awaitDialogClose();
  setTimeout(() => {
    console.log("form submit!");
  }, 1000);
},

至此,功能就完成了,這個功能適用場景還是很廣的(我也是請教了大佬才學會的),大家有興趣的也可以挖掘一些其他的使用場景。具體代碼在這里,有興趣的可以看一看呀。

可是在 Vue3 中,$once 被移除了,不過沒關(guān)系,Vue 官方也提出了可以替代的方法。

事件總線模式可以被替換為使用外部的、實現(xiàn)了事件觸發(fā)器接口的庫,例如 mitttiny-emitter

import emitter from 'tiny-emitter/instance'

export default {
  $once: (...args) =&gt; emitter.once(...args),
  $emit: (...args) =&gt; emitter.emit(...args),
}
復制代碼

總結(jié)

沒有無用的 API,只是沒有找到適用的場景。如果大家有更好的解決方法,也可以在評論區(qū)告訴我,讓我學習學習。

到此這篇關(guān)于Vue中$once實用小技巧的文章就介紹到這了,更多相關(guān)Vue $once小技巧內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • vue框架實現(xiàn)將側(cè)邊欄完全隱藏

    vue框架實現(xiàn)將側(cè)邊欄完全隱藏

    這篇文章主要介紹了vue框架實現(xiàn)將側(cè)邊欄完全隱藏,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • vue3中的ref與reactive使用方法對比

    vue3中的ref與reactive使用方法對比

    Vue3 提供了兩個新的 API:ref 和 reactive,它們可以幫助我們更好地管理和處理響應式數(shù)據(jù),這篇文章主要介紹了vue3中的ref與reactive的區(qū)別和使用方法,需要的朋友可以參考下
    2023-04-04
  • element表單驗證如何清除校驗提示語

    element表單驗證如何清除校驗提示語

    本文主要介紹了element表單驗證如何清除校驗提示語,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • Vue extend的基本用法(實例詳解)

    Vue extend的基本用法(實例詳解)

    這篇文章主要介紹了Vue extend的基本用法,本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-12-12
  • Vue中Mustache插值語法與v-bind指令詳解

    Vue中Mustache插值語法與v-bind指令詳解

    在Vue中通過Mustache語法(雙大括號)將data中的文本數(shù)據(jù)插入到HTML中,下面這篇文章主要給大家介紹了關(guān)于Vue中Mustache插值語法與v-bind指令的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-10-10
  • vue組件實現(xiàn)移動端九宮格轉(zhuǎn)盤抽獎

    vue組件實現(xiàn)移動端九宮格轉(zhuǎn)盤抽獎

    這篇文章主要為大家詳細介紹了vue組件實現(xiàn)移動端九宮格轉(zhuǎn)盤抽獎,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-10-10
  • vue部署后靜態(tài)文件加載404的解決

    vue部署后靜態(tài)文件加載404的解決

    這篇文章主要介紹了vue部署后靜態(tài)文件加載404的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • vue使用axios實現(xiàn)動態(tài)追加數(shù)據(jù)

    vue使用axios實現(xiàn)動態(tài)追加數(shù)據(jù)

    在vuejs中使用axios時,有時候需要追加數(shù)據(jù),比如,移動端下拉觸底加載,分頁加載,滑動滾動條等,下面小編就來為大家介紹一下如何使用使用axios實現(xiàn)動態(tài)追加數(shù)據(jù)吧
    2023-10-10
  • vue-cli是什么及創(chuàng)建vue-cli項目的方法

    vue-cli是什么及創(chuàng)建vue-cli項目的方法

    vue-cli是 vue 官方提供的、快速生成 vue 工程化項目的工具,支持創(chuàng)建vue2和vue3的項目,本文給大家詳細講解vue-cli是什么及創(chuàng)建vue-cli項目的方法,感興趣的朋友跟隨小編一起看看吧
    2023-04-04
  • Vue2與Vue3中Ref綁定元素方式

    Vue2與Vue3中Ref綁定元素方式

    這篇文章主要介紹了Vue2與Vue3中Ref綁定元素方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-11-11

最新評論