refactor(Steps): refactor with composition api

This commit is contained in:
chenjiahan 2020-08-28 14:30:12 +08:00
parent 1237ee6c2c
commit e3cf460762
2 changed files with 80 additions and 65 deletions

View File

@ -1,52 +1,63 @@
import { computed } from 'vue';
import { createNamespace } from '../utils';
import { BORDER } from '../utils/constant';
import { ChildrenMixin } from '../mixins/relation';
import { STEPS_KEY } from '../steps';
import { useParent } from '../composition/use-relation';
import Icon from '../icon';
const [createComponent, bem] = createNamespace('step');
export default createComponent({
mixins: [ChildrenMixin('vanSteps')],
setup(props, { slots }) {
const { parent, index } = useParent(STEPS_KEY);
computed: {
status() {
if (this.index < this.parent.active) {
const getStatus = () => {
const active = +parent.props.active;
if (index.value < active) {
return 'finish';
}
if (this.index === +this.parent.active) {
if (index.value === active) {
return 'process';
}
},
};
active() {
return this.status === 'process';
},
const isActive = () => getStatus() === 'process';
lineStyle() {
if (this.status === 'finish') {
return { background: this.parent.activeColor };
const lineStyle = computed(() => {
const { activeColor, inactiveColor } = parent.props;
if (getStatus() === 'finish') {
return { background: activeColor };
}
return { background: this.parent.inactiveColor };
},
titleStyle() {
if (this.active) {
return { color: this.parent.activeColor };
return { background: inactiveColor };
});
const titleStyle = computed(() => {
const { activeColor, inactiveColor } = parent.props;
if (isActive()) {
return { color: activeColor };
}
if (!this.status) {
return { color: this.parent.inactiveColor };
if (!getStatus()) {
return { color: inactiveColor };
}
},
},
});
methods: {
genCircle() {
const { activeIcon, activeColor, inactiveIcon } = this.parent;
const onClickStep = () => {
parent.emit('click-step', index.value);
};
if (this.active) {
return this.$slots['active-icon'] ? (
this.$slots['active-icon']()
) : (
const renderCircle = () => {
const { activeIcon, activeColor, inactiveIcon } = parent.props;
if (isActive()) {
if (slots['active-icon']) {
return slots['active-icon']();
}
return (
<Icon
class={bem('icon', 'active')}
name={activeIcon}
@ -55,40 +66,36 @@ export default createComponent({
);
}
if (inactiveIcon || this.$slots['inactive-icon']) {
return this.$slots['inactive-icon'] ? (
this.$slots['inactive-icon']()
) : (
<Icon class={bem('icon')} name={inactiveIcon} />
);
if (slots['inactive-icon']) {
return slots['inactive-icon']();
}
return <i class={bem('circle')} style={this.lineStyle} />;
},
if (inactiveIcon) {
return <Icon class={bem('icon')} name={inactiveIcon} />;
}
onClickStep() {
this.parent.$emit('click-step', this.index);
},
},
return <i class={bem('circle')} style={lineStyle.value} />;
};
render() {
const { status, active } = this;
const { direction } = this.parent;
return () => {
const { direction } = parent.props;
const status = getStatus();
return (
<div class={[BORDER, bem([direction, { [status]: status }])]}>
<div
class={bem('title', { active })}
style={this.titleStyle}
onClick={this.onClickStep}
>
{this.$slots.default?.()}
return (
<div class={[BORDER, bem([direction, { [status]: status }])]}>
<div
class={bem('title', { active: isActive() })}
style={titleStyle.value}
onClick={onClickStep}
>
{slots.default?.()}
</div>
<div class={bem('circle-container')} onClick={onClickStep}>
{renderCircle()}
</div>
<div class={bem('line')} style={lineStyle.value} />
</div>
<div class={bem('circle-container')} onClick={this.onClickStep}>
{this.genCircle()}
</div>
<div class={bem('line')} style={this.lineStyle} />
</div>
);
);
};
},
});

View File

@ -1,11 +1,11 @@
import { provide, reactive } from 'vue';
import { createNamespace } from '../utils';
import { ParentMixin } from '../mixins/relation';
const [createComponent, bem] = createNamespace('steps');
export default createComponent({
mixins: [ParentMixin('vanSteps')],
export const STEPS_KEY = 'vanSteps';
export default createComponent({
props: {
activeColor: String,
inactiveIcon: String,
@ -26,10 +26,18 @@ export default createComponent({
emits: ['click-step'],
render() {
return (
<div class={bem([this.direction])}>
<div class={bem('items')}>{this.$slots.default?.()}</div>
setup(props, { emit, slots }) {
const children = reactive([]);
provide(STEPS_KEY, {
emit,
props,
children,
});
return () => (
<div class={bem([props.direction])}>
<div class={bem('items')}>{slots.default?.()}</div>
</div>
);
},