javascript - VueJS : How to prevent textarea default behavior

标签 javascript vue.js vuejs2 vue-component

我正在尝试实现类似 slack 的功能,以便仅在完全按下回车键(未按下 shift)时发送消息

考虑这个vue模板 <textarea type="text" v-model="message" @keyup.enter.exact="sendMessage($event)"></textarea> 有了这个组件

export default {
  name: 'Typing',
  data() {
      return {
          message: null
      }
  },
  methods: {
      sendMessage(e) {
        // e.stopPropagation() and e.preventDefault() have no impact
        this.$socket.emit('message', { text: this.message });
        console.log(this.message); // Print the message with another '\n' at the end due to textarea default behavior
      }
  }
}

有没有人知道我如何避免在将最后一个 '\n' 发送到后端之前不使用正则表达式将其删除(我认为这会很脏)?

谢谢

PS:我对 VueJS 堆栈还很陌生,希望我的问题不是很明显

编辑:This question类似,但建议的解决方案不起作用

最佳答案

问题

<textarea
  type="text"
  v-model="message"
  @keyup.enter.exact="sendMessage($event)"
>
</textarea>

代码在Enter 键的keyup 事件上调用sendMessage 方法。 keyup 事件在释放键之后被触发。因此,代码在按下键后、键运行的默认行为(输入换行符)后以及键被释放后调用该方法。 preventDefault 不会阻止问题,因为试图阻止的行为在 keyup 事件之前已经发生。

解决方案

正如我们已经确定的:

  • 我们希望防止按 Enter 键的默认行为。
  • keyup 事件在默认行为已经发生后触发。

解决方案是阻止 keydown 事件的默认行为,并调用 keyup 事件的方法。

Note: it is important to only call the method on the keyup event to avoid multiple calls if the user holds down the key.

  <textarea
    v-model="value"
    @keydown.enter.exact.prevent
    @keyup.enter.exact="send"
    @keydown.enter.shift.exact="newline"
  >
  </textarea>

当按下 Enter+Shift 组合时,可以调用将换行符附加到文本区域值的方法。

下面是一个片段,展示了解决方案中描述的所有行为。

new Vue({
  template: `
    <div>
      <textarea
        v-model="value"
        @keydown.enter.exact.prevent
        @keyup.enter.exact="send"
        @keydown.enter.shift.exact="newline"
      >
      </textarea>
    </div>
  `,
  
  data: {
    value: '',
  },
  
  methods: {
    newline() {
      this.value = `${this.value}\n`;
    },

    send() {
      console.log('========');
      console.log(this.value);
      console.log('========');
    },
  },
}).$mount('#root');
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
</head>
<body>
  <div id="root"></div>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.min.js"></script>
</body>
</html>

进一步阅读

关于javascript - VueJS : How to prevent textarea default behavior,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47221119/

相关文章:

javascript - 选中 Vuejs Vuetify 时更改复选框图标

css - VueJs vue-router 链接外部网站

javascript - 改进自定义正则表达式

javascript - 如何计算 json 对象数组中的值? (在 VueJS 中)

c# - 部分 View 不工作的 MVC3 Ajax 表单验证

Vue.js 组织 API 端点的最佳方法?

javascript - Vue.js Safari 移动和兼容性

vue.js - Vue 触发函数与来自 child 意外的参数

javascript - Angularj JS 上下文菜单

javascript - javascript 中的匿名函数和空返回对象