Merge remote-tracking branch 'origin/next' into refactor-tree

pull/4577/head
tangjinzhou 2021-08-25 10:10:17 +08:00
commit eff286d0e5
10 changed files with 78 additions and 39 deletions

View File

@ -33,7 +33,7 @@ const AutoComplete = defineComponent({
inheritAttrs: false, inheritAttrs: false,
props: { props: {
...autoCompleteProps, ...autoCompleteProps,
prefixCls: PropTypes.string.def('ant-select'), prefixCls: PropTypes.string,
showSearch: PropTypes.looseBool, showSearch: PropTypes.looseBool,
transitionName: PropTypes.string.def('slide-up'), transitionName: PropTypes.string.def('slide-up'),
choiceTransitionName: PropTypes.string.def('zoom'), choiceTransitionName: PropTypes.string.def('zoom'),

View File

@ -318,14 +318,16 @@ const Form = defineComponent({
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
emit('submit', e); emit('submit', e);
const res = validateFields(); if (props.model) {
res const res = validateFields();
.then(values => { res
emit('finish', values); .then(values => {
}) emit('finish', values);
.catch(errors => { })
handleFinishFailed(errors); .catch(errors => {
}); handleFinishFailed(errors);
});
}
}; };
expose({ expose({

View File

@ -107,6 +107,8 @@ function useForm(
validateInfos: validateInfos; validateInfos: validateInfos;
resetFields: (newValues?: Props) => void; resetFields: (newValues?: Props) => void;
validate: <T = any>(names?: namesType, option?: validateOptions) => Promise<T>; validate: <T = any>(names?: namesType, option?: validateOptions) => Promise<T>;
/** This is an internal usage. Do not use in your prod */
validateField: ( validateField: (
name: string, name: string,
value: any, value: any,
@ -117,19 +119,33 @@ function useForm(
clearValidate: (names?: namesType) => void; clearValidate: (names?: namesType) => void;
} { } {
const initialModel = cloneDeep(unref(modelRef)); const initialModel = cloneDeep(unref(modelRef));
let validateInfos: validateInfos = {}; const validateInfos = reactive<validateInfos>({});
const rulesKeys = computed(() => { const rulesKeys = computed(() => {
return Object.keys(unref(rulesRef)); return Object.keys(unref(rulesRef));
}); });
rulesKeys.value.forEach(key => { watch(
validateInfos[key] = { rulesKeys,
autoLink: false, () => {
required: isRequired(unref(rulesRef)[key]), const newValidateInfos = {};
}; rulesKeys.value.forEach(key => {
}); newValidateInfos[key] = validateInfos[key] || {
validateInfos = reactive(validateInfos); autoLink: false,
required: isRequired(unref(rulesRef)[key]),
};
delete validateInfos[key];
});
for (const key in validateInfos) {
if (Object.prototype.hasOwnProperty.call(validateInfos, key)) {
delete validateInfos[key];
}
}
Object.assign(validateInfos, newValidateInfos);
},
{ immediate: true },
);
const resetFields = (newValues: Props) => { const resetFields = (newValues: Props) => {
Object.assign(unref(modelRef), { Object.assign(unref(modelRef), {
...cloneDeep(initialModel), ...cloneDeep(initialModel),
@ -249,6 +265,9 @@ function useForm(
}, },
!!option.validateFirst, !!option.validateFirst,
); );
if (!validateInfos[name]) {
return promise.catch((e: any) => e);
}
validateInfos[name].validateStatus = 'validating'; validateInfos[name].validateStatus = 'validating';
promise promise
.catch((e: any) => e) .catch((e: any) => e)
@ -325,7 +344,9 @@ function useForm(
validate(names, { trigger: 'change' }); validate(names, { trigger: 'change' });
oldModel = cloneDeep(model); oldModel = cloneDeep(model);
}; };
const debounceOptions = options?.debounce; const debounceOptions = options?.debounce;
watch( watch(
modelRef, modelRef,
debounceOptions && debounceOptions.wait debounceOptions && debounceOptions.wait

View File

@ -1,7 +1,7 @@
// mixins for clearfix // mixins for clearfix
// ------------------------ // ------------------------
.clearfix() { .clearfix() {
zoom: 1;
&::before, &::before,
&::after { &::after {
display: table; display: table;

View File

@ -70,4 +70,35 @@ describe('Switch', () => {
}); });
expect(checked.value).toBe(1); expect(checked.value).toBe(1);
}); });
it('customize checked value and children should work', async () => {
resetWarned();
const checked = ref(1);
const onUpdate = val => (checked.value = val);
const wrapper = mount({
render() {
return (
<Switch
{...{ 'onUpdate:checked': onUpdate }}
checked={checked.value}
unCheckedValue={1}
checkedValue={2}
checkedChildren="on"
unCheckedChildren="off"
/>
);
},
});
await asyncExpect(() => {
wrapper.find('button').trigger('click');
});
expect(checked.value).toBe(2);
expect(wrapper.find('.ant-switch-inner').text()).toBe('on');
await asyncExpect(() => {
wrapper.find('button').trigger('click');
});
expect(checked.value).toBe(1);
expect(wrapper.find('.ant-switch-inner').text()).toBe('off');
});
}); });

View File

@ -134,6 +134,7 @@ const Switch = defineComponent({
[`${prefixCls.value}-disabled`]: props.disabled, [`${prefixCls.value}-disabled`]: props.disabled,
[prefixCls.value]: true, [prefixCls.value]: true,
})); }));
return () => ( return () => (
<Wave insertExtraNode> <Wave insertExtraNode>
<button <button
@ -160,7 +161,7 @@ const Switch = defineComponent({
> >
{props.loading ? <LoadingOutlined class={`${prefixCls.value}-loading-icon`} /> : null} {props.loading ? <LoadingOutlined class={`${prefixCls.value}-loading-icon`} /> : null}
<span class={`${prefixCls.value}-inner`}> <span class={`${prefixCls.value}-inner`}>
{checked.value {checkedStatus.value
? getPropsSlot(slots, props, 'checkedChildren') ? getPropsSlot(slots, props, 'checkedChildren')
: getPropsSlot(slots, props, 'unCheckedChildren')} : getPropsSlot(slots, props, 'unCheckedChildren')}
</span> </span>

View File

@ -115,6 +115,9 @@ const Mentions = {
const { measureText: prevMeasureText, measuring } = this.$data; const { measureText: prevMeasureText, measuring } = this.$data;
const { prefix = '', validateSearch } = this.$props; const { prefix = '', validateSearch } = this.$props;
const target = event.target; const target = event.target;
if (target.composing) {
return;
}
const selectionStartText = getBeforeSelectionText(target); const selectionStartText = getBeforeSelectionText(target);
const { location: measureIndex, prefix: measurePrefix } = getLastMeasureIndex( const { location: measureIndex, prefix: measurePrefix } = getLastMeasureIndex(
selectionStartText, selectionStartText,

View File

@ -1,7 +1,6 @@
import warning, { noteOnce } from '../../vc-util/warning'; import warning, { noteOnce } from '../../vc-util/warning';
import type { SelectProps } from '..'; import type { SelectProps } from '..';
import { convertChildrenToData } from './legacyUtil'; import { convertChildrenToData } from './legacyUtil';
import type { OptionData } from '../interface';
import { toArray } from './commonUtil'; import { toArray } from './commonUtil';
import type { RawValueType, LabelValueType } from '../interface/generator'; import type { RawValueType, LabelValueType } from '../interface/generator';
import { isValidElement } from '../../_util/props-util'; import { isValidElement } from '../../_util/props-util';
@ -36,23 +35,6 @@ function warningProps(props: SelectProps) {
'Please avoid setting option to disabled in tags mode since user can always type text as tag.', 'Please avoid setting option to disabled in tags mode since user can always type text as tag.',
); );
// `combobox` & `tags` should option be `string` type
if (mode === 'tags' || mode === 'combobox') {
const hasNumberValue = mergedOptions.some(item => {
if (item.options) {
return item.options.some(
(opt: OptionData) => typeof ('value' in opt ? opt.value : opt.key) === 'number',
);
}
return typeof ('value' in item ? item.value : item.key) === 'number';
});
warning(
!hasNumberValue,
'`value` of Option should not use number type when `mode` is `tags` or `combobox`.',
);
}
// `combobox` should not use `optionLabelProp` // `combobox` should not use `optionLabelProp`
warning( warning(
mode !== 'combobox' || !optionLabelProp, mode !== 'combobox' || !optionLabelProp,

View File

@ -196,7 +196,7 @@
"webpack": "^5.0.0", "webpack": "^5.0.0",
"webpack-bundle-analyzer": "^4.0.0", "webpack-bundle-analyzer": "^4.0.0",
"webpack-cli": "^4.6.0", "webpack-cli": "^4.6.0",
"webpack-dev-server": "^3.1.14", "webpack-dev-server": "^4.0.0",
"webpack-merge": "^5.0.0", "webpack-merge": "^5.0.0",
"webpackbar": "^5.0.0-3", "webpackbar": "^5.0.0-3",
"xhr-mock": "^2.5.1" "xhr-mock": "^2.5.1"

View File

@ -130,7 +130,6 @@ module.exports = {
historyApiFallback: { historyApiFallback: {
rewrites: [{ from: /./, to: '/index.html' }], rewrites: [{ from: /./, to: '/index.html' }],
}, },
disableHostCheck: true,
hot: true, hot: true,
open: true, open: true,
}, },