Skip to content

Commit

Permalink
refactor: events emitted way change to use props (#95)
Browse files Browse the repository at this point in the history
* feat: change events to use props

* fix: wheel-item mete prop type error

* ci: update create script
  • Loading branch information
qmhc authored Jul 19, 2022
1 parent 4b66611 commit a79871e
Show file tree
Hide file tree
Showing 74 changed files with 1,411 additions and 987 deletions.
27 changes: 24 additions & 3 deletions common/config/src/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,12 +156,33 @@ export function createStateProp(defaultValue: MaybeRef<ComponentState> = 'defaul
}
}

type MaybeArray<T> = T | MaybeArray<T>[]
type MaybeArray<T> = T | T[]
type MaybeArrayDeep<T> = T | MaybeArrayDeep<T>[]

export type ClassType = MaybeArray<string | { [x: string]: ClassType }>
export type StyleType = MaybeArray<
export type ClassType = MaybeArrayDeep<string | { [x: string]: ClassType }>
export type StyleType = MaybeArrayDeep<
string | (CSSProperties & { [x: `--${string}`]: string | number })
>

export const classProp = [String, Object, Array] as PropType<ClassType>
export const styleProp = [String, Object, Array] as PropType<StyleType>

type AnyFunction = (...args: any[]) => any
type VoidFunction = () => void

const eventTypes = [Function, Array]

export function eventProp<F extends AnyFunction = VoidFunction>() {
return eventTypes as PropType<MaybeArray<F>>
}

export function emitEvent<A extends any[]>(handlers: MaybeArray<(...args: A) => void>, ...args: A) {
if (Array.isArray(handlers)) {
for (let i = 0, len = handlers.length; i < len; ++i) {
const handler = handlers[i]
typeof handler === 'function' && handlers[i](...args)
}
} else {
typeof handlers === 'function' && handlers(...args)
}
}
20 changes: 13 additions & 7 deletions components/alert/alert.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@
</div>
<div v-if="hasIcon" :class="nh.be('icon')">
<slot name="icon">
<Icon :icon="iconComp" :scale="hasTitle ? 2 : 1" :style="{ color: props.iconColor }"></Icon>
<Icon
:icon="iconComp"
:scale="hasTitle ? 2 : 1"
:style="{ color: props.iconColor }"
></Icon>
</slot>
</div>
</div>
Expand All @@ -29,7 +33,7 @@
import { defineComponent, ref, computed } from 'vue'
import { CollapseTransition } from '@/components/collapse-transition'
import { Icon } from '@/components/icon'
import { useNameHelper, useProps, booleanProp } from '@vexip-ui/config'
import { useNameHelper, useProps, booleanProp, eventProp, emitEvent } from '@vexip-ui/config'
import {
Flag,
Expand Down Expand Up @@ -73,10 +77,12 @@ export default defineComponent({
iconColor: String,
noBorder: booleanProp,
banner: booleanProp,
manual: booleanProp
manual: booleanProp,
onClose: eventProp(),
onHide: eventProp()
},
emits: ['close', 'hide'],
setup(_props, { slots, emit }) {
emits: [],
setup(_props, { slots }) {
const props = useProps('alert', _props, {
type: {
default: 'info' as AlertType,
Expand Down Expand Up @@ -129,11 +135,11 @@ export default defineComponent({
closed.value = true
}
emit('close')
emitEvent(props.onClose)
}
function handleAfterLeave() {
emit('hide')
emitEvent(props.onHide)
hidden.value = true
}
Expand Down
9 changes: 5 additions & 4 deletions components/anchor/anchor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import {
getCurrentInstance,
isVNode
} from 'vue'
import { useNameHelper, useProps, booleanProp } from '@vexip-ui/config'
import { useNameHelper, useProps, booleanProp, eventProp, emitEvent } from '@vexip-ui/config'
import { animateScrollTo } from './helper'
import { ANCHOR_STATE } from './symbol'
Expand All @@ -56,9 +56,10 @@ export default defineComponent({
offset: Number,
marker: booleanProp,
scrollDuration: Number,
markerTransition: String
markerTransition: String,
onChange: eventProp<(value: string) => void>()
},
emits: ['change', 'update:active'],
emits: ['update:active'],
setup(_props, { emit }) {
const props = useProps('anchor', _props, {
active: {
Expand Down Expand Up @@ -104,7 +105,7 @@ export default defineComponent({
}
)
watch(currentActive, value => {
emit('change', value)
emitEvent(props.onChange, value)
emit('update:active', value)
})
watch(() => props.viewer, updateContainer)
Expand Down
27 changes: 17 additions & 10 deletions components/auto-complete/auto-complete.vue
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,9 @@ import {
sizeProp,
stateProp,
createSizeProp,
createStateProp
createStateProp,
eventProp,
emitEvent
} from '@vexip-ui/config'
import { isNull } from '@vexip-ui/utils'
Expand Down Expand Up @@ -123,9 +125,15 @@ export default defineComponent({
ignoreCase: booleanProp,
autofocus: booleanProp,
spellcheck: booleanProp,
keyConfig: Object as PropType<OptionKeyConfig>
keyConfig: Object as PropType<OptionKeyConfig>,
onSelect: eventProp<(value: string | number, data: RawOption) => void>(),
onInput: eventProp<(value: string) => void>(),
onChange: eventProp<(value: string | number, data: RawOption) => void>(),
onToggle: eventProp<(visible: boolean) => void>(),
onEnter: eventProp<(value: string | number) => void>(),
onClear: eventProp()
},
emits: ['select', 'input', 'change', 'toggle', 'enter', 'clear', 'update:value'],
emits: ['update:value'],
setup(_props, { slots, emit }) {
const { state, validateField, clearField, getFieldValue, setFieldValue } = useFieldStore<
string | number
Expand Down Expand Up @@ -282,7 +290,7 @@ export default defineComponent({
const prevValue = currentValue.value
currentValue.value = value
emit('select', value, data)
emitEvent(props.onSelect, value, data)
if (value !== prevValue) {
changed = true
Expand All @@ -303,7 +311,7 @@ export default defineComponent({
currentIndex.value = 0
}
emit('input', value)
emitEvent(props.onInput, value)
}
function handleInputChange(event: string | Event) {
Expand Down Expand Up @@ -339,7 +347,7 @@ export default defineComponent({
const option = optionsStates.value.find(option => option.value === lastValue)
setFieldValue(currentValue.value)
emit('change', currentValue.value, option?.data || null)
emitEvent(props.onChange, currentValue.value, option?.data || null!)
emit('update:value', currentValue.value)
validateField()
Expand All @@ -349,8 +357,7 @@ export default defineComponent({
function handleToggle() {
testOptionCanDrop()
emit('toggle', visible.value)
emitEvent(props.onToggle, visible.value)
if (!visible.value) {
currentIndex.value = -1
Expand Down Expand Up @@ -389,7 +396,7 @@ export default defineComponent({
handleChange()
}
emit('enter', currentValue.value)
emitEvent(props.onEnter, currentValue.value)
control.value?.blur()
visible.value = false
}
Expand All @@ -406,7 +413,7 @@ export default defineComponent({
}
handleChange()
emit('clear')
emitEvent(props.onClear)
nextTick(clearField)
}
}
Expand Down
16 changes: 7 additions & 9 deletions components/avatar/avatar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
import { defineComponent, ref, computed, watch, inject } from 'vue'
import { Icon } from '@/components/icon'
import { ResizeObserver } from '@/components/resize-observer'
import { useNameHelper, useProps, booleanProp } from '@vexip-ui/config'
import { useNameHelper, useProps, booleanProp, eventProp, emitEvent } from '@vexip-ui/config'
import { GROUP_STATE } from './symbol'
import type { PropType } from 'vue'
Expand All @@ -60,10 +60,11 @@ export default defineComponent({
iconScale: Number,
fallbackSrc: String,
color: String,
background: String
background: String,
onError: eventProp<(event: Event) => void>()
},
emits: ['error'],
setup(_props, { emit }) {
emits: [],
setup(_props) {
const props = useProps('avatar', _props, {
size: 'default' as ComponentSize,
src: {
Expand Down Expand Up @@ -135,14 +136,11 @@ export default defineComponent({
scaleText()
}
)
watch(
() => props.gap,
scaleText
)
watch(() => props.gap, scaleText)
function handleError(event: Event) {
loadFail.value = true
emit('error', event)
emitEvent(props.onError, event)
}
let lastText: string | null = null
Expand Down
22 changes: 15 additions & 7 deletions components/badge/badge.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,20 @@

<script lang="ts">
import { defineComponent, computed } from 'vue'
import { useNameHelper, useProps, booleanProp } from '@vexip-ui/config'
import { useNameHelper, useProps, booleanProp, eventProp, emitEvent } from '@vexip-ui/config'
import type { PropType } from 'vue'
export type BadgeType = 'error' | 'primary' | 'success' | 'warning' | 'info' | 'disabled'
const badgeTypes = Object.freeze<BadgeType>(['error', 'primary', 'success', 'warning', 'info', 'disabled'])
const badgeTypes = Object.freeze<BadgeType>([
'error',
'primary',
'success',
'warning',
'info',
'disabled'
])
export default defineComponent({
name: 'Badge',
Expand All @@ -39,10 +46,11 @@ export default defineComponent({
disabled: booleanProp,
isDot: booleanProp,
type: String as PropType<BadgeType>,
color: String
color: String,
onBadgeClick: eventProp<(event: MouseEvent) => void>()
},
emits: ['badge-click'],
setup(_props, { slots, emit }) {
emits: [],
setup(_props, { slots }) {
const props = useProps('badge', _props, {
content: {
default: null,
Expand Down Expand Up @@ -90,8 +98,8 @@ export default defineComponent({
return !props.disabled && (props.content || props.content === 0 || props.isDot)
})
function handleBadgeClick() {
emit('badge-click')
function handleBadgeClick(event: MouseEvent) {
emitEvent(props.onBadgeClick, event)
}
return {
Expand Down
14 changes: 8 additions & 6 deletions components/breadcrumb/breadcrumb-item.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
<script lang="ts">
import { defineComponent, ref, reactive, watch, inject, onBeforeUnmount } from 'vue'
import { Renderer } from '@/components/renderer'
import { useNameHelper } from '@vexip-ui/config'
import { useNameHelper, eventProp, emitEvent } from '@vexip-ui/config'
import { isFunction } from '@vexip-ui/utils'
import { BREADCRUMB_STATE } from './symbol'
Expand All @@ -36,10 +36,12 @@ export default defineComponent({
label: {
type: [String, Number],
default: null
}
},
onSelect: eventProp<(label: string | number) => void>(),
onSeparatorClick: eventProp<(label: string | number) => void>()
},
emits: ['select', 'separator-click'],
setup(props, { emit }) {
emits: [],
setup(props) {
const breadcrumbState = inject(BREADCRUMB_STATE, null)
const currentLabel = ref(props.label)
Expand Down Expand Up @@ -82,12 +84,12 @@ export default defineComponent({
}
function handleClick() {
emit('select', currentLabel.value)
emitEvent(props.onSelect!, currentLabel.value)
breadcrumbState?.handleSelect(currentLabel.value)
}
function handleSeparatorClick() {
emit('separator-click', currentLabel.value)
emitEvent(props.onSeparatorClick!, currentLabel.value)
breadcrumbState?.handleSeparatorClick(currentLabel.value)
}
Expand Down
14 changes: 8 additions & 6 deletions components/breadcrumb/breadcrumb.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

<script lang="ts">
import { defineComponent, reactive, computed, provide, watch, toRef } from 'vue'
import { useNameHelper, useProps, booleanProp } from '@vexip-ui/config'
import { useNameHelper, useProps, booleanProp, eventProp, emitEvent } from '@vexip-ui/config'
import { isNull, debounceMinor } from '@vexip-ui/utils'
import { BreadcrumbItem } from '@/components/breadcrumb-item'
import { BREADCRUMB_STATE } from './symbol'
Expand All @@ -26,10 +26,12 @@ export default defineComponent({
props: {
separator: String,
border: booleanProp,
options: Array as PropType<string[]>
options: Array as PropType<string[]>,
onSelect: eventProp<(label: string | number) => void>(),
onSeparatorClick: eventProp<(label: string | number) => void>()
},
emits: ['select', 'separator-click'],
setup(_props, { slots, emit }) {
emits: [],
setup(_props, { slots }) {
const props = useProps('breadcrumb', _props, {
separator: '/',
border: false,
Expand Down Expand Up @@ -89,11 +91,11 @@ export default defineComponent({
}
function handleSelect(label: string | number) {
emit('select', label)
emitEvent(props.onSelect, label)
}
function handleSeparatorClick(label: string | number) {
emit('separator-click', label)
emitEvent(props.onSeparatorClick, label)
}
return {
Expand Down
Loading

0 comments on commit a79871e

Please sign in to comment.