@@ -38,7 +38,13 @@ export default {
3838 touchEvent: ' ' ,
3939 isInited: false ,
4040 deactivatedX: 0 ,
41- deactivatedY: 0
41+ deactivatedY: 0 ,
42+ // 缓存高度,用于检测变化
43+ cachedContentHeight: 0 ,
44+ cachedWrapperHeight: 0 ,
45+ // 缓存宽度,用于检测变化
46+ cachedContentWidth: 0 ,
47+ cachedWrapperWidth: 0
4248 }
4349 },
4450 props: {
@@ -107,7 +113,24 @@ export default {
107113 },
108114 watch: {
109115 x (newVal ) {
116+ if (this .direction === ' vertical' || this .direction === ' none' ) {
117+ return
118+ }
110119 this .source = ' '
120+ // 检查宽度是否发生变化,只有在变化时才调用 refresh
121+ const widthChanged = this .checkWidthChange ()
122+ let currentX = this .bs .x
123+
124+ if (widthChanged) {
125+ // 兼容容器尺寸变化且同时改变x的场景,ResizeObserver回调是异步的,如果不直接refresh,minScrollX, maxScrollX 拿到的都是上一次的值
126+ this .refresh ()
127+ // bs refresh 方法内会触发 resetPosition(),如果容器宽度从 100 - 50,y 从 100 - 50,这会导致位置立即跳转到边界内,没有动画效果,造成视觉突兀
128+ // 如果 refresh 导致了位置变化,先恢复到原位置再动画滚动
129+ if (this .bs .x !== currentX) {
130+ this .bs .scrollTo (currentX, this .bs .y , 0 )
131+ }
132+ }
133+
111134 if (newVal > this .bs .minScrollX ) {
112135 newVal = this .bs .minScrollX
113136 }
@@ -118,7 +141,24 @@ export default {
118141 this .bs .scrollTo (newVal, this .bs .y , this .speed )
119142 },
120143 y (newVal ) {
144+ if (this .direction === ' horizontal' || this .direction === ' none' ) {
145+ return
146+ }
121147 this .source = ' '
148+ // 检查高度是否发生变化,只有在变化时才调用 refresh
149+ const heightChanged = this .checkHeightChange ()
150+ let currentY = this .bs .y
151+
152+ if (heightChanged) {
153+ // 兼容容器尺寸变化且同时改变y的场景,ResizeObserver回调是异步的,如果不直接refresh,minScrollY, maxScrollY 拿到的都是上一次的值
154+ this .refresh ()
155+ // bs refresh 方法内会触发 resetPosition(),如果容器高度从 100 - 50,y 从 100 - 50,这会导致位置立即跳转到边界内,没有动画效果,造成视觉突兀
156+ // 如果 refresh 导致了位置变化,先恢复到原位置再动画滚动
157+ if (this .bs .y !== currentY) {
158+ this .bs .scrollTo (this .bs .x , currentY, 0 )
159+ }
160+ }
161+
122162 if (newVal > this .bs .minScrollY ) {
123163 newVal = this .bs .minScrollY
124164 }
@@ -146,6 +186,10 @@ export default {
146186 if (! this .scrollOptions .closeResizeObserver ) {
147187 this .createResizeObserver ()
148188 }
189+ // 初始化尺寸缓存
190+ this .$nextTick (() => {
191+ this .initSizeCache ()
192+ })
149193 this .init ()
150194 },
151195 activated () {
@@ -178,13 +222,50 @@ export default {
178222 }
179223 this .refresh ()
180224 })
181- const elementToObserve = document .querySelector (' .mpx-movable-scroll-content' )
182- elementToObserve && this .resizeObserver .observe (elementToObserve)
225+ this .resizeObserver .observe (this .$refs .scrollContent )
183226 }
184227 },
185228 refresh () {
186229 this .bs && this .bs .refresh ()
187230 },
231+ // 检查高度是否发生变化
232+ checkHeightChange () {
233+ if (! this .$refs .scrollContent || ! this .$parent .$refs .movableArea ) {
234+ return false
235+ }
236+
237+ const currentContentHeight = this .$refs .scrollContent .clientHeight
238+ const currentWrapperHeight = this .$parent .$refs .movableArea .clientHeight
239+
240+ const heightChanged =
241+ currentContentHeight !== this .cachedContentHeight ||
242+ currentWrapperHeight !== this .cachedWrapperHeight
243+
244+ // 更新缓存的高度
245+ this .cachedContentHeight = currentContentHeight
246+ this .cachedWrapperHeight = currentWrapperHeight
247+
248+ return heightChanged
249+ },
250+ // 检查宽度是否发生变化
251+ checkWidthChange () {
252+ if (! this .$refs .scrollContent || ! this .$parent .$refs .movableArea ) {
253+ return false
254+ }
255+
256+ const currentContentWidth = this .$refs .scrollContent .clientWidth
257+ const currentWrapperWidth = this .$parent .$refs .movableArea .clientWidth
258+
259+ const widthChanged =
260+ currentContentWidth !== this .cachedContentWidth ||
261+ currentWrapperWidth !== this .cachedWrapperWidth
262+
263+ // 更新缓存的宽度
264+ this .cachedContentWidth = currentContentWidth
265+ this .cachedWrapperWidth = currentWrapperWidth
266+
267+ return widthChanged
268+ },
188269 destroyBs () {
189270 if (! this .bs ) return
190271 this .bs .destroy ()
@@ -364,6 +445,15 @@ export default {
364445 }
365446 extend (this .bsOptions , this .scrollOptions )
366447 },
448+ // 初始化尺寸缓存
449+ initSizeCache () {
450+ if (this .$refs .scrollContent && this .$parent .$refs .movableArea ) {
451+ this .cachedContentHeight = this .$refs .scrollContent .clientHeight
452+ this .cachedWrapperHeight = this .$parent .$refs .movableArea .clientHeight
453+ this .cachedContentWidth = this .$refs .scrollContent .clientWidth
454+ this .cachedWrapperWidth = this .$parent .$refs .movableArea .clientWidth
455+ }
456+ },
367457 // 处理小数点,四舍五入,默认保留一位小数
368458 roundFun (value , n = 1 ) {
369459 return Math .round (value * Math .pow (10 , n)) / Math .pow (10 , n)
0 commit comments