refactor(components): 统一组件点击事件命名规范
- 将 EventCard、FeedCard、FriendItem 组件的点击事件从 'tap' 改为 'item-click' - 更新相关页面中的事件监听器以匹配新的事件名称 - 在聊天页面优化键盘处理逻辑,添加输入框失焦时的键盘保持功能 - 为圆圈页面添加导航防抖锁,防止页面重复打开 - 调整聊天输入框样式,增加10px缓冲避免与键盘贴合
This commit is contained in:
@@ -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: '已结束' }
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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
@@ -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 })
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -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({
|
||||||
|
|||||||
Reference in New Issue
Block a user