refactor(components): 统一组件点击事件命名规范

- 将 EventCard、FeedCard、FriendItem 组件的点击事件从 'tap' 改为 'item-click'
- 更新相关页面中的事件监听器以匹配新的事件名称
- 在聊天页面优化键盘处理逻辑,添加输入框失焦时的键盘保持功能
- 为圆圈页面添加导航防抖锁,防止页面重复打开
- 调整聊天输入框样式,增加10px缓冲避免与键盘贴合
This commit is contained in:
cg
2026-07-21 22:48:35 +08:00
parent 99723497fa
commit 9052a6f4da
5 changed files with 34 additions and 16 deletions
+2 -2
View File
@@ -1,5 +1,5 @@
<template> <template>
<view class="event-card" @click="$emit('tap', event)"> <view class="event-card" @click="$emit('item-click', event)">
<!-- 状态标签 --> <!-- 状态标签 -->
<view class="event-status" :class="'status-' + event.status"> <view class="event-status" :class="'status-' + event.status">
<text class="event-status-text">{{ statusLabel }}</text> <text class="event-status-text">{{ statusLabel }}</text>
@@ -46,7 +46,7 @@ export default {
props: { props: {
event: { type: Object, default: () => ({}) } event: { type: Object, default: () => ({}) }
}, },
emits: ['tap'], emits: ['item-click'],
computed: { computed: {
statusLabel() { statusLabel() {
const map = { open: '报名中', ongoing: '进行中', ended: '已结束' } const map = { open: '报名中', ongoing: '进行中', ended: '已结束' }
+2 -2
View File
@@ -1,5 +1,5 @@
<template> <template>
<view class="feed-card" @click="$emit('tap', feed)"> <view class="feed-card" @click="$emit('item-click', feed)">
<!-- 头部头像+昵称+时间 --> <!-- 头部头像+昵称+时间 -->
<view class="feed-header"> <view class="feed-header">
<view class="feed-avatar-wrap"> <view class="feed-avatar-wrap">
@@ -68,7 +68,7 @@ export default {
props: { props: {
feed: { type: Object, default: () => ({}) } feed: { type: Object, default: () => ({}) }
}, },
emits: ['tap', 'like', 'comment', 'share'], emits: ['item-click', 'like', 'comment', 'share'],
methods: { methods: {
getCatIcon, getCatIcon,
isIconPath, isIconPath,
+2 -2
View File
@@ -1,5 +1,5 @@
<template> <template>
<view class="friend-item" @click="$emit('tap', friend)"> <view class="friend-item" @click="$emit('item-click', friend)">
<view class="friend-avatar-wrap"> <view class="friend-avatar-wrap">
<image v-if="friend.avatar" class="friend-avatar" :src="friend.avatar" mode="aspectFill"></image> <image v-if="friend.avatar" class="friend-avatar" :src="friend.avatar" mode="aspectFill"></image>
<view v-else class="friend-avatar friend-avatar-ph"> <view v-else class="friend-avatar friend-avatar-ph">
@@ -21,7 +21,7 @@ export default {
props: { props: {
friend: { type: Object, default: () => ({}) } friend: { type: Object, default: () => ({}) }
}, },
emits: ['tap'] emits: ['item-click']
} }
</script> </script>
+21 -7
View File
@@ -103,11 +103,13 @@
:hold-keyboard="true" :hold-keyboard="true"
@confirm="sendMessage" @confirm="sendMessage"
@input="onInput" @input="onInput"
@blur="onInputBlur"
/> />
</view> </view>
<view <view
class="chat-send-btn" class="chat-send-btn"
:class="{ 'chat-send-active': inputText.trim() }" :class="{ 'chat-send-active': inputText.trim() }"
@touchstart="onSendTouch"
@click="sendMessage" @click="sendMessage"
> >
<text class="chat-send-icon"></text> <text class="chat-send-icon"></text>
@@ -167,7 +169,8 @@ export default {
computed: { computed: {
inputBarStyle() { inputBarStyle() {
if (this.keyboardHeight > 0) { if (this.keyboardHeight > 0) {
return { paddingBottom: this.keyboardHeight + 'px' } // +10px 缓冲,避免输入栏与键盘顶部贴合/遮挡
return { paddingBottom: (this.keyboardHeight + 10) + 'px' }
} }
return {} return {}
} }
@@ -278,11 +281,7 @@ export default {
this.inputText = '' this.inputText = ''
this.$nextTick(() => this.scrollToBottom()) this.$nextTick(() => this.scrollToBottom())
// 保持键盘不收起:先失焦再重新聚焦输入框(仿微信发送后键盘保留) // 键盘保持由 onInputBlur 处理,无需额外操作
this.inputFocus = false
this.$nextTick(() => {
this.inputFocus = true
})
// 通过 WebSocket 发送 // 通过 WebSocket 发送
wsManager.send('chat', { wsManager.send('chat', {
@@ -312,9 +311,24 @@ export default {
}, 500) }, 500)
}, },
/** 点击发送按钮时记录时间戳 */
onSendTouch() {
this._sendTouchedAt = Date.now()
},
/** 输入框失焦:若因点击发送按钮导致,立即重聚焦保持键盘不收起 */
onInputBlur() {
if (this._sendTouchedAt && Date.now() - this._sendTouchedAt < 500) {
this._sendTouchedAt = 0
this.inputFocus = false
this.$nextTick(() => {
this.inputFocus = true
})
}
},
/** 输入时通知对方 */ /** 输入时通知对方 */
onInput() { onInput() {
this.inputFocus = true
wsManager.send('typing', { receiverId: this.friendId }) wsManager.send('typing', { receiverId: this.friendId })
}, },
+7 -3
View File
@@ -43,7 +43,7 @@
:feed="feed" :feed="feed"
@like="handleLike" @like="handleLike"
@comment="goDetail" @comment="goDetail"
@tap="goDetail" @item-click="goDetail"
/> />
<view v-if="loading" class="circle-loading"> <view v-if="loading" class="circle-loading">
<text class="circle-loading-text">加载中...</text> <text class="circle-loading-text">加载中...</text>
@@ -75,7 +75,7 @@
v-for="f in friends" v-for="f in friends"
:key="f.id" :key="f.id"
:friend="f" :friend="f"
@tap="goChat(f)" @item-click="goChat(f)"
/> />
<EmptyState <EmptyState
v-if="!friends.length" v-if="!friends.length"
@@ -95,7 +95,7 @@
v-for="evt in events" v-for="evt in events"
:key="evt.id" :key="evt.id"
:event="evt" :event="evt"
@tap="goEventDetail" @item-click="goEventDetail"
/> />
<EmptyState <EmptyState
v-if="!events.length" v-if="!events.length"
@@ -226,6 +226,10 @@ export default {
uni.navigateTo({ url: '/pages/friends/friends' }) uni.navigateTo({ url: '/pages/friends/friends' })
}, },
goChat(friend) { goChat(friend) {
// 导航防抖锁:防止事件重复触发导致页面打开两次
if (this._navLock) return
this._navLock = true
setTimeout(() => { this._navLock = false }, 600)
// 根据 friendId 查找对应会话 (f001 -> conv_001) // 根据 friendId 查找对应会话 (f001 -> conv_001)
const convId = 'conv_' + friend.id.replace('f', '') const convId = 'conv_' + friend.id.replace('f', '')
uni.navigateTo({ uni.navigateTo({