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