vue3 中组合键 command+Enter / shift+Enter / alt + Enter 实现换行,详细实现

vue3 中组合键实现换行

需求背景

  • 有一个聊天室功能,采用输入框的形式,输入完毕使用Enter可以直接进行发送 。使用一些组合键 比如 command+Enter / shift+Enter / alt + Enter ... 可以实现换行操作 。但现实的情况是,原生 Enter 天然支持换行,但是我们需要阻止掉。但是组合键又需要自己去实现换行

效果图

  • 原生使用Enter 换行
  • 实现自定义组合键换行效果图

实现过程分析

  1. 根据需求定义组合键 Map
  2. 换行是根据光标位置进行换行,所以首先要获取到光标的位置
  3. 根据光标的位置,拆分成两段文本
  4. 合并两端文本为带有换行符的新文本
  5. 重新设置光标位置

代码实现

  • template模版
js 复制代码
<el-input
        ref="editorRef"
        v-model="valueHtml"
        type="textarea"
        :rows="4"
        placeholder="请输入内容"
        @keydown="handleKeyDown"
      >
      </el-input>

js逻辑

js 复制代码
import { ref, nextTick } from 'vue'
const currentEvent = ref()
const valueHtml = ref('')
const editorRef = ref()

const handleKeyDown = ($event: Event) => {
  const event = $event as KeyboardEvent
  currentEvent.value = event.target as HTMLInputElement
  // 定义组合键 Map
  const shortCutKeys: (keyof KeyboardEvent)[] = ['metaKey', 'altKey', 'ctrlKey', 'shiftKey']
  const isEnterKey = event.key === 'Enter'
  const isShortcutKeys = shortCutKeys.some((item) => event[item])
  if (isEnterKey && isShortcutKeys) {
    // 获取光标位置
    const cursorPosition = currentEvent.value.selectionStart

    // 拆分成两段文本
    const textBeforeCursor = valueHtml.value.slice(0, cursorPosition)
    const textAfterCursor = valueHtml.value.slice(cursorPosition)

    // 合并为带有换行符的新文本
    const newText = textBeforeCursor + '\n' + textAfterCursor

    // 更新输入框的值
    valueHtml.value = newText
    // 文本编辑器的高度发生变化后
    nextTick(() => {
      // 高度变化 自动滚动到底部
      const editor = editorRef.value.textarea
      editorRef.value.textarea.scrollTop = editor.scrollHeight
      // 设置光标位置为: start 和 end 相同,光标会移动到换行符后面的新行首
      currentEvent.value.setSelectionRange(cursorPosition + 1, cursorPosition + 1)
    })
  } else if (event.key === 'Enter') {
    // 阻止掉 Enter 的默认换行行为
    event.preventDefault()
    // do yourself things for example  send
  }
}

细节优化

  1. 组合键实现了换行,但是按下Enter 也会触发换行,要阻止掉他的默认行为
js 复制代码
else if (event.key === 'Enter') {
    // 阻止掉 Enter 的默认换行行为
    event.preventDefault()
}
  1. 文本内容换行后,高度有限,需要自动滚动到最下面,保证内容始终可见
js 复制代码
const editor = editorRef.value.textarea
editorRef.value.textarea.scrollTop = editor.scrollHeight
相关推荐
江城开朗的豌豆几秒前
Vue和React的数据流之争:双向绑定 vs 单向数据流,谁更适合你?
前端·javascript·vue.js
芜青2 分钟前
JavaScript手录09-内置对象【String对象】
开发语言·javascript·ecmascript
OpenTiny社区4 分钟前
前端可智能识别的搜索组件 SearchBox 使用详解!
前端·vue.js·ui·开源·opentiny
世伟爱吗喽5 分钟前
最新面试题总结
前端·javascript·vue.js
江城开朗的豌豆11 分钟前
前端权限控制实战:手把手教你玩转角色权限分配
前端·javascript·vue.js
超浪的晨23 分钟前
JavaWeb 入门:HTML 基础与实战详解(Java 开发者视角)
java·开发语言·前端·后端·html·个人开发
CCF_NOI.3 小时前
谷歌浏览器深入用法全解析:解锁高效网络之旅
大数据·运维·服务器·前端·计算机·谷歌
paopaokaka_luck6 小时前
基于SpringBoot+Uniapp的健身饮食小程序(协同过滤算法、地图组件)
前端·javascript·vue.js·spring boot·后端·小程序·uni-app
患得患失9496 小时前
【前端】【vscode】【.vscode/settings.json】为单个项目配置自动格式化和开发环境
前端·vscode·json