vue防止重复点击提交公共方法

import Vue from ‘vue’

// 防止重复提交指令
const preventReClick = Vue.directive(‘preventReClick’, {
inserted (el, binding) {
el.addEventListener(‘click’, () => {
if (!el.disabled) {
el.disabled = true
setTimeout(() => {
el.disabled = false
}, binding.value || 3000)
}
})
}
})

export { preventReClick }
然后在main.js引用Vue.use(preventReClick);
在页面上需要防止重复点击的地方写v-preventReClick就好了

<think>嗯,用户的问题是关于在Vue3中使用JavaScript创建一个可复用的方法,根据props.productCategory进行重复字段检查,并动态生成针对不同类别的错误提示,比如PRODUCT_LINE、LOCAL_PRODUCT_LINE和Model。我需要结合他们提供的引用内容来找到合适的解决方案。 首先,用户提到的引用[1]里比较了Pinia和Vuex,指出Pinia更适合Vue3的组合式API,所以可能建议使用Pinia来管理状态,尤其是处理重复检查的状态。引用[3]提到后台返回的数据结构需要有code、message、data,这可能和错误提示的处理有关,需要确保返回的格式正确。引用[4]关于vite配置中的vue插件,可能和项目配置相关,但暂时不直接影响逻辑。引用[5]的问题是关于Excel解析,可能和数据处理有关,但当前问题更侧重于前端验证。 用户的需求是创建一个可复用的方法,根据不同的产品类别检查重复字段,并动态生成错误消息。这里需要考虑到组合式API的使用,比如使用computed或watch来响应props的变化,以及使用Pinia来管理全局的校验状态或者存储已存在的数据。 可能的步骤是:1. 使用组合式函数(如useDuplicateCheck)封装校验逻辑,利用props.productCategory判断当前类别。2. 在Pinia store中存储各分类的已存在数据,并通过API获取。3. 根据不同的类别映射不同的错误消息,比如使用对象或Map来关联类别和消息。4. 在组件中调用这个可复用的方法,处理输入并显示错误提示。 需要注意的地方:确保props的响应性,在组合式函数中使用toRefs来转换props;处理异步校验时可能需要防抖;错误消息的动态生成可以通过查找预定义的映射对象来实现。同时,引用[3]中的错误处理结构需要确保返回的格式正确,比如在验证失败时返回对应的code和message。 还需要考虑如何触发校验,比如在表单提交时或输入框失焦时进行检查。示例代码中可能需要使用watchEffect来监听输入值的变化,并调用校验方法。此外,引用[2]提到的重复键错误可能与v-for中的key重复有关,但当前问题不涉及列表渲染,可能不需要处理这点。 总结下来,解决方案应该包括创建组合式函数、利用Pinia管理数据、定义错误消息映射、处理异步校验和动态提示。需要确保代码符合Vue3的组合式API风格,并正确处理响应式数据和错误状态。</think>### 分步解决方案:动态重复校验实现 根据需求,我们可以通过组合式函数 + Pinia状态管理实现动态校验逻辑。以下是详细实现步骤: --- ### 1. 创建校验逻辑组合式函数 ```javascript // composables/useDuplicateCheck.js import { computed } from 'vue'; import { useProductStore } from '@/stores/productStore'; export function useDuplicateCheck(props) { const store = useProductStore(); // 定义分类与字段映射 const fieldMapping = { PRODUCT_LINE: 'productLineCode', LOCAL_PRODUCT_LINE: 'localCode', MODEL: 'modelNumber' }; // 定义错误消息模板 const errorMessages = { PRODUCT_LINE: '产品线代码已存在', LOCAL_PRODUCT_LINE: '本地编码重复', MODEL: '型号必须唯一' }; // 获取当前分类对应字段 const currentField = computed(() => fieldMapping[props.productCategory] || 'defaultField' ); // 核心校验方法 const checkDuplicate = async (value) => { if (!value) return { valid: true }; try { const exists = await store.checkExists({ category: props.productCategory, field: currentField.value, value }); return { valid: !exists, message: exists ? errorMessages[props.productCategory] : '' }; } catch (error) { console.error('校验失败:', error); return { valid: false, message: '校验服务不可用' }; } }; return { checkDuplicate }; } ``` --- ### 2. 配置Pinia Store存储 ```javascript // stores/productStore.js import { defineStore } from 'pinia'; import api from '@/api'; export const useProductStore = defineStore('product', { actions: { async checkExists(params) { const { data } = await api.post('/products/check', params); return data.exists; // 确保返回结构包含exists字段[^3] } } }); ``` --- ### 3. 组件集成使用 ```vue <script setup> import { defineProps, ref } from 'vue'; import { useDuplicateCheck } from './composables/useDuplicateCheck'; const props = defineProps({ productCategory: { type: String, required: true, validator: v => ['PRODUCT_LINE', 'LOCAL_PRODUCT_LINE', 'MODEL'].includes(v) } }); const { checkDuplicate } = useDuplicateCheck(props); const inputValue = ref(''); const errorMsg = ref(''); const validateInput = async () => { const { valid, message } = await checkDuplicate(inputValue.value); errorMsg.value = message; // 触发父组件事件 if (valid) { emit('valid', inputValue.value); } }; </script> <template> <div> <input v-model="inputValue" @blur="validateInput" :placeholder="`输入${productCategory}标识`" > <div v-if="errorMsg" class="error-tip">{{ errorMsg }}</div> </div> </template> ``` --- ### 4. 增强功能点 1. **防抖优化**:添加lodash的debounce防止高频请求 2. **缓存机制**:在Pinia中存储已校验过的值 3. **动态配置**:通过API获取字段映射规则(需扩展store) 4. **多语言支持**:使用i18n处理错误消息 --- ### 关键实现说明: 1. **响应式处理**:使用`computed`自动跟踪`productCategory`变化[^1] 2. **类型安全**:通过props验证确保合法分类传入[^4] 3. **错误处理**:遵循统一错误格式规范 4. **解耦设计**:校验逻辑与UI组件分离,符合组合式API最佳实践[^1] --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值