perf: 优化长按事件

This commit is contained in:
kuaifan 2025-04-12 18:29:39 +08:00
parent e3d0f571d2
commit aa74c5ccaf
6 changed files with 127 additions and 64 deletions

View File

@ -123,15 +123,15 @@
</ul>
</div>
<div ref="menuProject" class="menu-project">
<ul>
<ul v-longpress="handleLongpress">
<li
v-for="(item, key) in projectLists"
:ref="`project_${item.id}`"
:key="key"
:class="classNameProject(item)"
:data-id="item.id"
@click="toggleRoute('project', {projectId: item.id})"
v-longpress="handleLongpress">
@pointerdown="handleOperation"
@click="toggleRoute('project', {projectId: item.id})">
<div class="project-h1">
<em @click.stop="toggleOpenMenu(item.id)"></em>
<div class="title">{{item.name}}</div>
@ -505,16 +505,14 @@ export default {
'clientNewVersion',
'cacheTaskBrowse',
'dialogIns',
'reportUnreadNumber',
'approveUnreadNumber',
'dialogIns',
'okrWindow',
'formOptions',
'mobileTabbar'
'mobileTabbar',
'longpressData',
]),
...mapGetters(['dashboardTask']),
@ -1133,16 +1131,21 @@ export default {
this.workReportShow = true;
},
handleLongpress(event, el) {
const projectId = $A.getAttr(el, 'data-id')
const projectItem = this.projectLists.find(item => item.id == projectId)
handleLongpress(event) {
const {type, data, element} = this.longpressData;
this.$store.commit("longpress/clear")
//
if (type !== 'manage') {
return
}
const projectItem = this.projectLists.find(item => item.id == data.projectId)
if (!projectItem) {
return
}
this.operateVisible = false;
this.operateItem = $A.isJson(projectItem) ? projectItem : {};
this.$nextTick(() => {
const rect = el.getBoundingClientRect();
const rect = element.getBoundingClientRect();
const parentRect = this.$refs.boxMenu?.getBoundingClientRect() || {top: 0, left: 0}
this.operateStyles = {
left: `${event.clientX - parentRect.left}px`,
@ -1153,6 +1156,16 @@ export default {
})
},
handleOperation({currentTarget}) {
this.$store.commit("longpress/set", {
type: 'manage',
data: {
projectId: $A.getAttr(currentTarget, 'data-id')
},
element: currentTarget
})
},
handleTopClick() {
this.$store.dispatch("call", {
url: 'project/top',

View File

@ -30,10 +30,8 @@
</div>
<template v-else>
<div
ref="avatar"
class="dialog-avatar"
@contextmenu="handleOperation"
@touchstart="handleOperation">
@pointerdown="handleOperation">
<UserAvatar :userid="source.userid" :size="30" @open-dialog="onOpenDialog"/>
</div>
<DialogView
@ -214,11 +212,11 @@ export default {
})
},
handleOperation() {
handleOperation({currentTarget}) {
this.$store.commit("longpress/set", {
type: 'mention',
data: this.source,
element: this.$refs.avatar
element: currentTarget
})
},

View File

@ -6,12 +6,10 @@
</div>
<div
ref="dialogHead"
class="dialog-head"
:class="headClass"
@click="handleClick"
@contextmenu="handleOperation"
@touchstart="handleOperation">
@pointerdown="handleOperation">
<!--回复-->
<div v-if="!hideReply && msgData.reply_id && showReplyData(msgData.msg.reply_data)" class="dialog-reply no-dark-content" :class="replyClass" @click="viewReply">
<div class="reply-avatar">
@ -394,11 +392,11 @@ export default {
},
methods: {
handleOperation() {
handleOperation({currentTarget}) {
this.$store.commit("longpress/set", {
type: 'operateMsg',
data: this.msgData,
element: this.$refs.dialogHead
element: currentTarget
})
},

View File

@ -12,7 +12,10 @@
</Form>
</div>
</div>
<ul @touchstart="onTouchStart" @scroll="onScroll">
<ul
@scroll="onScroll"
@touchstart="onTouchStart"
v-longpress="handleLongpress">
<template v-if="projectLists.length === 0">
<li v-if="projectKeyLoading > 0" class="loading"><Loading/></li>
<li v-else class="nothing">
@ -24,7 +27,7 @@
:key="key"
:data-id="item.id"
:class="{operate: item.id == operateItem.id && operateVisible}"
v-longpress="handleLongpress"
@pointerdown="handleOperation"
@click="toggleRoute('project', {projectId: item.id})">
<div class="project-item">
<div class="item-left">
@ -90,7 +93,7 @@ export default {
},
computed: {
...mapState(['cacheProjects', 'loadProjects']),
...mapState(['cacheProjects', 'loadProjects', 'longpressData']),
projectLists() {
const {projectKeyValue, cacheProjects} = this;
@ -173,16 +176,21 @@ export default {
});
},
handleLongpress(event, el) {
const projectId = $A.getAttr(el, 'data-id')
const projectItem = this.projectLists.find(item => item.id == projectId)
handleLongpress(event) {
const {type, data, element} = this.longpressData;
this.$store.commit("longpress/clear")
//
if (type !== 'projectList') {
return
}
const projectItem = this.projectLists.find(item => item.id == data.projectId)
if (!projectItem) {
return
}
this.operateVisible = false;
this.operateItem = $A.isJson(projectItem) ? projectItem : {};
this.$nextTick(() => {
const rect = el.getBoundingClientRect();
const rect = element.getBoundingClientRect();
const parentRect = this.$el.getBoundingClientRect() || {top: 0, left: 0}
this.operateStyles = {
left: `${event.clientX - parentRect.left}px`,
@ -193,6 +201,16 @@ export default {
})
},
handleOperation({currentTarget}) {
this.$store.commit("longpress/set", {
type: 'projectList',
data: {
projectId: $A.getAttr(currentTarget, 'data-id')
},
element: currentTarget
})
},
handleTopClick() {
this.$store.dispatch("call", {
url: 'project/top',

View File

@ -119,7 +119,7 @@
<p>{{$L('没有任何文件')}}</p>
</div>
<div v-else class="file-list" @contextmenu.prevent="handleContextmenu">
<ul>
<ul v-longpress="handleLongpress">
<li v-for="item in fileList">
<div
class="file-item"
@ -129,7 +129,7 @@
operate: contextMenuVisible && item.id === contextMenuItem.id,
}"
:data-id="item.id"
v-longpress="handleLongpress"
@pointerdown="handleOperation"
@click="dropFile(item, 'openCheckMenu')">
<div class="file-check" :class="{'file-checked':selectIds.includes(item.id)}" @click.stop="dropFile(item, 'select')">
<Checkbox :value="selectIds.includes(item.id)"/>
@ -769,7 +769,17 @@ export default {
},
computed: {
...mapState(['systemConfig', 'userIsAdmin', 'userInfo', 'fileLists', 'wsOpenNum', 'windowWidth', 'filePackLists', 'fileShakeId']),
...mapState([
'systemConfig',
'userIsAdmin',
'userInfo',
'fileLists',
'wsOpenNum',
'windowWidth',
'filePackLists',
'fileShakeId',
'longpressData'
]),
pid() {
const {folderId} = this.$route.params;
@ -1018,15 +1028,30 @@ export default {
this.autoBlur(id)
},
handleLongpress(event, el) {
const fileId = $A.getAttr(el, 'data-id')
const fileItem = this.fileList.find(item => item.id == fileId)
handleLongpress(event) {
const {type, data} = this.longpressData;
this.$store.commit("longpress/clear")
//
if (type !== 'file') {
return
}
const fileItem = this.fileList.find(item => item.id == data.fileId)
if (!fileItem) {
return
}
this.handleRightClick(event, fileItem)
},
handleOperation({currentTarget}) {
this.$store.commit("longpress/set", {
type: 'file',
data: {
fileId: $A.getAttr(currentTarget, 'data-id')
},
element: currentTarget
})
},
handleContextmenu(event) {
if (this.windowLandscape) {
this.handleRightClick(event)

View File

@ -68,7 +68,8 @@
class="messenger-list"
:hide-bar="operateVisible"
@touchstart.native="listTouch"
@on-scroll="listScroll">
@on-scroll="listScroll"
v-longpress="handleLongpress">
<ul v-if="tabActive==='dialog'" ref="ul" class="dialog">
<template v-if="dialogList.length > 0">
<li
@ -76,13 +77,14 @@
:ref="`dialog_${dialog.id}`"
:key="key"
:data-id="dialog.id"
data-type="dialog"
:class="dialogClass(dialog)"
@click="openDialog({
dialog_id: dialog.id,
dialog_msg_id: dialog.search_msg_id,
search_msg_id: dialog.search_msg_id,
})"
v-longpress="handleDialogLongpress"
@pointerdown="handleOperation"
:style="{'background-color':dialog.color}">
<template v-if="dialog.type=='group'">
<EAvatar v-if="dialog.avatar" class="img-avatar" :src="dialog.avatar" :size="42"></EAvatar>
@ -141,9 +143,10 @@
v-for="(user, index) in items.list"
:key="index"
:data-id="user.userid"
data-type="contacts"
:class="userClass(user)"
@click="openContacts(user)"
v-longpress="handleUserLongpress">
@pointerdown="handleOperation">
<div class="avatar"><UserAvatar :userid="user.userid" :size="contactAvatarSize"/></div>
<div class="nickname">
<em>{{user.nickname}}</em>
@ -366,7 +369,8 @@ export default {
'dialogMsgs',
'messengerSearchKey',
'appNotificationPermission',
'taskColorList'
'taskColorList',
'longpressData'
]),
...mapGetters(['getDialogDraft', 'tagDialogDraft']),
@ -1031,38 +1035,34 @@ export default {
})
},
handleDialogLongpress(event, el) {
if (this.dialogSearchKey) {
return;
}
const dialogId = $A.getAttr(el, 'data-id')
const dialogItem = this.dialogList.find(item => item.id == dialogId)
if (!dialogItem) {
handleLongpress(event) {
const {type, data, element} = this.longpressData;
this.$store.commit("longpress/clear")
//
if (type !== 'messenger') {
return
}
this.handleLongpress(dialogItem, el.getBoundingClientRect(), event.clientX)
},
handleUserLongpress(event, el) {
if (this.contactsKey) {
return;
}
const userId = $A.getAttr(el, 'data-id')
const userItem = this.contactsFilter.find(item => item.userid == userId)
if (!userItem) {
return
}
this.handleLongpress(userItem, el.getBoundingClientRect(), event.clientX)
},
handleLongpress(item, rect, clientX) {
this.operateType = this.tabActive;
this.operateVisible = false;
this.operateItem = $A.isJson(item) ? item : {};
if (data.dataType === 'contacts') {
if (this.contactsKey) {
return;
}
this.operateItem = this.contactsFilter.find(item => item.userid == data.dataId)
} else {
if (this.dialogSearchKey) {
return;
}
this.operateItem = this.dialogList.find(item => item.id == data.dataId)
}
if (!this.operateItem) {
return
}
const rect = element.getBoundingClientRect();
this.$nextTick(() => {
const parentRect = this.$refs.select?.getBoundingClientRect() || {top: 0, left: 0}
this.operateStyles = {
left: `${clientX}px`,
left: `${event.clientX}px`,
top: `${rect.top + this.windowScrollY - parentRect.top}px`,
height: rect.height + 'px',
}
@ -1070,6 +1070,17 @@ export default {
})
},
handleOperation({currentTarget}) {
this.$store.commit("longpress/set", {
type: 'messenger',
data: {
dataId: $A.getAttr(currentTarget, 'data-id'),
dataType: $A.getAttr(currentTarget, 'data-type'),
},
element: currentTarget
})
},
handleDialogClick(act, value = undefined) {
switch (act) {
case 'top':