javascript - 如果不使用 v-model.lazy,Vue3 Cleave js 将无法工作

标签 javascript typescript vuejs3 cleave

目前,我尝试使用 cleavejs 来格式化我的输入数字的千位分隔符,当我输入 1000.123 时,它显示出奇怪的行为,它显示 1,000.12 这是正确的格式,但我的 v-model 值是 1000.123 而不是 1000.12。其他人建议使用 v-model.lazy 但它仅在我将焦点从输入文本中移开时更新。

有没有其他方法可以在不使用 v-model.lazy 的情况下解决这个问题?

这是我当前的组件

<script setup lang="ts">
import { ref, watch } from 'vue'
const props = withDefaults(defineProps<Props>(), {
  type: 'text',
  required: false,
  readonly: false,
  disabled: false
})
const inputValue = ref(props.modelValue)
const emit = defineEmits<{
  (e: 'update:modelValue', value: string | number): void
}>()

watch(
  () => props.modelValue,
  () => {
    inputValue.value = numeric.format(props.modelValue)
  },
  {
    immediate: true
  }
)

watch(
  inputValue,
  () => {
    emit('update:modelValue', parseFloat(inputValue.value.toString().replace(/(\d+),(?=\d+(\D|$))/g, '$1')))
  },
  {
    immediate: true
  }
)
</script>

<template>
 <input
        class="form-input"
        v-model.lazy="inputValue"
        v-cleave="{ numeral: true, numeralThousandsGroupStyle: 'thousand' }"
        :placeholder="props.placeholder"
        :required="props.required"
        :readonly="props.readonly"
        :disabled="props.disabled"
      />
</template>

我希望 v-model 返回与 cleavejs 不使用 .lazy 时相同的值

最佳答案

首先,您根本不需要使用 watch,并且我们不会在此 setter 上发出信号,因为我们等待 Cleavejs 事件

const inputValue = computed({
  set: (text: string) => {},
  get: () => new Intl.NumberFormat('en-US').format(props.modelValue)
})

其次,从 Cleavejs onValueChanged 事件发出原始值数据

const emit = defineEmits<{
  (e: 'update:modelValue', value: number): void
}>()

const onValueChanged = (e: any) => {
  emit('update:modelValue', Number(e.target.rawValue))
}

最后,更新您的输入指令

v-cleave="{ numeral: true, numeralThousandsGroupStyle: 'thousand', onValueChanged: onValueChanged }"

完整组件示例

<script setup lang="ts">
import { computed } from 'vue'

export interface Props {
  modelValue: number
}

const props = withDefaults(defineProps<Props>(), {})

const inputValue = computed({
  set: (text: string) => {},
  get: () => new Intl.NumberFormat('en-US').format(props.modelValue)
})

const emit = defineEmits<{
  (e: 'update:modelValue', value: number): void
}>()

const onValueChanged = (e: any) => {
  emit('update:modelValue', Number(e.target.rawValue))
}
</script>

<template>
  <input
    v-cleave="{ numeral: true, numeralThousandsGroupStyle: 'thousand', onValueChanged: onValueChanged }"
    v-model="inputValue"
  />
</template>

关于javascript - 如果不使用 v-model.lazy,Vue3 Cleave js 将无法工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76496552/

相关文章:

javascript - React Native - FlatList 无法到达底部

javascript - 处理可能因多种原因而失败的 jQuery Promise

javascript - 协助从函数中返回 js 变量

signalr - 导出 TypeScript 模块会导致接口(interface)未被拾取

angular - MatTable 上的多个过滤器

vue-cli - 如何使用 vuejs 3 将路由器添加到 @vue/cli 应用程序?

vue.js - 如何使用 Vue 3 组件内的 Vuex 4 状态数据作为另一个调度的有效负载?

javascript - React Native - Tesseract.js - 错误 : Cannot create URL for blob

angular - 如何将 AM/PM 时间格式转换为 Angular 2 中的小时格式

post - axios拦截器在401重试时更改POST请求的内容类型