refactor(components): refactor scrollbar

This commit is contained in:
undefined-design 2021-11-06 09:32:11 +08:00 committed by 三咲智子
parent a586e15a35
commit 0369fa8fac
6 changed files with 93 additions and 69 deletions

View File

@ -1,7 +1,7 @@
import { nextTick } from 'vue' import { nextTick } from 'vue'
import { mount } from '@vue/test-utils' import { mount } from '@vue/test-utils'
import { defineGetter, makeScroll } from '@element-plus/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) => const _mount = (template: string) =>
mount({ mount({

View File

@ -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 Scrollbar from './src/scrollbar.vue'
import type { SFCWithInstall } from '@element-plus/utils/types' import Bar from './src/bar.vue'
Scrollbar.install = (app: App): void => { export const ElScrollbar = withInstall(Scrollbar, {
app.component(Scrollbar.name, Scrollbar) Bar,
} })
export default ElScrollbar
const _Scrollbar = Scrollbar as SFCWithInstall<typeof Scrollbar> export const ElBar = withNoopInstall(Bar)
export default _Scrollbar
export const ElScrollbar = _Scrollbar
export * from './src/util' export * from './src/util'
export * from './src/scrollbar'
export * from './src/bar'

View File

@ -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<typeof barProps>

View File

@ -28,18 +28,13 @@ import {
import { off, on } from '@element-plus/utils/dom' import { off, on } from '@element-plus/utils/dom'
import { BAR_MAP, renderThumbStyle } from './util' import { BAR_MAP, renderThumbStyle } from './util'
import { barProps } from './bar'
import type { Ref } from 'vue' import type { Ref } from 'vue'
import type { Nullable } from '@element-plus/utils/types' import type { Nullable } from '@element-plus/utils/types'
export default defineComponent({ export default defineComponent({
name: 'Bar', name: 'Bar',
props: { props: barProps,
vertical: Boolean,
size: String,
move: Number,
ratio: Number,
always: Boolean,
},
setup(props) { setup(props) {
const instance = ref(null) const instance = ref(null)
const thumb = ref(null) const thumb = ref(null)

View File

@ -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 | CSSProperties[]>([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<typeof scrollbarProps>
export const scrollbarEmits = {
scroll: ({
scrollTop,
scrollLeft,
}: {
scrollTop: number
scrollLeft: number
}) => isNumber(scrollTop) && isNumber(scrollLeft),
}
export type ScrollbarEmits = typeof scrollbarEmits

View File

@ -55,62 +55,21 @@ import {
import { debugWarn } from '@element-plus/utils/error' import { debugWarn } from '@element-plus/utils/error'
import Bar from './bar.vue' import Bar from './bar.vue'
import type { CSSProperties, PropType } from 'vue' import { scrollbarProps, scrollbarEmits } from './scrollbar'
import type { CSSProperties } from 'vue'
export default defineComponent({ export default defineComponent({
name: 'ElScrollbar', name: 'ElScrollbar',
components: { Bar }, components: { Bar },
props: { props: scrollbarProps,
height: { emits: scrollbarEmits,
type: [String, Number],
default: '',
},
maxHeight: {
type: [String, Number],
default: '',
},
native: {
type: Boolean,
default: false,
},
wrapStyle: {
type: [String, Array] as PropType<string | CSSProperties[]>,
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'],
setup(props, { emit }) { setup(props, { emit }) {
const sizeWidth = ref('0') const sizeWidth = ref('0')
const sizeHeight = ref('0') const sizeHeight = ref('0')
const moveX = ref(0) const moveX = ref(0)
const moveY = ref(0) const moveY = ref(0)
const scrollbar = ref(null) const scrollbar = ref(null)
const wrap = ref(null) const wrap = ref<HTMLElement>()
const resize = ref(null) const resize = ref(null)
const ratioY = ref(1) const ratioY = ref(1)
const ratioX = ref(1) const ratioX = ref(1)
@ -142,7 +101,7 @@ export default defineComponent({
debugWarn(SCOPE, 'value must be a number') debugWarn(SCOPE, 'value must be a number')
return return
} }
wrap.value.scrollTop = value wrap.value!.scrollTop = value
} }
const setScrollLeft = (value: number) => { const setScrollLeft = (value: number) => {
@ -150,7 +109,7 @@ export default defineComponent({
debugWarn(SCOPE, 'value must be a number') debugWarn(SCOPE, 'value must be a number')
return return
} }
wrap.value.scrollLeft = value wrap.value!.scrollLeft = value
} }
const update = () => { const update = () => {
@ -199,14 +158,14 @@ export default defineComponent({
nextTick(update) nextTick(update)
} }
if (!props.noresize) { if (!props.noresize) {
addResizeListener(resize.value, update) addResizeListener(resize.value!, update)
addEventListener('resize', update) addEventListener('resize', update)
} }
}) })
onBeforeUnmount(() => { onBeforeUnmount(() => {
if (!props.noresize) { if (!props.noresize) {
removeResizeListener(resize.value, update) removeResizeListener(resize.value!, update)
removeEventListener('resize', update) removeEventListener('resize', update)
} }
}) })