You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Vue.js中使用Buefy对话框时实现单次触发功能?

解决Buefy Dialog Confirm重复触发问题

方法一:添加触发锁变量

在组件内新增一个状态变量,标记是否正在执行确认流程,避免重复触发弹窗或请求:

<script>
export default {
  data() {
    return {
      isConfirming: false
    }
  },
  methods: {
    async saveButton () {
      if (this.isConfirming) return
      this.isConfirming = true
      
      this.$dialog.confirm({
        message: 'SAVE',
        canCancel: ['escape', 'button'],
        cancelText: 'CANCEL',
        confirmText: 'OK',
        async onConfirm () {
          try {
            await this.saveAPI()
          } finally {
            this.isConfirming = false
          }
        },
        onCancel () {
          this.isConfirming = false
        }
      })
    },
    async saveAPI() {
      try {
        let data = await API.saveAPI
        return data
      } catch (error) {
        console.error('保存失败:', error)
      }
    }
  }
}
</script>

核心逻辑是用isConfirming做互斥校验:已在执行确认流程时直接返回,避免重复创建弹窗;确认完成或取消后重置变量,保证后续可正常触发。

方法二:替换弹窗按钮的事件监听

直接操作弹窗DOM,将确认按钮的默认事件替换为仅触发一次的版本:

<script>
export default {
  methods: {
    async saveButton () {
      const dialogInstance = this.$dialog.confirm({
        message: 'SAVE',
        canCancel: ['escape', 'button'],
        cancelText: 'CANCEL',
        confirmText: 'OK',
        onConfirm: () => {},
        onCancel: () => {}
      })

      this.$nextTick(() => {
        const confirmBtn = document.querySelector('.dialog-confirm-button')
        if (confirmBtn) {
          // 移除默认事件
          confirmBtn.removeEventListener('click', dialogInstance.confirm)
          confirmBtn.removeEventListener('keyup', dialogInstance.handleKeyup)
          
          // 添加仅触发一次的自定义事件
          const onceConfirm = async () => {
            await this.saveAPI()
            dialogInstance.close()
          }
          confirmBtn.addEventListener('click', onceConfirm, { once: true })
          confirmBtn.addEventListener('keyup', (e) => {
            if (e.key === 'Enter') onceConfirm()
          }, { once: true })
        }
      })
    },
    async saveAPI() {
      try {
        let data = await API.saveAPI
        return data
      } catch (error) {
        console.error('保存失败:', error)
      }
    }
  }
}
</script>

注意:Buefy确认按钮的类名是dialog-confirm-button,若使用不同版本需核对类名是否一致。

方法三:对保存函数做防抖处理

直接给saveAPI添加防抖逻辑,确保短时间内仅执行一次:

<script>
// 可引入lodash的防抖函数,或自行实现
import { debounce } from 'lodash'

export default {
  methods: {
    saveButton () {
      this.$dialog.confirm({
        message: 'SAVE',
        canCancel: ['escape', 'button'],
        cancelText: 'CANCEL',
        confirmText: 'OK',
        onConfirm: () => this.debouncedSaveAPI(),
        onCancel: () => {}
      })
    },
    async saveAPI() {
      try {
        let data = await API.saveAPI
        return data
      } catch (error) {
        console.error('保存失败:', error)
      }
    },
    // 500ms内重复调用仅执行一次,立即触发
    debouncedSaveAPI: debounce(async function() {
      await this.saveAPI()
    }, 500, { leading: true, trailing: false })
  }
}
</script>

若不想引入lodash,可自行实现简单防抖函数:

function debounce(func, wait, options = {}) {
  let timeoutId
  return function(...args) {
    if (!timeoutId && options.leading) {
      func.apply(this, args)
    }
    clearTimeout(timeoutId)
    timeoutId = setTimeout(() => {
      if (options.trailing !== false) {
        func.apply(this, args)
      }
      timeoutId = null
    }, wait)
  }
}

内容的提问来源于stack exchange,提问作者JohnZ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 09:20:17