diff --git a/components/_util/props-util.js b/components/_util/props-util.js index 3872ccb86..9c95d149a 100644 --- a/components/_util/props-util.js +++ b/components/_util/props-util.js @@ -133,6 +133,7 @@ const getComponentFromProp = (instance, prop, options = instance, execute = true const componentOptions = instance.componentOptions || {}; (componentOptions.children || []).forEach(child => { if (child.data && child.data.slot === prop) { + delete child.data.slot; if (child.tag === 'template') { slotsProp.push(child.children); } else { diff --git a/components/progress/circle.jsx b/components/progress/circle.jsx index 89db450ee..581bffe9f 100644 --- a/components/progress/circle.jsx +++ b/components/progress/circle.jsx @@ -1,6 +1,5 @@ import { Circle as VCCircle } from '../vc-progress'; import { validProgress } from './utils'; -import { ProgressProps } from './progress'; const statusColorMap = { normal: '#108ee9', diff --git a/components/progress/line.jsx b/components/progress/line.jsx index 6d80d0f5f..bd5d0bd7c 100644 --- a/components/progress/line.jsx +++ b/components/progress/line.jsx @@ -1,5 +1,4 @@ import { validProgress } from './utils'; -import { ProgressProps } from './progress'; const Line = { functional: true, diff --git a/components/radio/Group.jsx b/components/radio/Group.jsx index 68faee769..371dbc40f 100644 --- a/components/radio/Group.jsx +++ b/components/radio/Group.jsx @@ -11,9 +11,7 @@ export default { prop: 'value', }, props: { - prefixCls: { - type: String, - }, + prefixCls: PropTypes.string, defaultValue: PropTypes.any, value: PropTypes.any, size: { @@ -103,7 +101,6 @@ export default { prefixCls={prefixCls} disabled={props.disabled} value={option} - onChange={this.onRadioChange} checked={this.stateValue === option} > {option} @@ -116,7 +113,6 @@ export default { prefixCls={prefixCls} disabled={option.disabled || props.disabled} value={option.value} - onChange={this.onRadioChange} checked={this.stateValue === option.value} > {option.label} diff --git a/components/radio/Radio.jsx b/components/radio/Radio.jsx index d229c483a..b8d8e838c 100644 --- a/components/radio/Radio.jsx +++ b/components/radio/Radio.jsx @@ -12,9 +12,7 @@ export default { prop: 'checked', }, props: { - prefixCls: { - type: String, - }, + prefixCls: PropTypes.string, defaultChecked: Boolean, checked: { type: Boolean, default: undefined }, disabled: Boolean, @@ -41,6 +39,12 @@ export default { blur() { this.$refs.vcCheckbox.blur(); }, + onChange(e) { + this.$emit('change', e); + if (this.radioGroupContext && this.radioGroupContext.onRadioChange) { + this.radioGroupContext.onRadioChange(e); + } + }, }, render() { @@ -60,7 +64,7 @@ export default { if (radioGroup) { radioProps.props.name = radioGroup.name; - radioProps.on.change = radioGroup.onRadioChange; + radioProps.on.change = this.onChange; radioProps.props.checked = props.value === radioGroup.stateValue; radioProps.props.disabled = props.disabled || radioGroup.disabled; } else { diff --git a/components/radio/RadioButton.jsx b/components/radio/RadioButton.jsx index fefa0ce8d..2b4599a1a 100644 --- a/components/radio/RadioButton.jsx +++ b/components/radio/RadioButton.jsx @@ -1,4 +1,5 @@ import Radio from './Radio'; +import PropTypes from '../_util/vue-types'; import { getOptionProps } from '../_util/props-util'; import { ConfigConsumerProps } from '../config-provider'; @@ -6,9 +7,6 @@ export default { name: 'ARadioButton', props: { ...Radio.props, - prefixCls: { - type: String, - }, }, inject: { radioGroupContext: { default: undefined }, diff --git a/components/radio/__tests__/group.test.js b/components/radio/__tests__/group.test.js index 9cb4039a0..add89c5e5 100644 --- a/components/radio/__tests__/group.test.js +++ b/components/radio/__tests__/group.test.js @@ -2,6 +2,7 @@ import { mount } from '@vue/test-utils'; import { asyncExpect } from '@/tests/utils'; import Radio from '../Radio'; import RadioGroup from '../Group'; +import RadioButton from '../radioButton'; describe('Radio', () => { function createRadioGroup(props, listeners = {}) { @@ -50,10 +51,16 @@ describe('Radio', () => { }, }); - wrapper.trigger('mouseenter'); + wrapper + .findAll('div') + .at(0) + .trigger('mouseenter'); expect(onMouseEnter).toHaveBeenCalled(); - wrapper.trigger('mouseleave'); + wrapper + .findAll('div') + .at(0) + .trigger('mouseleave'); expect(onMouseLeave).toHaveBeenCalled(); }); @@ -89,6 +96,80 @@ describe('Radio', () => { }); }); + it('both of radio and radioGroup will trigger onchange event when they exists', async () => { + const onChange = jest.fn(); + const onChangeRadioGroup = jest.fn(); + + const wrapper = mount( + { + props: ['value'], + render() { + const groupProps = {}; + if (this.value !== undefined) { + groupProps.value = this.value; + } + return ( + + + A + + + B + + + C + + + ); + }, + }, + { sync: false }, + ); + const radios = wrapper.findAll('input'); + + // uncontrolled component + wrapper.vm.$refs.radioGroup.stateValue = 'B'; + radios.at(0).trigger('change'); + expect(onChange.mock.calls.length).toBe(1); + expect(onChangeRadioGroup.mock.calls.length).toBe(1); + + // controlled component + wrapper.setProps({ value: 'A' }); + radios.at(1).trigger('change'); + expect(onChange.mock.calls.length).toBe(2); + }); + + it('Trigger onChange when both of radioButton and radioGroup exists', () => { + const onChange = jest.fn(); + const props = {}; + const wrapper = mount( + createRadioGroup(props, { + change: onChange, + }), + { sync: false }, + ); + const radios = wrapper.findAll('input'); + + // uncontrolled component + wrapper.vm.$refs.radioGroup.stateValue = 'B'; + radios.at(0).trigger('change'); + expect(onChange.mock.calls.length).toBe(1); + + // controlled component + wrapper.setProps({ value: 'A' }); + radios.at(1).trigger('change'); + expect(onChange.mock.calls.length).toBe(2); + }); + + // it('should only trigger once when in group with options', () => { + // const onChange = jest.fn(); + // const options = [{ label: 'Bamboo', value: 'Bamboo' }]; + // const wrapper = mount(); + + // wrapper.find('input').trigger('change'); + // expect(onChange).toHaveBeenCalledTimes(1); + // }); + // it('won\'t fire change events when value not changes', async () => { // const onChange = jest.fn() diff --git a/components/radio/__tests__/radio.test.js b/components/radio/__tests__/radio.test.js index 09739fd6f..7141c3072 100644 --- a/components/radio/__tests__/radio.test.js +++ b/components/radio/__tests__/radio.test.js @@ -28,12 +28,12 @@ describe('Radio', () => { { sync: false }, ); await asyncExpect(() => { - wrapper.trigger('mouseenter'); + wrapper.find('label').trigger('mouseenter'); }); await asyncExpect(() => { expect(onMouseEnter).toHaveBeenCalled(); }); - wrapper.trigger('mouseleave'); + wrapper.find('label').trigger('mouseleave'); await asyncExpect(() => { expect(onMouseLeave).toHaveBeenCalled(); }); diff --git a/components/rate/index.jsx b/components/rate/index.jsx index 60c1b070f..006acf993 100644 --- a/components/rate/index.jsx +++ b/components/rate/index.jsx @@ -40,12 +40,7 @@ const Rate = { characterRender(node, { index }) { const { tooltips } = this.$props; if (!tooltips) return node; - const tooltipsProps = { - props: { - title: tooltips[index], - }, - }; - return {node}; + return {node}; }, }, render() { diff --git a/components/select/index.jsx b/components/select/index.jsx index 36ed1013f..c5c687737 100644 --- a/components/select/index.jsx +++ b/components/select/index.jsx @@ -1,4 +1,4 @@ -import warning from 'warning'; +import warning from '../_util/warning'; import omit from 'omit.js'; import PropTypes from '../_util/vue-types'; import { Select as VcSelect, Option, OptGroup } from '../vc-select'; @@ -96,7 +96,6 @@ const Select = { name: 'ASelect', props: { ...SelectProps, - prefixCls: PropTypes.string, showSearch: PropTypes.bool.def(false), transitionName: PropTypes.string.def('slide-up'), choiceTransitionName: PropTypes.string.def('zoom'), diff --git a/components/skeleton/Title.jsx b/components/skeleton/Title.jsx index 2bc922a44..2ffc7911d 100644 --- a/components/skeleton/Title.jsx +++ b/components/skeleton/Title.jsx @@ -1,5 +1,4 @@ import PropTypes from '../_util/vue-types'; -import { initDefaultProps } from '../_util/props-util'; const skeletonTitleProps = { prefixCls: PropTypes.string, diff --git a/components/skeleton/demo/index.vue b/components/skeleton/demo/index.vue index cc37b9e16..65c6d185f 100644 --- a/components/skeleton/demo/index.vue +++ b/components/skeleton/demo/index.vue @@ -16,8 +16,6 @@ const md = { - 网络较慢,需要长时间等待加载处理的情况下。 - 图文信息内容较多的列表/卡片中。 - - 只适合用在第一次加载数据的场景。 - - 可以被 Spin 完全代替,但是在可用的场景下可以比 Spin 提供更好的视觉效果和用户体验。 ## 代码演示`, us: `# Skeleton @@ -27,8 +25,6 @@ const md = { - When resource needs long time to load, like low network speed. - The component contains much information. Such as List or Card. - - Only works when loading data at first time. - - Could be replaced by Spin in all situation, but provide better user experience then spin if it works. ## Examples `, }; @@ -38,12 +34,12 @@ export default { type: 'Feedback', title: 'Skeleton', cols: 1, - render () { + render() { return (
- -
- + +
+

@@ -52,12 +48,12 @@ export default {
-
+
-