diff --git a/src/step/index.js b/src/step/index.js index 0e3390561..346bcd8ea 100644 --- a/src/step/index.js +++ b/src/step/index.js @@ -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 ( - ); + if (slots['inactive-icon']) { + return slots['inactive-icon'](); } - return ; - }, + if (inactiveIcon) { + return ; + } - onClickStep() { - this.parent.$emit('click-step', this.index); - }, - }, + return ; + }; - render() { - const { status, active } = this; - const { direction } = this.parent; + return () => { + const { direction } = parent.props; + const status = getStatus(); - return ( -
-
- {this.$slots.default?.()} + return ( +
+
+ {slots.default?.()} +
+
+ {renderCircle()} +
+
-
- {this.genCircle()} -
-
-
- ); + ); + }; }, }); diff --git a/src/steps/index.js b/src/steps/index.js index 3e17de6ce..d5633d035 100644 --- a/src/steps/index.js +++ b/src/steps/index.js @@ -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 ( -
-
{this.$slots.default?.()}
+ setup(props, { emit, slots }) { + const children = reactive([]); + + provide(STEPS_KEY, { + emit, + props, + children, + }); + + return () => ( +
+
{slots.default?.()}
); },