From 77c5f5bec2558ba09c5fa2abef8faec6061dfb80 Mon Sep 17 00:00:00 2001 From: populus Date: Tue, 16 Nov 2021 12:58:40 +0800 Subject: [PATCH 1/2] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0steps-guide?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E5=8F=AF=E9=85=8D=E7=BD=AE=E5=8F=82=E6=95=B0?= =?UTF-8?q?,=E5=AE=8C=E5=96=84=E8=AF=B4=E6=98=8E=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../steps-guide/directive/steps-guide.ts | 7 + .../devui/steps-guide/hooks/index.ts | 2 +- .../steps-guide/hooks/use-steps-guide-ctrl.ts | 39 ++++-- ...de-position.ts => use-steps-guide-posi.ts} | 29 ++-- packages/devui-vue/devui/steps-guide/index.ts | 2 + .../steps-guide/src/steps-guide-types.ts | 18 +++ .../devui/steps-guide/src/steps-guide.tsx | 87 ++++++------ .../docs/components/steps-guide/index.md | 130 ++++++++++++++---- 8 files changed, 214 insertions(+), 100 deletions(-) create mode 100644 packages/devui-vue/devui/steps-guide/directive/steps-guide.ts rename packages/devui-vue/devui/steps-guide/hooks/{use-steps-guide-position.ts => use-steps-guide-posi.ts} (81%) diff --git a/packages/devui-vue/devui/steps-guide/directive/steps-guide.ts b/packages/devui-vue/devui/steps-guide/directive/steps-guide.ts new file mode 100644 index 00000000..cc2088fc --- /dev/null +++ b/packages/devui-vue/devui/steps-guide/directive/steps-guide.ts @@ -0,0 +1,7 @@ +export default { + mounted(el: HTMLElement, binding, vNode) { + }, + updated(el: HTMLElement, binding) { + } + } + \ No newline at end of file diff --git a/packages/devui-vue/devui/steps-guide/hooks/index.ts b/packages/devui-vue/devui/steps-guide/hooks/index.ts index 2cc49d12..63c3fd1b 100644 --- a/packages/devui-vue/devui/steps-guide/hooks/index.ts +++ b/packages/devui-vue/devui/steps-guide/hooks/index.ts @@ -1,2 +1,2 @@ -export * from './use-steps-guide-position' +export * from './use-steps-guide-posi' export * from './use-steps-guide-ctrl' \ No newline at end of file diff --git a/packages/devui-vue/devui/steps-guide/hooks/use-steps-guide-ctrl.ts b/packages/devui-vue/devui/steps-guide/hooks/use-steps-guide-ctrl.ts index 9c1b13a9..e7ca9d2a 100644 --- a/packages/devui-vue/devui/steps-guide/hooks/use-steps-guide-ctrl.ts +++ b/packages/devui-vue/devui/steps-guide/hooks/use-steps-guide-ctrl.ts @@ -1,25 +1,40 @@ -import { ref, nextTick } from 'vue' +import { ref, nextTick, computed, WritableComputedRef, SetupContext } from 'vue' +import { StepsGuideProps, Step } from '../src/steps-guide-types' -export function useStepsGuideCtrl(stepsCount, stepIndex, updateGuidePosition) { - const showSteps = ref(true) - const closeSteps = ():void => { - showSteps.value = false +export function useStepsGuideCtrl( + props: StepsGuideProps, + ctx: SetupContext<('guide-close'|'update:stepIndex')[]>, + updateGuidePosition: Function, + stepIndex: WritableComputedRef + ) { + const stepsCount = computed(() => props.steps.length) + + const closeGuide = () => { + // 缓存关闭前的index, 并在关闭后触发事件 + const _index = stepIndex.value + stepIndex.value = -1 + nextTick(() => { + ctx.emit('guide-close', _index) + }) } const setCurrentIndex = (index:number):void => { - if (index > stepsCount.value || index < 0) index = 0 - stepIndex.value = index - if (!showSteps.value) { - showSteps.value = true + if(index !== -1 && props.stepChange()){ + if(index > -1 && index < stepsCount.value) { + stepIndex.value = index + console.log(stepIndex.value, index, stepsCount.value) nextTick(() => { + console.log(stepIndex.value, index, stepsCount.value) updateGuidePosition() }) } else { - updateGuidePosition() + console.error(`stepIndex is not within the value range`) } + } + if(index === -1) closeGuide() } return { - showSteps, - closeSteps, + stepsCount, + closeGuide, setCurrentIndex } } \ No newline at end of file diff --git a/packages/devui-vue/devui/steps-guide/hooks/use-steps-guide-position.ts b/packages/devui-vue/devui/steps-guide/hooks/use-steps-guide-posi.ts similarity index 81% rename from packages/devui-vue/devui/steps-guide/hooks/use-steps-guide-position.ts rename to packages/devui-vue/devui/steps-guide/hooks/use-steps-guide-posi.ts index 6120300e..146ce438 100644 --- a/packages/devui-vue/devui/steps-guide/hooks/use-steps-guide-position.ts +++ b/packages/devui-vue/devui/steps-guide/hooks/use-steps-guide-posi.ts @@ -1,21 +1,19 @@ -import { Ref, ref, reactive, computed, nextTick } from 'vue' -import { Step, positionConf } from '../src/steps-guide-types' +import { ref, reactive, ComputedRef, nextTick } from 'vue' +import { Step, positionConf, StepsGuideProps } from '../src/steps-guide-types' -export function useStepsGuideNav(steps: Step[], stepIndex:Ref) { - - const currentStep = computed(() => { - const _step = steps[stepIndex.value] - _step.position = _step.position || 'top' - return _step - }) +export function useStepsGuidePosition( + props: StepsGuideProps, + currentStep: ComputedRef) { const guideClassList = ['devui-steps-guide'] const stepsRef = ref(null) const guidePosition = reactive({ left: '', top: '', - zIndex: 1100 + zIndex: props.zIndex }) + const updateGuidePosition = () => { + if(!currentStep.value) return; const baseTop = window.pageYOffset - document.documentElement.clientTop const baseLeft = window.pageXOffset - document.documentElement.clientLeft const currentStepPosition:positionConf = currentStep.value.position @@ -63,13 +61,14 @@ export function useStepsGuideNav(steps: Step[], stepIndex:Ref) { } guidePosition.left = _left + 'px' guidePosition.top = _top + 'px' - nextTick(() => { - // 位置更新后滚动视图 - stepGuideElement.scrollIntoView({behavior: "smooth", block: "nearest", inline: "nearest"}) - }) + if(props.scrollToTargetSwitch) { + nextTick(() => { + // 位置更新后滚动视图 + stepGuideElement.scrollIntoView({behavior: "smooth", block: "nearest", inline: "nearest"}) + }) + } } return { - currentStep, stepsRef, guidePosition, guideClassList, diff --git a/packages/devui-vue/devui/steps-guide/index.ts b/packages/devui-vue/devui/steps-guide/index.ts index 3e41d491..98a5023c 100644 --- a/packages/devui-vue/devui/steps-guide/index.ts +++ b/packages/devui-vue/devui/steps-guide/index.ts @@ -1,6 +1,7 @@ import type { App } from 'vue' import StepsGuide from './src/steps-guide' +import StepsGuideDirective from './directive/steps-guide' StepsGuide.install = function(app: App): void { app.component(StepsGuide.name, StepsGuide) } @@ -13,5 +14,6 @@ export default { status: '50%', install(app: App): void { app.use(StepsGuide as any) + app.directive('StepsGuide', StepsGuideDirective) } } diff --git a/packages/devui-vue/devui/steps-guide/src/steps-guide-types.ts b/packages/devui-vue/devui/steps-guide/src/steps-guide-types.ts index 6c712312..83219f79 100644 --- a/packages/devui-vue/devui/steps-guide/src/steps-guide-types.ts +++ b/packages/devui-vue/devui/steps-guide/src/steps-guide-types.ts @@ -14,6 +14,10 @@ export type Step = { } export const stepsGuideProps = { steps: Array as PropType, + stepIndex: { + type: Number, + default: undefined + }, showClose: { type: Boolean, default: true @@ -21,6 +25,20 @@ export const stepsGuideProps = { showDots: { type: Boolean, default: true + }, + scrollToTargetSwitch: { + type: Boolean, + default: true + }, + zIndex: { + type: Number, + default: 1100 + }, + stepChange: { + type: Function, + default(){ + return true + } } } as const diff --git a/packages/devui-vue/devui/steps-guide/src/steps-guide.tsx b/packages/devui-vue/devui/steps-guide/src/steps-guide.tsx index 93cf84bd..14c621ce 100644 --- a/packages/devui-vue/devui/steps-guide/src/steps-guide.tsx +++ b/packages/devui-vue/devui/steps-guide/src/steps-guide.tsx @@ -1,77 +1,70 @@ import './steps-guide.scss' +import { computed, ref, defineComponent, Teleport, onMounted } from 'vue' +import { stepsGuideProps, StepsGuideProps, Step } from './steps-guide-types' +import { useStepsGuidePosition, useStepsGuideCtrl } from '../hooks' -import { defineComponent, Teleport, ref, onMounted, computed } from 'vue' -import { stepsGuideProps, StepsGuideProps } from './steps-guide-types' -import { useStepsGuideNav, useStepsGuideCtrl } from '../hooks' export default defineComponent({ name: 'DStepsGuide', props: stepsGuideProps, - emits: [], + emits: ['guide-close', 'update:stepIndex'], setup(props: StepsGuideProps, ctx) { - const stepsCount = computed(() => props.steps.length - 1) - const stepIndex = ref(0) + const stepIndexData = ref((props.stepIndex ?? 0) as number) + const stepIndex = computed({ + set: val => { + if(props.stepIndex != null) { + ctx.emit('update:stepIndex', val) + } + stepIndexData.value = val + }, + get: () => stepIndexData.value + }) + const currentStep = computed(() => { + const _step = props.steps[stepIndex.value] + if(_step) _step.position = _step.position || 'top' + return _step + }) + const { - currentStep, stepsRef, guidePosition, guideClassList, - updateGuidePosition } = useStepsGuideNav(props.steps, stepIndex) - const { showSteps, - closeSteps, - setCurrentIndex } = useStepsGuideCtrl(stepsCount, stepIndex, updateGuidePosition) + updateGuidePosition } = useStepsGuidePosition(props, currentStep) + const { + stepsCount, + closeGuide, + setCurrentIndex } = useStepsGuideCtrl(props, ctx, updateGuidePosition, stepIndex) onMounted(() => { updateGuidePosition() }) - - return { - stepsCount, - stepIndex, - showSteps, - guidePosition, - guideClassList, - stepsRef, - currentStep, - setCurrentIndex, - closeSteps - } - }, - render(props) { - const { showSteps, - guidePosition, - guideClassList, - currentStep, - stepIndex, - stepsCount, - setCurrentIndex, - closeSteps, - showClose, - showDots } = props - - return showSteps ? + ctx.expose({ + closeGuide, + setCurrentIndex + }) + return () => stepIndex.value > -1 && stepsCount.value > 0 ? ( -
+
-

{currentStep.title}

- {showClose ?
: null} -
{currentStep.content}
+

{currentStep.value.title}

+ {props.showClose ?
: null} +
{currentStep.value.content}
{ - showDots ? + props.showDots ?
{props.steps.map((step, index) => { - return + return })}
: null }
- {stepIndex > 0 ?
setCurrentIndex(--props.stepIndex)}>{'上一步'}
: null} - {stepIndex === stepsCount ? -
{'我知道啦'}
: -
{ setCurrentIndex(++props.stepIndex) }}>{'我知道啦,继续'}
} + {stepIndex.value > 0 ?
setCurrentIndex(stepIndex.value - 1)}>{'上一步'}
: null} + {stepIndex.value === stepsCount.value - 1 ? +
{'我知道啦'}
: +
{ setCurrentIndex(stepIndex.value + 1) }}>{'我知道啦,继续'}
}
diff --git a/packages/devui-vue/docs/components/steps-guide/index.md b/packages/devui-vue/docs/components/steps-guide/index.md index 4744d655..3c6973d9 100644 --- a/packages/devui-vue/docs/components/steps-guide/index.md +++ b/packages/devui-vue/docs/components/steps-guide/index.md @@ -11,25 +11,94 @@ :::demo ```vue