This commit is contained in:
张成
2025-11-06 14:02:48 +08:00
parent 9d507c88ab
commit 6953193cf5

View File

@@ -94,29 +94,50 @@ export default {
methods: { methods: {
show(callback) { show(callback) {
this.ensureParentPosition() this.ensureParentPosition()
this.showPanel = true // 使用 requestAnimationFrame 确保在下一帧渲染时显示,避免闪烁
this.callback = callback requestAnimationFrame(() => {
this.showPanel = true
this.callback = callback
})
}, },
hide() { hide() {
this.showPanel = false this.showPanel = false
this.callback = null this.callback = null
this.restoreParentPosition() // 延迟恢复父容器定位,等待动画完成
setTimeout(() => {
this.restoreParentPosition()
}, 300)
}, },
ensureParentPosition() { ensureParentPosition() {
// 确保父容器有 position: relative // 确保父容器有 position: relative,提前设置避免闪烁
this.$nextTick(() => { if (!this.parentElement) {
if (!this.parentElement && this.$el) { // 在组件挂载后立即获取父元素
if (this.$el && this.$el.parentElement) {
this.parentElement = this.$el.parentElement this.parentElement = this.$el.parentElement
} else {
// 如果组件还未挂载,使用 $nextTick
this.$nextTick(() => {
if (this.$el && this.$el.parentElement) {
this.parentElement = this.$el.parentElement
}
this.setParentPosition()
})
return
} }
if (this.parentElement) { }
const computedStyle = window.getComputedStyle(this.parentElement) this.setParentPosition()
const position = computedStyle.position },
if (position === 'static' || !position) { setParentPosition() {
this.originalParentPosition = this.parentElement.style.position || '' if (this.parentElement) {
this.parentElement.style.position = 'relative' const computedStyle = window.getComputedStyle(this.parentElement)
} const position = computedStyle.position
if (position === 'static' || !position) {
this.originalParentPosition = this.parentElement.style.position || ''
// 使用 will-change 优化性能
this.parentElement.style.willChange = 'transform'
this.parentElement.style.position = 'relative'
} }
}) }
}, },
restoreParentPosition() { restoreParentPosition() {
// 恢复父容器的原始定位 // 恢复父容器的原始定位
@@ -126,6 +147,7 @@ export default {
} else { } else {
this.parentElement.style.position = '' this.parentElement.style.position = ''
} }
this.parentElement.style.willChange = ''
this.originalParentPosition = null this.originalParentPosition = null
} }
}, },
@@ -150,12 +172,23 @@ export default {
} }
} }
}, },
mounted() {
// 组件挂载后立即获取父元素并设置定位,避免后续闪烁
this.$nextTick(() => {
if (this.$el && this.$el.parentElement) {
this.parentElement = this.$el.parentElement
// 预先设置 position避免显示时闪烁
this.setParentPosition()
}
})
},
beforeDestroy() { beforeDestroy() {
// 组件销毁时关闭面板并清理 // 组件销毁时关闭面板并清理
if (this.showPanel) { if (this.showPanel) {
this.hide() this.hide()
} else {
this.restoreParentPosition()
} }
this.restoreParentPosition()
} }
} }
</script> </script>
@@ -170,6 +203,11 @@ export default {
z-index: 1000; z-index: 1000;
width: 100%; width: 100%;
height: 100%; height: 100%;
/* 使用 will-change 优化性能,避免重排 */
will-change: transform;
/* 使用 transform 代替 position避免触发重排 */
transform: translateZ(0);
backface-visibility: hidden;
} }
.float-panel { .float-panel {
@@ -182,6 +220,10 @@ export default {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
overflow: hidden; overflow: hidden;
/* 使用 GPU 加速,避免闪烁 */
will-change: transform;
transform: translateZ(0);
backface-visibility: hidden;
&.float-panel-right { &.float-panel-right {
animation: slideInRight 0.3s ease-out; animation: slideInRight 0.3s ease-out;
@@ -242,12 +284,16 @@ export default {
// 动画效果 // 动画效果
.float-panel-enter-active, .float-panel-enter-active,
.float-panel-leave-active { .float-panel-leave-active {
transition: opacity 0.3s; transition: opacity 0.3s ease;
/* 使用 transform 代替 opacity性能更好 */
will-change: transform, opacity;
} }
.float-panel-enter, .float-panel-enter,
.float-panel-leave-to { .float-panel-leave-to {
opacity: 0; opacity: 0;
/* 使用 transform 避免重排 */
transform: translateZ(0);
} }
@keyframes slideInRight { @keyframes slideInRight {