在VUE JS中的Cursor位置插入字符

Gen*_*ble 8 javascript vue.js vuejs2

我一直在尝试在textarea中插入表情符号,正好是诅咒所在的位置.我how tos在网上环顾四周找不到任何具体的VUE JS.他们中的大多数都是普通的JS.

我有这个代码

<div class="picker" v-show="showPicker">
    <click-outside :handler="handleClickOutside">
        <picker
            set ="messenger"
            title="Pick your emoji…"
            emoji="point_up"
            @click="addEmoji"
            :emoji-size="16"
        >
        </picker> 
    </click-outside>
</div>

<textarea id="greeting_text_input" class="form-control"
    type="text" 
    v-model="greeting_text"
    rows="8"
    required
    placeholder="Hi {first-name}! Welcome to our bot. Click on the ‘Get 
    Started’ button to begin
">
</textarea>
Run Code Online (Sandbox Code Playgroud)

我的方法

addEmoji(emoji){
        this.greeting_text += emoji.native;
        this.showPicker = !this.showPicker;
    }
Run Code Online (Sandbox Code Playgroud)

显然,这段代码会将字符(表情符号,在我的例子中)添加到字符串的最后一个.我需要一个纯粹的vuejs解决方案.在vue中出现这种问题的最佳做法是什么?因为在网络中很少有基于vanilla JS或Jquery的解决方案.

gra*_*ang 15

两个步骤:

1 textarea使用vue-way 获取元素:

1.1 在模板代码中reftextarea标记添加attrbute :

<textarea ref="ta"></textarea>
Run Code Online (Sandbox Code Playgroud)

1.2在此组件mounted挂钩后获取此元素:

let textarea = this.$refs.ta
Run Code Online (Sandbox Code Playgroud)

2获取textarea元素的光标位置.

let cursorPosition = textarea.selectionStart
Run Code Online (Sandbox Code Playgroud)

这是参考:参考


小智 5

<!-- tag -->
<textarea ref="yourTextarea" v-model.trim="txtContent" ......></textarea>
Run Code Online (Sandbox Code Playgroud)

<!-- tag -->
<textarea ref="yourTextarea" v-model.trim="txtContent" ......></textarea>
Run Code Online (Sandbox Code Playgroud)


agm*_*984 5

setSelectionRange从一个不同的问题中了解到,我用它来处理信用卡号输入。我将在这里展示我的解决方案,以便人们可能会受到它的启发。

模板:

<input
    ref="input"
    v-model="value"
    @input="handleChange"
>
Run Code Online (Sandbox Code Playgroud)

实例方法:

data() {
    return {
        lastValue: '',
    }
},

methods: {
    setCursorPosition(el, pos) {
        el.focus();
        el.setSelectionRange(pos, pos);
    },
    handleChange() {
        // handle backspace event
        if (this.value.length < this.lastValue.length) {
            this.lastValue = this.value;
            this.$emit('input-changed', this.value);
            return;
        }
        // handle value-edit event
        if (this.$refs.input.selectionStart < this.value.length) {
            const startPos = this.$refs.input.selectionStart;
            this.value = this.value.replace(/\W/gi, '').replace(/(.{4})/g, '$1 ').trim();
            this.$nextTick(() => this.setCursorPosition(this.$refs.input, startPos));
            this.lastValue = this.value;
            this.$emit('input-changed', this.value);
            return;
        }
        // handle everything else
        this.value = this.value.replace(/\W/gi, '').replace(/(.{4})/g, '$1 ').trim();
        this.lastValue = this.value;
        this.$emit('input-changed', this.value);
    },
},
Run Code Online (Sandbox Code Playgroud)

上面代码的目标是在信用卡输入中添加空格,因此1234123412341234会自动重新格式化为1234 1234 1234 1234. 冒险进入这个领域的人会注意到在编辑输入值时出现问题。

您可以在上面的示例中看到三个条件。最后一个是默认值,它使用两步组合简单地重新格式化当前值:删除所有空格,然后每 4 个字符添加一个空格。

如果你注释掉这两个if块,你可以看到问题的出现。

第一个if块处理退格事件。如您所见,每次输入更改时,值都会被捕获为this.lastValue。当您按退格键时,第一个条件的目标是不运行正则表达式。在我看来,这是更好的用户体验。如果你注释掉那个条件,你就可以看到。

第二个if块处理编辑事件。测试它的一个好方法是输入一个有效的 CC 但省略第 3 个字符,以便一切都关闭一个。然后添加字符。一切都应该很好。同样,如果您退格多个字符。第二个条件的目标是正确管理光标位置(或插入符号位置,如果您喜欢这种命名法)。

您可以安全地删除第一个条件和所有引用,lastValue代码仍然可以工作。这可以说是更简单但更糟糕的用户体验。