feat: update radio (#2374)

* feat: update radio

* chore: add @babel/plugin-proposal-optional-chaining
This commit is contained in:
Amour1688 2020-06-13 22:32:10 +08:00 committed by GitHub
parent 5c811049f3
commit 109a386c22
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 112 additions and 100 deletions

View File

@ -1,15 +1,14 @@
import { provide, inject, nextTick } from 'vue';
import classNames from 'classnames';
import PropTypes from '../_util/vue-types';
import Radio from './Radio';
import { getOptionProps, filterEmpty, hasProp, getListeners } from '../_util/props-util';
import { getOptionProps, filterEmpty, hasProp, getSlot } from '../_util/props-util';
import { ConfigConsumerProps } from '../config-provider';
function noop() {}
export default {
name: 'ARadioGroup',
model: {
prop: 'value',
},
inheritAttrs: false,
props: {
prefixCls: PropTypes.string,
defaultValue: PropTypes.any,
@ -35,14 +34,11 @@ export default {
stateValue: value === undefined ? defaultValue : value,
};
},
provide() {
setup() {
return {
radioGroupContext: this,
configProvider: inject('configProvider', ConfigConsumerProps),
};
},
inject: {
configProvider: { default: () => ConfigConsumerProps },
},
computed: {
radioOptions() {
const { disabled } = this;
@ -52,13 +48,6 @@ export default {
: { ...option, disabled: option.disabled === undefined ? disabled : option.disabled };
});
},
classes() {
const { prefixCls, size } = this;
return {
[`${prefixCls}`]: true,
[`${prefixCls}-${size}`]: size,
};
},
},
watch: {
value(val) {
@ -66,6 +55,10 @@ export default {
this.stateValue = val;
},
},
created() {
this.configProvider = inject('configProvider', ConfigConsumerProps);
this.radioGroupContext = provide('radioGroupContext', this);
},
methods: {
onRadioChange(ev) {
const lastValue = this.stateValue;
@ -76,27 +69,32 @@ export default {
// nextTick for https://github.com/vueComponent/ant-design-vue/issues/1280
if (!this.updatingValue && value !== lastValue) {
this.updatingValue = true;
this.$emit('input', value);
this.$emit('update:modelValue', value);
this.$emit('change', ev);
}
this.$nextTick(() => {
nextTick(() => {
this.updatingValue = false;
});
},
},
render() {
const { mouseenter = noop, mouseleave = noop } = getListeners(this);
const { onMouseenter = noop, onMouseleave = noop, class: className, style, id } = this.$attrs;
const props = getOptionProps(this);
const { prefixCls: customizePrefixCls, options, buttonStyle } = props;
const getPrefixCls = this.configProvider.getPrefixCls;
const prefixCls = getPrefixCls('radio', customizePrefixCls);
const groupPrefixCls = `${prefixCls}-group`;
const classString = classNames(groupPrefixCls, `${groupPrefixCls}-${buttonStyle}`, {
[`${groupPrefixCls}-${props.size}`]: props.size,
});
const classString = classNames(
groupPrefixCls,
`${groupPrefixCls}-${buttonStyle}`,
{
[`${groupPrefixCls}-${props.size}`]: props.size,
},
className,
);
let children = filterEmpty(this.$slots.default);
let children = filterEmpty(getSlot(this));
// options, 使
if (options && options.length > 0) {
@ -113,24 +111,29 @@ export default {
{option}
</Radio>
);
} else {
return (
<Radio
key={`radio-group-value-options-${option.value}`}
prefixCls={prefixCls}
disabled={option.disabled || props.disabled}
value={option.value}
checked={this.stateValue === option.value}
>
{option.label}
</Radio>
);
}
return (
<Radio
key={`radio-group-value-options-${option.value}`}
prefixCls={prefixCls}
disabled={option.disabled || props.disabled}
value={option.value}
checked={this.stateValue === option.value}
>
{option.label}
</Radio>
);
});
}
return (
<div class={classString} onMouseenter={mouseenter} onMouseleave={mouseleave}>
<div
class={classString}
onMouseenter={onMouseenter}
onMouseleave={onMouseleave}
style={style}
id={id}
>
{children}
</div>
);

View File

@ -1,13 +1,15 @@
import { inject } from 'vue';
import PropTypes from '../_util/vue-types';
import VcCheckbox from '../vc-checkbox';
import classNames from 'classnames';
import { getOptionProps, getAttrs, getListeners } from '../_util/props-util';
import { getOptionProps } from '../_util/props-util';
import { ConfigConsumerProps } from '../config-provider';
function noop() {}
export default {
name: 'ARadio',
inheritAttrs: false,
model: {
prop: 'checked',
},
@ -23,9 +25,11 @@ export default {
autoFocus: Boolean,
type: PropTypes.string.def('radio'),
},
inject: {
radioGroupContext: { default: undefined },
configProvider: { default: () => ConfigConsumerProps },
setup() {
return {
configProvider: inject('configProvider', ConfigConsumerProps),
radioGroupContext: inject('radioGroupContext'),
};
},
methods: {
focus() {
@ -36,7 +40,7 @@ export default {
},
handleChange(event) {
const targetChecked = event.target.checked;
this.$emit('input', targetChecked);
this.$emit('update:value', targetChecked);
this.$emit('change', event);
},
onChange(e) {
@ -48,38 +52,48 @@ export default {
},
render() {
const { $slots, radioGroupContext: radioGroup } = this;
const { $slots, radioGroupContext: radioGroup, $attrs } = this;
const props = getOptionProps(this);
const children = $slots.default;
const { mouseenter = noop, mouseleave = noop, ...restListeners } = getListeners(this);
const {
onMouseenter = noop,
onMouseleave = noop,
class: className,
style,
...restAttrs
} = $attrs;
const { prefixCls: customizePrefixCls, ...restProps } = props;
const getPrefixCls = this.configProvider.getPrefixCls;
const prefixCls = getPrefixCls('radio', customizePrefixCls);
const radioProps = {
props: { ...restProps, prefixCls },
on: restListeners,
attrs: getAttrs(this),
prefixCls,
...restProps,
...restAttrs,
};
if (radioGroup) {
radioProps.props.name = radioGroup.name;
radioProps.on.change = this.onChange;
radioProps.props.checked = props.value === radioGroup.stateValue;
radioProps.props.disabled = props.disabled || radioGroup.disabled;
radioProps.name = radioGroup.name;
radioProps.onChange = this.onChange;
radioProps.checked = props.value === radioGroup.stateValue;
radioProps.disabled = props.disabled || radioGroup.disabled;
} else {
radioProps.on.change = this.handleChange;
radioProps.onChange = this.handleChange;
}
const wrapperClassString = classNames({
const wrapperClassString = classNames(className, {
[`${prefixCls}-wrapper`]: true,
[`${prefixCls}-wrapper-checked`]: radioProps.props.checked,
[`${prefixCls}-wrapper-disabled`]: radioProps.props.disabled,
[`${prefixCls}-wrapper-checked`]: radioProps.checked,
[`${prefixCls}-wrapper-disabled`]: radioProps.disabled,
});
return (
<label class={wrapperClassString} onMouseenter={mouseenter} onMouseleave={mouseleave}>
<label
class={wrapperClassString}
style={style}
onMouseenter={onMouseenter}
onMouseleave={onMouseleave}
>
<VcCheckbox {...radioProps} ref="vcCheckbox" />
{children !== undefined ? <span>{children}</span> : null}
{$slots.default !== undefined ? <span>{$slots.default()}</span> : null}
</label>
);
},

View File

@ -1,5 +1,6 @@
import { inject } from 'vue';
import Radio from './Radio';
import { getOptionProps, getListeners } from '../_util/props-util';
import { getOptionProps, getSlot } from '../_util/props-util';
import { ConfigConsumerProps } from '../config-provider';
export default {
@ -7,27 +8,27 @@ export default {
props: {
...Radio.props,
},
inject: {
radioGroupContext: { default: undefined },
configProvider: { default: () => ConfigConsumerProps },
setup() {
return {
configProvider: inject('configProvider', ConfigConsumerProps),
radioGroupContext: inject('radioGroupContext'),
};
},
render() {
const { prefixCls: customizePrefixCls, ...otherProps } = getOptionProps(this);
const props = getOptionProps(this);
const { prefixCls: customizePrefixCls, ...otherProps } = props;
const getPrefixCls = this.configProvider.getPrefixCls;
const prefixCls = getPrefixCls('radio-button', customizePrefixCls);
const radioProps = {
props: {
...otherProps,
prefixCls,
},
on: getListeners(this),
prefixCls,
...otherProps,
};
if (this.radioGroupContext) {
radioProps.on.change = this.radioGroupContext.onRadioChange;
radioProps.props.checked = this.$props.value === this.radioGroupContext.stateValue;
radioProps.props.disabled = this.$props.disabled || this.radioGroupContext.disabled;
radioProps.onChange = this.radioGroupContext.onRadioChange;
radioProps.checked = props.value === this.radioGroupContext.stateValue;
radioProps.disabled = props.disabled || this.radioGroupContext.disabled;
}
return <Radio {...radioProps}>{this.$slots.default}</Radio>;
return <Radio {...radioProps}>{getSlot(this)}</Radio>;
},
};

View File

@ -1,17 +1,16 @@
import Radio from './Radio';
import Group from './Group';
import Button from './RadioButton';
import Base from '../base';
// import Base from '../base';
Radio.Group = Group;
Radio.Button = Button;
/* istanbul ignore next */
Radio.install = function(Vue) {
Vue.use(Base);
Vue.component(Radio.name, Radio);
Vue.component(Radio.Group.name, Radio.Group);
Vue.component(Radio.Button.name, Radio.Button);
Radio.install = function(app) {
app.component(Radio.name, Radio);
app.component(Radio.Group.name, Radio.Group);
app.component(Radio.Button.name, Radio.Button);
};
export { Button, Group };

View File

@ -1,13 +1,8 @@
import PropTypes from '../../_util/vue-types';
import { nextTick } from 'vue';
import classNames from 'classnames';
import {
getOptionProps,
hasProp,
initDefaultProps,
getAttrs,
getListeners,
} from '../../_util/props-util';
import PropTypes from '../../_util/vue-types';
import BaseMixin from '../../_util/BaseMixin';
import { getOptionProps, hasProp, initDefaultProps } from '../../_util/props-util';
export default {
name: 'Checkbox',
@ -53,7 +48,7 @@ export default {
},
},
mounted() {
this.$nextTick(() => {
nextTick(() => {
if (this.autoFocus) {
this.$refs.input && this.$refs.input.focus();
}
@ -94,7 +89,7 @@ export default {
this.eventShiftKey = false;
},
onClick(e) {
this.__emit('click', e);
this.$emit('click', e);
// onChangeshiftKey使onClick hack
this.eventShiftKey = e.shiftKey;
},
@ -110,11 +105,12 @@ export default {
readOnly,
tabIndex,
autoFocus,
onFocus,
onBlur,
value,
...others
} = getOptionProps(this);
const attrs = getAttrs(this);
const globalProps = Object.keys({ ...others, ...attrs }).reduce((prev, key) => {
const globalProps = Object.keys({ ...others, ...this.$attrs }).reduce((prev, key) => {
if (key.substr(0, 5) === 'aria-' || key.substr(0, 5) === 'data-' || key === 'role') {
prev[key] = others[key];
}
@ -141,14 +137,11 @@ export default {
autoFocus={autoFocus}
ref="input"
value={value}
{...{
attrs: globalProps,
on: {
...getListeners(this),
change: this.handleChange,
click: this.onClick,
},
}}
onChange={this.handleChange}
onClick={this.onClick}
onFocus={onFocus}
onBlur={onBlur}
{...globalProps}
/>
<span class={`${prefixCls}-inner`} />
</span>

View File

@ -10,6 +10,7 @@ import Affix from 'ant-design-vue/affix';
import Alert from 'ant-design-vue/alert';
import Divider from 'ant-design-vue/divider';
import Anchor from 'ant-design-vue/anchor';
import Radio from 'ant-design-vue/radio';
import ConfigProvider from 'ant-design-vue/config-provider';
import Result from 'ant-design-vue/result';
import Spin from 'ant-design-vue/spin';
@ -34,6 +35,7 @@ createApp(App)
.use(Drawer)
.use(Affix)
.use(Alert)
.use(Radio)
.use(Divider)
.use(Result)
.use(PageHeader)

View File

@ -65,6 +65,7 @@
"@babel/plugin-proposal-class-properties": "^7.8.3",
"@babel/plugin-proposal-export-default-from": "^7.8.3",
"@babel/plugin-proposal-object-rest-spread": "^7.9.6",
"@babel/plugin-proposal-optional-chaining": "^7.10.1",
"@babel/plugin-transform-member-expression-literals": "^7.8.3",
"@babel/plugin-transform-object-assign": "^7.8.3",
"@babel/plugin-transform-property-literals": "^7.8.3",

View File

@ -37,7 +37,8 @@ module.exports = {
],
],
plugins: [
['@ant-design-vue/babel-plugin-jsx', { transformOn: true, compatibleProps: true }],
['@ant-design-vue/babel-plugin-jsx', { transformOn: true }],
'@babel/plugin-proposal-optional-chaining',
'@babel/plugin-transform-object-assign',
'@babel/plugin-proposal-object-rest-spread',
'@babel/plugin-proposal-export-default-from',
@ -85,8 +86,6 @@ module.exports = {
extensions: ['.js', '.jsx', '.vue'],
},
devServer: {
host: 'localhost',
port: 3002,
historyApiFallback: {
rewrites: [{ from: /./, to: '/index.html' }],
},