refactor: mentions to ts

pull/2992/head
Amour1688 2020-10-15 09:48:43 +08:00
parent 54ca9021c3
commit b331753d31
4 changed files with 56 additions and 26 deletions

View File

@ -1,4 +1,4 @@
import { inject } from 'vue'; import { App, defineComponent, inject, PropType, VNodeTypes } from 'vue';
import classNames from '../_util/classNames'; import classNames from '../_util/classNames';
import omit from 'omit.js'; import omit from 'omit.js';
import PropTypes from '../_util/vue-types'; import PropTypes from '../_util/vue-types';
@ -8,14 +8,27 @@ import Spin from '../spin';
import BaseMixin from '../_util/BaseMixin'; import BaseMixin from '../_util/BaseMixin';
import { defaultConfigProvider } from '../config-provider'; import { defaultConfigProvider } from '../config-provider';
import { getOptionProps, getComponent, getSlot } from '../_util/props-util'; import { getOptionProps, getComponent, getSlot } from '../_util/props-util';
import { RenderEmptyHandler } from '../config-provider/renderEmpty';
const { Option } = VcMentions; const { Option } = VcMentions;
interface MentionsConfig {
prefix?: string | string[];
split?: string;
}
export interface OptionProps {
value: string;
disabled: boolean;
children: VNodeTypes;
[key: string]: any;
}
function loadingFilterOption() { function loadingFilterOption() {
return true; return true;
} }
function getMentions(value = '', config) { function getMentions(value: string = '', config: MentionsConfig) {
const { prefix = '@', split = ' ' } = config || {}; const { prefix = '@', split = ' ' } = config || {};
const prefixList = Array.isArray(prefix) ? prefix : [prefix]; const prefixList = Array.isArray(prefix) ? prefix : [prefix];
@ -44,7 +57,7 @@ function getMentions(value = '', config) {
.filter(entity => !!entity && !!entity.value); .filter(entity => !!entity && !!entity.value);
} }
const Mentions = { const Mentions = defineComponent({
name: 'AMentions', name: 'AMentions',
mixins: [BaseMixin], mixins: [BaseMixin],
inheritAttrs: false, inheritAttrs: false,
@ -53,12 +66,20 @@ const Mentions = {
props: { props: {
...mentionsProps, ...mentionsProps,
loading: PropTypes.looseBool, loading: PropTypes.looseBool,
onFocus: PropTypes.func, onFocus: {
onBlur: PropTypes.func, type: Function as PropType<(e: FocusEvent) => void>,
onSelect: PropTypes.func, },
onChange: PropTypes.func, onBlur: {
'onUpdate:value': PropTypes.func, type: Function as PropType<(e: FocusEvent) => void>,
},
onSelect: {
type: Function as PropType<(option: OptionProps, prefix: string) => void>,
},
onChange: {
type: Function as PropType<(text: string) => void>,
},
}, },
emits: ['update:value', 'change', 'focus', 'blur', 'select'],
setup() { setup() {
return { return {
configProvider: inject('configProvider', defaultConfigProvider), configProvider: inject('configProvider', defaultConfigProvider),
@ -79,29 +100,29 @@ const Mentions = {
}); });
}, },
methods: { methods: {
handleFocus(...args) { handleFocus(e: FocusEvent) {
this.$emit('focus', ...args); this.$emit('focus', e);
this.setState({ this.setState({
focused: true, focused: true,
}); });
}, },
handleBlur(...args) { handleBlur(e: FocusEvent) {
this.$emit('blur', ...args); this.$emit('blur', e);
this.setState({ this.setState({
focused: false, focused: false,
}); });
}, },
handleSelect(...args) { handleSelect(...args: [OptionProps, string]) {
this.$emit('select', ...args); this.$emit('select', ...args);
this.setState({ this.setState({
focused: true, focused: true,
}); });
}, },
handleChange(val) { handleChange(val: string) {
this.$emit('update:value', val); this.$emit('update:value', val);
this.$emit('change', val); this.$emit('change', val);
}, },
getNotFoundContent(renderEmpty) { getNotFoundContent(renderEmpty: RenderEmptyHandler) {
const notFoundContent = getComponent(this, 'notFoundContent'); const notFoundContent = getComponent(this, 'notFoundContent');
if (notFoundContent !== undefined) { if (notFoundContent !== undefined) {
return notFoundContent; return notFoundContent;
@ -130,10 +151,10 @@ const Mentions = {
return filterOption; return filterOption;
}, },
focus() { focus() {
this.$refs.vcMentions.focus(); (this.$refs.vcMentions as any).focus();
}, },
blur() { blur() {
this.$refs.vcMentions.blur(); (this.$refs.vcMentions as any).blur();
}, },
}, },
render() { render() {
@ -144,7 +165,7 @@ const Mentions = {
disabled, disabled,
getPopupContainer, getPopupContainer,
...restProps ...restProps
} = getOptionProps(this); } = getOptionProps(this) as any;
const { class: className, ...otherAttrs } = this.$attrs; const { class: className, ...otherAttrs } = this.$attrs;
const prefixCls = getPrefixCls('mentions', customizePrefixCls); const prefixCls = getPrefixCls('mentions', customizePrefixCls);
const otherProps = omit(restProps, ['loading', 'onUpdate:value']); const otherProps = omit(restProps, ['loading', 'onUpdate:value']);
@ -174,10 +195,10 @@ const Mentions = {
return <VcMentions {...mentionsProps} />; return <VcMentions {...mentionsProps} />;
}, },
}; });
/* istanbul ignore next */ /* istanbul ignore next */
Mentions.install = function(app) { Mentions.install = function(app: App) {
app.component(Mentions.name, Mentions); app.component(Mentions.name, Mentions);
app.component(Mentions.Option.name, Mentions.Option); app.component(Mentions.Option.name, Mentions.Option);
return app; return app;

View File

@ -1,5 +1,6 @@
import { PropType } from 'vue';
import PropTypes from '../../_util/vue-types'; import PropTypes from '../../_util/vue-types';
import { initDefaultProps } from '../../_util/props-util'; import initDefaultProps from '../../_util/props-util/initDefaultProps';
import { import {
filterOption as defaultFilterOption, filterOption as defaultFilterOption,
validateSearch as defaultValidateSearch, validateSearch as defaultValidateSearch,
@ -13,15 +14,21 @@ export const mentionsProps = {
value: PropTypes.string, value: PropTypes.string,
defaultValue: PropTypes.string, defaultValue: PropTypes.string,
disabled: PropTypes.looseBool, disabled: PropTypes.looseBool,
notFoundContent: PropTypes.any, notFoundContent: PropTypes.VNodeChild,
split: PropTypes.string, split: PropTypes.string,
transitionName: PropTypes.string, transitionName: PropTypes.string,
placement: PropTypes.oneOf(PlaceMent), placement: PropTypes.oneOf(PlaceMent),
character: PropTypes.any, character: PropTypes.any,
characterRender: PropTypes.func, characterRender: PropTypes.func,
filterOption: PropTypes.func, filterOption: {
validateSearch: PropTypes.func, type: [Boolean, Function] as PropType<false | typeof defaultFilterOption>,
getPopupContainer: PropTypes.func, },
validateSearch: {
type: Function as PropType<typeof defaultValidateSearch>,
},
getPopupContainer: {
type: Function as PropType<() => HTMLElement>,
},
}; };
export const vcMentionsProps = { export const vcMentionsProps = {

View File

@ -1 +1,3 @@
export const PlaceMent = ['top', 'bottom']; import { tuple } from '../../_util/type';
export const PlaceMent = tuple('top', 'bottom');