refactor(Radio): refactor with composition api

This commit is contained in:
chenjiahan 2020-09-25 15:30:21 +08:00
parent 3402ba5c8f
commit aafbcfcf04
3 changed files with 51 additions and 51 deletions

View File

@ -33,17 +33,21 @@ export default defineComponent({
setup(props, { emit, slots }) { setup(props, { emit, slots }) {
const iconRef = ref(); const iconRef = ref();
const getParentProp = (name: string) => {
if (props.parent) {
return props.parent.props[name];
}
return null;
};
const disabled = computed( const disabled = computed(
() => (props.parent && props.parent.disabled) || props.disabled () => getParentProp('disabled') || props.disabled
); );
const direction = computed( const direction = computed(() => getParentProp('direction') || null);
() => (props.parent && props.parent.direction) || null
);
const iconStyle = computed(() => { const iconStyle = computed(() => {
const checkedColor = const checkedColor = props.checkedColor || getParentProp('checkedColor');
props.checkedColor || (props.parent && props.parent.checkedColor);
if (checkedColor && props.checked && !disabled.value) { if (checkedColor && props.checked && !disabled.value) {
return { return {
@ -72,8 +76,8 @@ export default defineComponent({
}; };
const renderIcon = () => { const renderIcon = () => {
const { bem, shape, parent, checked } = props; const { bem, shape, checked } = props;
const iconSize = props.iconSize || (parent && parent.iconSize); const iconSize = props.iconSize || getParentProp('iconSize');
return ( return (
<div <div

View File

@ -1,32 +1,39 @@
import { watch } from 'vue';
import { createNamespace } from '../utils'; import { createNamespace } from '../utils';
import { FieldMixin } from '../mixins/field'; import { useChildren } from '../composition/use-relation';
import { ParentMixin } from '../mixins/relation'; import { useParentField } from '../composition/use-parent-field';
const [createComponent, bem] = createNamespace('radio-group'); const [createComponent, bem] = createNamespace('radio-group');
export default createComponent({ export const RADIO_KEY = 'vanRadio';
mixins: [ParentMixin('vanRadio'), FieldMixin],
export default createComponent({
props: { props: {
disabled: Boolean, disabled: Boolean,
iconSize: [Number, String],
direction: String, direction: String,
modelValue: null, modelValue: null,
checkedColor: String, checkedColor: String,
iconSize: [Number, String],
}, },
emits: ['change', 'update:modelValue'], emits: ['change', 'update:modelValue'],
watch: { setup(props, { emit, slots }) {
value(value) { const { linkChildren } = useChildren(RADIO_KEY);
this.$emit('change', value);
},
},
render() { watch(
return ( () => props.modelValue,
<div class={bem([this.direction])} role="radiogroup"> (value) => {
{this.$slots.default?.()} emit('change', value);
}
);
linkChildren({ emit, props });
useParentField(() => props.modelValue);
return () => (
<div class={bem([props.direction])} role="radiogroup">
{slots.default?.()}
</div> </div>
); );
}, },

View File

@ -1,48 +1,37 @@
import { pick, createNamespace } from '../utils'; import { pick, createNamespace } from '../utils';
import { ChildrenMixin } from '../mixins/relation'; import { useParent } from '../composition/use-relation';
import Checker, { checkerProps } from '../checkbox/Checker'; import Checker, { checkerProps } from '../checkbox/Checker';
import { RADIO_KEY } from '../radio-group';
const [createComponent, bem] = createNamespace('radio'); const [createComponent, bem] = createNamespace('radio');
export default createComponent({ export default createComponent({
mixins: [ChildrenMixin('vanRadio')],
props: checkerProps, props: checkerProps,
emits: ['update:modelValue'], emits: ['update:modelValue'],
computed: { setup(props, { emit, slots }) {
currentValue: { const { parent } = useParent(RADIO_KEY);
get() {
return this.parent ? this.parent.modelValue : this.modelValue;
},
set(val) { const checked = () => {
(this.parent || this).$emit('update:modelValue', val); const value = parent ? parent.props.modelValue : props.modelValue;
}, return value === props.name;
}, };
checked() { const toggle = () => {
return this.currentValue === this.name; const emitter = parent ? parent.emit : emit;
}, emitter('update:modelValue', props.name);
}, };
methods: { return () => (
toggle() {
this.currentValue = this.name;
},
},
render() {
return (
<Checker <Checker
v-slots={pick(this.$slots, ['default', 'icon'])} v-slots={pick(slots, ['default', 'icon'])}
bem={bem} bem={bem}
role="radio" role="radio"
parent={this.parent} parent={parent}
checked={this.checked} checked={checked()}
onToggle={this.toggle} onToggle={toggle}
{...this.$props} {...props}
/> />
); );
}, },