使用.native给dropdown和input增添事件 && 发送快捷键切换功能实现

219 阅读2分钟

dropdown的官方文档用法:

<el-dropdown @command="handleCommand"> 
    <span class="el-dropdown-link"> 下拉菜单
    <i class="el-icon-arrow-down el-icon--right"></i> 
    </span> <el-dropdown-menu slot="dropdown"> 
        <el-dropdown-item command="a">黄金糕</el-dropdown-item> 
        <el-dropdown-item command="b">狮子头</el-dropdown-item> 
        <el-dropdown-item command="c">螺蛳粉</el-dropdown-item> 
        <el-dropdown-item command="d" disabled>双皮奶</el-dropdown-item> 
        <el-dropdown-item command="e" divided>蚵仔煎</el-dropdown-item> 
    </el-dropdown-menu> 
 </el-dropdown>

采用绑定command的形式,对组件的下拉item,没有一个默认的click点击事件。

但是,可以使用 @click.native 来监听 <el-dropdown-item> 的原生 click 事件。

.native 修饰符可以让你直接监听子组件根元素的原生事件,而不是子组件触发的自定义事件。

在这种情况下,@click.native 将监听 <el-dropdown-item> 的原生 click 事件,当用户点击下拉菜单中的某一项时,handleClick 方法将被调用

<el-dropdown-menu slot="dropdown"> 
    <el-dropdown-item 
        v-for="(item, index) in arr" 
        :key="index" 
        @click.native="handleClick" > 
            {{ item }} 
    </el-dropdown-item> 
</el-dropdown-menu>

同样,el-input也没有监听键盘事件,因此可以采用原生keydown事件:

 <el-input
    type="textarea"
    resize="none"
    :autosize="{
        minRows: 1.2,
        maxRows: 1.2,
    }"
    @keydown.enter.native="enterEvent($event)"
    v-model="userInput"
>
</el-input>

feat1: 区别输入法选择的enter和实际发送的enter

可以看见event里面有一个isComposing属性,当是输入法选择时候,忽略此条enter

enterEvent(event) {
    if (event.isComposing) {
        return;
}

feat2: 根据操作系统切换快捷键

想要实现的功能是:如果是macOS,则可以切换enter和cmd+enter进行发送; 如果是windows,可以切换enter和ctrl+enter进行发送; 判断操作系统的方法是:

> window.navigator.userAgent.indexOf('Mac OS X')
< 30
> window.navigator.userAgent.indexOf('Window')
< -1

feat3: 判断发送/换行

0是Enter,1为Ctrl/Cmd+Enter

enterEvent(event) {
    if (event.isComposing) {
        return;
    }
    console.log('enterEvent', this.os, this.userConfig.comm.shortcutKey, event)
    // 进入handleAsk的情况:
    // 1. windows系统,且选择enter发送消息,且没有按下ctrl键
    // 2. mac系统,且选择enter发送消息,且没有按下cmd键
    // 3. windows系统,选择ctrl + enter发送消息,且按下ctrl键
    // 4. mac系统,且选择cmd + enter发送消息,且按下cmd键
    if (this.os === 'Windows' && this.shortcutKey === 0 && !event.ctrlKey ||
        this.os === 'MacOS' && this.shortcutKey === 0 && !event.metaKey ||
        this.os === 'Windows' && this.shortcutKey === 1 && event.ctrlKey ||
        this.os === 'MacOS' && this.shortcutKey === 1 && event.metaKey
    ) {
        // 阻止默认事件
        event.preventDefault();
        this.handleAsk();
    } else if(this.shortcutKey === 0){
        // 本身enter会换行,因此,如果是enter是发送的情况,再额外换行
        this.userInput += "\n";
    }
}