diff --git a/packages/components/scrollbar/__tests__/scrollbar.spec.ts b/packages/components/scrollbar/__tests__/scrollbar.spec.ts index 71c3a301f0..d2c89ac083 100644 --- a/packages/components/scrollbar/__tests__/scrollbar.spec.ts +++ b/packages/components/scrollbar/__tests__/scrollbar.spec.ts @@ -1,7 +1,7 @@ import { nextTick } from 'vue' import { mount } from '@vue/test-utils' import { defineGetter, makeScroll } from '@element-plus/test-utils' -import Scrollbar from '../src/index.vue' +import Scrollbar from '../src/scrollbar.vue' const _mount = (template: string) => mount({ diff --git a/packages/components/scrollbar/index.ts b/packages/components/scrollbar/index.ts index 1b93c9a524..9531f6dd1d 100644 --- a/packages/components/scrollbar/index.ts +++ b/packages/components/scrollbar/index.ts @@ -1,15 +1,14 @@ -import Scrollbar from './src/index.vue' +import { withInstall, withNoopInstall } from '@element-plus/utils/with-install' -import type { App } from 'vue' -import type { SFCWithInstall } from '@element-plus/utils/types' +import Scrollbar from './src/scrollbar.vue' +import Bar from './src/bar.vue' -Scrollbar.install = (app: App): void => { - app.component(Scrollbar.name, Scrollbar) -} - -const _Scrollbar = Scrollbar as SFCWithInstall - -export default _Scrollbar -export const ElScrollbar = _Scrollbar +export const ElScrollbar = withInstall(Scrollbar, { + Bar, +}) +export default ElScrollbar +export const ElBar = withNoopInstall(Bar) export * from './src/util' +export * from './src/scrollbar' +export * from './src/bar' diff --git a/packages/components/scrollbar/src/bar.ts b/packages/components/scrollbar/src/bar.ts new file mode 100644 index 0000000000..aa658d6f83 --- /dev/null +++ b/packages/components/scrollbar/src/bar.ts @@ -0,0 +1,11 @@ +import { buildProps } from '@element-plus/utils/props' +import type { ExtractPropTypes } from 'vue' + +export const barProps = buildProps({ + vertical: Boolean, + size: String, + move: Number, + ratio: Number, + always: Boolean, +} as const) +export type BarProps = ExtractPropTypes diff --git a/packages/components/scrollbar/src/bar.vue b/packages/components/scrollbar/src/bar.vue index ccd8bca0a5..df70e7e195 100644 --- a/packages/components/scrollbar/src/bar.vue +++ b/packages/components/scrollbar/src/bar.vue @@ -28,18 +28,13 @@ import { import { off, on } from '@element-plus/utils/dom' import { BAR_MAP, renderThumbStyle } from './util' +import { barProps } from './bar' import type { Ref } from 'vue' import type { Nullable } from '@element-plus/utils/types' export default defineComponent({ name: 'Bar', - props: { - vertical: Boolean, - size: String, - move: Number, - ratio: Number, - always: Boolean, - }, + props: barProps, setup(props) { const instance = ref(null) const thumb = ref(null) diff --git a/packages/components/scrollbar/src/scrollbar.ts b/packages/components/scrollbar/src/scrollbar.ts new file mode 100644 index 0000000000..4f4f60918f --- /dev/null +++ b/packages/components/scrollbar/src/scrollbar.ts @@ -0,0 +1,60 @@ +import { buildProps, definePropType } from '@element-plus/utils/props' +import { isNumber } from '@element-plus/utils/util' +import type { CSSProperties, ExtractPropTypes } from 'vue' + +export const scrollbarProps = buildProps({ + height: { + type: [String, Number], + default: '', + }, + maxHeight: { + type: [String, Number], + default: '', + }, + native: { + type: Boolean, + default: false, + }, + wrapStyle: { + type: definePropType([String, Array]), + default: '', + }, + wrapClass: { + type: [String, Array], + default: '', + }, + viewClass: { + type: [String, Array], + default: '', + }, + viewStyle: { + type: [String, Array], + default: '', + }, + noresize: Boolean, // 如果 container 尺寸不会发生变化,最好设置它可以优化性能 + tag: { + type: String, + default: 'div', + }, + always: { + type: Boolean, + default: false, + }, + minSize: { + type: Number, + default: 20, + }, +} as const) + +export type ScrollbarProps = ExtractPropTypes + +export const scrollbarEmits = { + scroll: ({ + scrollTop, + scrollLeft, + }: { + scrollTop: number + scrollLeft: number + }) => isNumber(scrollTop) && isNumber(scrollLeft), +} +export type ScrollbarEmits = typeof scrollbarEmits diff --git a/packages/components/scrollbar/src/index.vue b/packages/components/scrollbar/src/scrollbar.vue similarity index 79% rename from packages/components/scrollbar/src/index.vue rename to packages/components/scrollbar/src/scrollbar.vue index 2bae2b9895..23de93ab65 100644 --- a/packages/components/scrollbar/src/index.vue +++ b/packages/components/scrollbar/src/scrollbar.vue @@ -55,62 +55,21 @@ import { import { debugWarn } from '@element-plus/utils/error' import Bar from './bar.vue' -import type { CSSProperties, PropType } from 'vue' +import { scrollbarProps, scrollbarEmits } from './scrollbar' +import type { CSSProperties } from 'vue' export default defineComponent({ name: 'ElScrollbar', components: { Bar }, - props: { - height: { - type: [String, Number], - default: '', - }, - maxHeight: { - type: [String, Number], - default: '', - }, - native: { - type: Boolean, - default: false, - }, - wrapStyle: { - type: [String, Array] as PropType, - default: '', - }, - wrapClass: { - type: [String, Array], - default: '', - }, - viewClass: { - type: [String, Array], - default: '', - }, - viewStyle: { - type: [String, Array], - default: '', - }, - noresize: Boolean, // 如果 container 尺寸不会发生变化,最好设置它可以优化性能 - tag: { - type: String, - default: 'div', - }, - always: { - type: Boolean, - default: false, - }, - minSize: { - type: Number, - default: 20, - }, - }, - emits: ['scroll'], + props: scrollbarProps, + emits: scrollbarEmits, setup(props, { emit }) { const sizeWidth = ref('0') const sizeHeight = ref('0') const moveX = ref(0) const moveY = ref(0) const scrollbar = ref(null) - const wrap = ref(null) + const wrap = ref() const resize = ref(null) const ratioY = ref(1) const ratioX = ref(1) @@ -142,7 +101,7 @@ export default defineComponent({ debugWarn(SCOPE, 'value must be a number') return } - wrap.value.scrollTop = value + wrap.value!.scrollTop = value } const setScrollLeft = (value: number) => { @@ -150,7 +109,7 @@ export default defineComponent({ debugWarn(SCOPE, 'value must be a number') return } - wrap.value.scrollLeft = value + wrap.value!.scrollLeft = value } const update = () => { @@ -199,14 +158,14 @@ export default defineComponent({ nextTick(update) } if (!props.noresize) { - addResizeListener(resize.value, update) + addResizeListener(resize.value!, update) addEventListener('resize', update) } }) onBeforeUnmount(() => { if (!props.noresize) { - removeResizeListener(resize.value, update) + removeResizeListener(resize.value!, update) removeEventListener('resize', update) } })