diff --git a/packages/components/splitter/__tests__/splitter.test.tsx b/packages/components/splitter/__tests__/splitter.test.tsx
index 87f24661e4..15b58d30cd 100644
--- a/packages/components/splitter/__tests__/splitter.test.tsx
+++ b/packages/components/splitter/__tests__/splitter.test.tsx
@@ -1,4 +1,4 @@
-import { nextTick } from 'vue'
+import { nextTick, ref } from 'vue'
import { mount } from '@vue/test-utils'
import { afterAll, beforeAll, describe, expect, it, vi } from 'vitest'
import { ElSplitter, ElSplitterPanel } from '../index'
@@ -217,4 +217,56 @@ describe('Splitter', () => {
await nextTick()
expect(onCollapse).toHaveBeenCalledWith(0, 'end', [200, 200])
})
+
+ it('should collapse normally when size is two-way bound and min & max is set', async () => {
+ const size = ref(150)
+ const wrapper = mount(() => (
+
+
+
+ Left Panel
+
+ Right Panel
+
+
+ ))
+ await nextTick()
+
+ const panels = wrapper.findAll('.el-splitter-panel')
+ const startCollapseButton = wrapper.find(
+ '.el-splitter-bar__horizontal-collapse-icon-start'
+ )
+ const endCollapseButton = wrapper.find(
+ '.el-splitter-bar__horizontal-collapse-icon-end'
+ )
+
+ // default size
+ expect(panels[0].attributes('style')).toContain('flex-basis: 150px;')
+
+ // Click collapse button
+ await startCollapseButton.trigger('click')
+ await nextTick()
+
+ // Panel should be collapsed (size = 0)
+ expect(panels[0].attributes('style')).toContain('flex-basis: 0px;')
+
+ // Click collapse button to expand
+ await endCollapseButton.trigger('click')
+ await nextTick()
+
+ // Panel should be restored to original size
+ expect(panels[0].attributes('style')).toContain('flex-basis: 150px;')
+
+ // Click collapse button to expand
+ await endCollapseButton.trigger('click')
+ await nextTick()
+
+ // Panel should be collapsed (size = 400)
+ expect(panels[0].attributes('style')).toContain('flex-basis: 400px;')
+ })
})
diff --git a/packages/components/splitter/src/split-panel.vue b/packages/components/splitter/src/split-panel.vue
index 96a39334af..9d71c879f9 100644
--- a/packages/components/splitter/src/split-panel.vue
+++ b/packages/components/splitter/src/split-panel.vue
@@ -115,7 +115,7 @@ let isSizeUpdating = false
watch(
() => props.size,
() => {
- if (panel.value) {
+ if (!isSizeUpdating && panel.value) {
const size = sizeToPx(props.size)
const maxSize = sizeToPx(props.max)
const minSize = sizeToPx(props.min)
@@ -124,12 +124,10 @@ watch(
const finalSize = Math.min(Math.max(size, minSize || 0), maxSize || size)
if (finalSize !== size) {
- isSizeUpdating = true
emits('update:size', finalSize)
}
panel.value.size = finalSize
- nextTick(() => (isSizeUpdating = false))
}
}
)
@@ -137,8 +135,10 @@ watch(
watch(
() => panel.value?.size,
(val) => {
- if (!isSizeUpdating && val !== props.size) {
+ if (val !== props.size) {
+ isSizeUpdating = true
emits('update:size', val as number)
+ nextTick(() => (isSizeUpdating = false))
}
}
)