很多时候,都需要监听键盘事件,比如,在登录的时候,按Enter键可以直接提交登录;又比如,在即时通讯的背景下,消息的实时生成,消息发送窗口的发送按钮通过Enter键是可以触发的,此时文本域的Enter换行操作是禁止的,取而代之的是shift+Enter或者自定义,下面来看看在Vue项目中是如何操作的。

案例采用Iview框架,需要监听键盘按下事件

1
2
<Input v-model="inputValue" type="textarea" :rows="5" :autosize="false" @keydown.native="listenKey($event)" placeholder="请输入消息..." />
<Button @click="handleSendMessage" size="small">发送</Button>

利用Vue组件的生命周期,在组件挂载之后进行时间监听,组件销毁之后移除事件监听,然后通过点击事件传入的event对象判断键码,从而阻止对应的默认操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
mounted() {
// 绑定enter事件
this.enterKeyup();
},
destroyed() {
// 销毁enter事件
this.enterKeyupDestroyed();
},
methods:{
enterKeyupDestroyed() {
document.removeEventListener("keyup", this.handleSendMessage);
},
enterKeyup() {
document.addEventListener("keyup", this.handleSendMessage);
},
handleSendMessage(e){
if (!e.shiftKey && e.keyCode === 13) {
console.log('发送',e)
}
},
listenKey(e){
if(!e.shiftKey && e.keyCode == 13){
e.cancelBubble=true;
e.preventDefault();
e.stopPropagation();
}
// if (e.keyCode === 13) {
// e.preventDefault() // 阻止浏览器默认换行操作
// return false
// }
}
}

除了监听键盘事件外,有时候我们还需要操作页面的滚动事件,比如,在我们QQ、微信聊天的时候,最新消息总是处于消息框中的最底部,而此时滚动条也总是滚动到最底部,我们同样需要借助生命周期函数和DOM操作来实现。

此时,消息框是随着数据的改变而动态变化的

1
2
3
4
5
6
7
8
9
<div class="body-middle-box" id="messageBox">
<div class="message-box">
<div v-for="(item,index) in currentMessageList" :key="index" :class="item.userName===currentConversation.conversationID?'message-item message-right':'message-item'">
<a href="javascript:;">
<img src="https://dev-file.iviewui.com/userinfoPDvn9gKWYihR24SpgC319vXY8qniCqj4/avatar" alt="">
</a>
<p>{{item.content}}</p>
</div>
</div>

然后借助声明周期函数,组件挂载后执行滚动操作函数,当数据发生变化引起页面DOM更新后再次调用滚动操作函数,由于Vue是不鼓励直接操作DOM的,需要利用nextTick函数DOM刷新后执行相应的操作,当然,也可以使用Vue提供的refs操作DOM

1
2
3
4
5
6
7
8
9
10
11
12
13
14
mounted() {
this.alwaysScrollBottom()
},
updated() {
this.alwaysScrollBottom()
},
methods: {
alwaysScrollBottom(){
this.$nextTick(() => {
let msg = document.getElementById('messageBox') // 获取对象
msg.scrollTop = msg.scrollHeight // 滚动高度
})
}
}