Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
F
factory_front
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
qinjianhui
factory_front
Commits
8f2d04a3
Commit
8f2d04a3
authored
Nov 18, 2025
by
wusiyi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix: 尝试修复图片预览会留存的问题
parent
735473e1
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
91 additions
and
47 deletions
+91
-47
src/router/index.ts
+3
-0
src/utils/hooks/useImagePreview..ts
+88
-47
No files found.
src/router/index.ts
View file @
8f2d04a3
...
@@ -4,6 +4,7 @@ import {
...
@@ -4,6 +4,7 @@ import {
RouteLocationNormalized
,
RouteLocationNormalized
,
NavigationGuardNext
,
NavigationGuardNext
,
}
from
'vue-router'
}
from
'vue-router'
import
{
cleanupImagePreview
}
from
'@/utils/hooks/useImagePreview.'
import
Login
from
'@/views/Login.vue'
import
Login
from
'@/views/Login.vue'
import
Reset
from
'@/views/Reset.vue'
import
Reset
from
'@/views/Reset.vue'
...
@@ -341,6 +342,8 @@ router.beforeEach(
...
@@ -341,6 +342,8 @@ router.beforeEach(
_from
:
RouteLocationNormalized
,
_from
:
RouteLocationNormalized
,
next
:
NavigationGuardNext
,
next
:
NavigationGuardNext
,
)
=>
{
)
=>
{
// 路由切换时清理图片预览,防止预览元素残留
cleanupImagePreview
()
const
token
=
getToken
()
const
token
=
getToken
()
if
(
to
.
query
.
factoryCode
)
{
if
(
to
.
query
.
factoryCode
)
{
localStorage
.
setItem
(
'factory_code'
,
String
(
to
.
query
.
factoryCode
))
localStorage
.
setItem
(
'factory_code'
,
String
(
to
.
query
.
factoryCode
))
...
...
src/utils/hooks/useImagePreview..ts
View file @
8f2d04a3
import
{
ref
}
from
'vue'
import
{
ref
,
onUnmounted
}
from
'vue'
export
default
function
useImagePreview
()
{
// 单例模式:所有实例共享同一个预览元素
const
show
=
ref
(
false
)
let
previewDiv
:
HTMLDivElement
|
null
=
null
const
div
=
document
.
createElement
(
'div'
)
let
previewImg
:
HTMLImageElement
|
null
=
null
div
.
style
.
position
=
'fixed'
const
show
=
ref
(
false
)
div
.
style
.
zIndex
=
'9999999999999'
let
currentTarget
:
HTMLElement
|
null
=
null
div
.
style
.
display
=
'none'
let
mousemoveHandler
:
((
ev
:
MouseEvent
)
=>
void
)
|
null
=
null
const
img
=
document
.
createElement
(
'img'
)
img
.
style
.
width
=
'300px'
// 初始化预览元素(只创建一次)
div
.
appendChild
(
img
)
function
initPreviewElement
()
{
document
.
body
.
appendChild
(
div
)
if
(
previewDiv
)
return
let
currentTarget
:
HTMLElement
|
null
=
null
previewDiv
=
document
.
createElement
(
'div'
)
previewDiv
.
style
.
position
=
'fixed'
previewDiv
.
style
.
zIndex
=
'9999999999999'
previewDiv
.
style
.
display
=
'none'
previewImg
=
document
.
createElement
(
'img'
)
previewImg
.
style
.
width
=
'300px'
previewDiv
.
appendChild
(
previewImg
)
document
.
body
.
appendChild
(
previewDiv
)
}
const
mousemoveHandler
=
(
ev
:
MouseEvent
)
=>
{
// 清理函数:移除事件监听器和重置状态
if
(
!
currentTarget
)
return
function
cleanup
()
{
const
rect
=
currentTarget
.
getBoundingClientRect
()
if
(
mousemoveHandler
)
{
const
inOrigin
=
window
.
removeEventListener
(
'mousemove'
,
mousemoveHandler
)
ev
.
clientX
>=
rect
.
left
&&
mousemoveHandler
=
null
ev
.
clientX
<=
rect
.
right
&&
}
ev
.
clientY
>=
rect
.
top
&&
if
(
previewDiv
)
{
ev
.
clientY
<=
rect
.
bottom
previewDiv
.
style
.
display
=
'none'
}
show
.
value
=
false
currentTarget
=
null
}
const
divRect
=
div
.
getBoundingClientRect
()
// 导出清理函数,供路由切换时使用
const
inPreview
=
export
function
cleanupImagePreview
()
{
ev
.
clientX
>=
divRect
.
left
&&
cleanup
()
ev
.
clientX
<=
divRect
.
right
&&
}
ev
.
clientY
>=
divRect
.
top
&&
ev
.
clientY
<=
divRect
.
bottom
if
(
!
inOrigin
&&
!
inPreview
)
{
export
default
function
useImagePreview
()
{
div
.
style
.
display
=
'none'
// 确保预览元素已初始化
show
.
value
=
false
initPreviewElement
()
window
.
removeEventListener
(
'mousemove'
,
mousemoveHandler
)
currentTarget
=
null
// 创建 mousemove 处理器(如果还没有)
if
(
!
mousemoveHandler
)
{
mousemoveHandler
=
(
ev
:
MouseEvent
)
=>
{
if
(
!
currentTarget
||
!
previewDiv
)
{
cleanup
()
return
}
const
rect
=
currentTarget
.
getBoundingClientRect
()
const
inOrigin
=
ev
.
clientX
>=
rect
.
left
&&
ev
.
clientX
<=
rect
.
right
&&
ev
.
clientY
>=
rect
.
top
&&
ev
.
clientY
<=
rect
.
bottom
const
divRect
=
previewDiv
.
getBoundingClientRect
()
const
inPreview
=
ev
.
clientX
>=
divRect
.
left
&&
ev
.
clientX
<=
divRect
.
right
&&
ev
.
clientY
>=
divRect
.
top
&&
ev
.
clientY
<=
divRect
.
bottom
if
(
!
inOrigin
&&
!
inPreview
)
{
cleanup
()
}
}
}
}
}
...
@@ -44,12 +77,13 @@ export default function useImagePreview() {
...
@@ -44,12 +77,13 @@ export default function useImagePreview() {
newBorder
?:
boolean
,
newBorder
?:
boolean
,
positionBOOTTOM
?:
boolean
,
positionBOOTTOM
?:
boolean
,
)
=>
{
)
=>
{
if
(
!
previewDiv
||
!
previewImg
)
return
ev
.
preventDefault
()
ev
.
preventDefault
()
if
(
show
.
value
===
true
)
return
if
(
show
.
value
===
true
)
return
i
mg
.
src
=
url
previewI
mg
.
src
=
url
i
mg
.
style
.
backgroundColor
=
'#eee'
previewI
mg
.
style
.
backgroundColor
=
'#eee'
if
(
newBorder
)
i
mg
.
style
.
border
=
'1px solid #eee'
if
(
newBorder
)
previewI
mg
.
style
.
border
=
'1px solid #eee'
if
(
newWitdh
)
i
mg
.
style
.
width
=
newWitdh
if
(
newWitdh
)
previewI
mg
.
style
.
width
=
newWitdh
const
cW
=
document
.
body
.
clientWidth
const
cW
=
document
.
body
.
clientWidth
const
cH
=
document
.
body
.
clientHeight
const
cH
=
document
.
body
.
clientHeight
const
cX
=
ev
.
clientX
const
cX
=
ev
.
clientX
...
@@ -59,14 +93,15 @@ export default function useImagePreview() {
...
@@ -59,14 +93,15 @@ export default function useImagePreview() {
else
y
=
cY
-
150
else
y
=
cY
-
150
if
(
cX
+
300
>=
cW
)
x
=
cX
-
300
if
(
cX
+
300
>=
cW
)
x
=
cX
-
300
else
x
=
cX
+
60
else
x
=
cX
+
60
img
.
onload
=
()
=>
{
previewImg
.
onload
=
()
=>
{
div
.
style
.
left
=
x
+
'px'
if
(
!
previewDiv
||
!
previewImg
)
return
div
.
style
.
top
=
y
+
'px'
previewDiv
.
style
.
left
=
x
+
'px'
div
.
style
.
display
=
'block'
previewDiv
.
style
.
top
=
y
+
'px'
previewDiv
.
style
.
display
=
'block'
if
(
positionBOOTTOM
)
{
if
(
positionBOOTTOM
)
{
// 获取图片实际尺寸
// 获取图片实际尺寸
const
imgWidth
=
i
mg
.
clientWidth
const
imgWidth
=
previewI
mg
.
clientWidth
const
imgHeight
=
i
mg
.
clientHeight
const
imgHeight
=
previewI
mg
.
clientHeight
// 计算新位置(鼠标正下方)
// 计算新位置(鼠标正下方)
let
x
=
cX
/
2
let
x
=
cX
/
2
...
@@ -85,20 +120,26 @@ export default function useImagePreview() {
...
@@ -85,20 +120,26 @@ export default function useImagePreview() {
if
(
y
<
0
)
{
if
(
y
<
0
)
{
y
=
10
y
=
10
}
}
d
iv
.
style
.
left
=
x
+
'px'
previewD
iv
.
style
.
left
=
x
+
'px'
d
iv
.
style
.
top
=
y
+
'px'
previewD
iv
.
style
.
top
=
y
+
'px'
}
}
show
.
value
=
true
show
.
value
=
true
currentTarget
=
ev
.
currentTarget
as
HTMLElement
currentTarget
=
ev
.
currentTarget
as
HTMLElement
window
.
addEventListener
(
'mousemove'
,
mousemoveHandler
)
if
(
mousemoveHandler
)
{
window
.
addEventListener
(
'mousemove'
,
mousemoveHandler
)
}
}
}
}
}
const
mouseleaveImg
=
()
=>
{
const
mouseleaveImg
=
()
=>
{
if
(
show
.
value
===
false
)
return
// 在 mouseleave 时也要清理事件监听器
div
.
style
.
display
=
'none'
cleanup
()
show
.
value
=
false
}
}
// 组件卸载时清理(防止内存泄漏)
onUnmounted
(()
=>
{
cleanup
()
})
return
{
mouseoverImg
,
mouseleaveImg
}
return
{
mouseoverImg
,
mouseleaveImg
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment