如何解决格式化input的值导致光标位置?

大佬们,二次封装了vant的组件,主要效果是用户输入的银行卡号自动4位分割出来一个空格,给后端提交数据的时候呢又是去掉空格的,功能是没问题,但是如果在input中间添加或者删除内容时光标会自动跳到末尾去,如何计算光标位置太难了,求助大佬们,非常感谢

<template>
  <van-field
    v-model="innerValue"
    v-bind="$attrs"
    v-on="$listeners"
  >
    <template v-for="(index, name) in $slots" :slot="name">
      <slot :name="name" />
    </template>
  </van-field>
</template>
<script>
export default {
  inheritAttrs: false,
  model: { event: 'filtered' },
  props: {
    value: { default: '' },
  },
  data() {
    return {}
  },
  computed: {
    innerValue: {
      get() {
        return this.value.replace(/\D/g, '').replace(/(\d{4})(?=\d)/g, '$1 ')
      },
      set(value) {
        this.$emit('filtered', value.replace(/\D/g, ''))
      }
    }
  },
  methods: {}
}
</script>
阅读 1.3k
1 个回答
<template>
  <van-field
    v-model="innerValue"
    v-bind="$attrs"
    v-on="$listeners"
    ref="inputField"
  >
    <template v-for="(index, name) in $slots" :slot="name">
      <slot :name="name" />
    </template>
  </van-field>
</template>

<script>
export default {
  inheritAttrs: false,
  model: { event: 'filtered' },
  props: {
    value: { default: '' },
  },
  data() {
    return {
      oldFormattedValue: ''  // 保存上一个格式化值
    }
  },
  computed: {
    innerValue: {
      get() {
        return this.value.replace(/\D/g, '').replace(/(\d{4})(?=\d)/g, '$1 ')
      },
      set(value) {
        const newValue = value.replace(/\D/g, '');
        this.$emit('filtered', newValue);

        this.adjustCursorPosition(newValue);

        this.oldFormattedValue = this.innerValue;
      }
    }
  },
  methods: {
    adjustCursorPosition(newValue) {
      const input = this.$refs.inputField.$el.querySelector('input');
      const oldPos = input.selectionStart;
      
      // 计算旧格式化值和新格式化值之间的差异
      const oldFormattedValueDiff = this.oldFormattedValue.slice(0, oldPos).split(' ').length - 1;
      const newFormattedValueDiff = this.innerValue.slice(0, oldPos + oldFormattedValueDiff).split(' ').length - 1;

      const diff = newFormattedValueDiff - oldFormattedValueDiff;

      // 调整光标位置
      const newPos = oldPos + diff;
      input.setSelectionRange(newPos, newPos);
    }
  }
}
</script>
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题