bootstrap-vue格式化程序正在更改输入位置

时间:2020-09-11 12:02:37

标签: vue.js bootstrap-vue

我想在bootstrap-vue中输入的文件名中用下划线_替换空格。但是,如果我没有在输入末尾添加空格,那么格式化程序会将光标位置移到输入末尾。 如何在不更改光标位置的情况下替换空格?

我尝试过:

<div class="form-group row">
    <label class="col-6 col-md-4 col-lg-3 col-xl-3">File name</label>
    <div class="col-6 col-md-8 col-lg-9 col-xl-9">
        <b-input-group v-if="viewModel.offer">
            <b-form-input ref="fileName" type="text" :formatter="formatter"></b-form-input>
            <b-input-group-append>
                <b-button variant="dark" v-b-popover.hover.top="'Download'" v-on:click=".."><i class="fas fa-arrow-circle-down"></i></b-button>
            </b-input-group-append>
        </b-input-group>
    </div>
</div>

具有:

            formatter(value, event) {                
                const pos = event.target.selectionStart - 1
                const nfileName = value.replace(/\s+/g, '_');
                if (nfileName !== value) {
                    this.$nextTick(() => {
                        event.target.selectionEnd = pos
                    })
                }
                return nfileName;
            }

但是selectionStart的值等于selectionEnd,因此实际位置未知。

1 个答案:

答案 0 :(得分:1)

尝试使用setTimeout代替$nextTicksetTimeout,应在允许输入呈现新值(并移动光标)之后运行。

我个人发现,关于逻辑如何起作用的解释相当不错。 http://www.hesselinkwebdesign.nl/2019/nexttick-vs-settimeout-in-vue/

new Vue({
  el: '#app',
  data() {
    return {
      text: ''
    }
  },
  methods: {
    formatter(value, event) {
      const {
        target: {
          selectionEnd,
          selectionStart
        }
      } = event

      setTimeout(() => {
        event.target.selectionStart = selectionStart;
        event.target.selectionEnd = selectionEnd;
      })

      return value.replace(/\s+/g, '_');
    }
  }
})
<link href="https://unpkg.com/bootstrap@4.5.2/dist/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://unpkg.com/bootstrap-vue@2.16.0/dist/bootstrap-vue.css" rel="stylesheet" />

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.js"></script>
<script src="https://unpkg.com/bootstrap-vue@2.16.0/dist/bootstrap-vue.js"></script>

<div id="app">
  <b-input v-model="text" :formatter="formatter"></b-input>
</div>