1.步骤条样式优化

2.添加简洁版步骤条(属性:simple)
3.添加点击切换时间监听(属性:onChange)方法
This commit is contained in:
dingyongya 2022-01-05 16:51:08 +08:00
parent d3e57feb5d
commit 44a74fc8e5
5 changed files with 317 additions and 60 deletions

View File

@ -15,8 +15,50 @@
<lay-step-item></lay-step-item> <lay-step-item></lay-step-item>
<lay-step-item></lay-step-item> <lay-step-item></lay-step-item>
</lay-step> </lay-step>
<lay-button size="xs" @click="nexts">下一步</lay-button> <div style="margin-top: 10px">
<lay-button size="xs" @click="previous">上一步</lay-button> <lay-button size="xs" @click="previous">上一步</lay-button>
<lay-button size="xs" @click="nexts">下一步</lay-button>
</div>
</div>
</template>
<script>
import { ref } from 'vue';
export default {
setup() {
const loading = ref(true);
const active = ref(-1);
const nexts = () => {
if (active.value++ >=3) active.value = 0
};
const previous = () => {
if (active.value-- ===0) active.value = 0
};
return {
loading,
active
}
}
}
</script>
:::
::: title composition 为row 的排版
:::
::: demo
<template>
<div>
<lay-step :active="active" composition="row">
<lay-step-item title="First" content="First step"></lay-step-item>
<lay-step-item title="Second" content="Second step"></lay-step-item>
<lay-step-item title="Third" content="Third step"></lay-step-item>
<lay-step-item title="Fourth" content="Fourth step"></lay-step-item>
</lay-step>
</div> </div>
</template> </template>
@ -96,8 +138,8 @@ export default {
<lay-step-item title="Second" content="Second step"></lay-step-item> <lay-step-item title="Second" content="Second step"></lay-step-item>
<lay-step-item title="Third" content="Third step"></lay-step-item> <lay-step-item title="Third" content="Third step"></lay-step-item>
</lay-step> </lay-step>
<lay-button size="xs" @click="next">下一步</lay-button>
<lay-button size="xs" @click="previous">上一步</lay-button> <lay-button size="xs" @click="previous">上一步</lay-button>
<lay-button size="xs" @click="next">下一步</lay-button>
</div> </div>
</template> </template>
@ -139,8 +181,8 @@ export default {
<lay-step-item title="Third" content="Third step"></lay-step-item> <lay-step-item title="Third" content="Third step"></lay-step-item>
<lay-step-item title="Fourth" content="Fourth step"></lay-step-item> <lay-step-item title="Fourth" content="Fourth step"></lay-step-item>
</lay-step> </lay-step>
<lay-button size="xs" @click="nexts">下一步</lay-button>
<lay-button size="xs" @click="previous">上一步</lay-button> <lay-button size="xs" @click="previous">上一步</lay-button>
<lay-button size="xs" @click="nexts">下一步</lay-button>
</div> </div>
</template> </template>
@ -180,8 +222,8 @@ export default {
<lay-step-item title="Second" content="Second step"></lay-step-item> <lay-step-item title="Second" content="Second step"></lay-step-item>
<lay-step-item title="Third" content="Third step"></lay-step-item> <lay-step-item title="Third" content="Third step"></lay-step-item>
</lay-step> </lay-step>
<lay-button size="xs" @click="next">下一步</lay-button>
<lay-button size="xs" @click="previous">上一步</lay-button> <lay-button size="xs" @click="previous">上一步</lay-button>
<lay-button size="xs" @click="next">下一步</lay-button>
</div> </div>
</template> </template>
@ -221,8 +263,8 @@ export default {
<lay-step-item title="Second" content="Second step" icon="layui-icon-tree"></lay-step-item> <lay-step-item title="Second" content="Second step" icon="layui-icon-tree"></lay-step-item>
<lay-step-item title="Third" content="Third step" icon="layui-icon-share"></lay-step-item> <lay-step-item title="Third" content="Third step" icon="layui-icon-share"></lay-step-item>
</lay-step> </lay-step>
<lay-button size="xs" @click="next">下一步</lay-button>
<lay-button size="xs" @click="previous">上一步</lay-button> <lay-button size="xs" @click="previous">上一步</lay-button>
<lay-button size="xs" @click="next">下一步</lay-button>
</div> </div>
</template> </template>
@ -266,8 +308,8 @@ export default {
<lay-step-item title="Second" content="Second step"></lay-step-item> <lay-step-item title="Second" content="Second step"></lay-step-item>
<lay-step-item title="Third" content="Third step"></lay-step-item> <lay-step-item title="Third" content="Third step"></lay-step-item>
</lay-step> </lay-step>
<lay-button size="xs" @click="next">下一步</lay-button>
<lay-button size="xs" @click="previous">上一步</lay-button> <lay-button size="xs" @click="previous">上一步</lay-button>
<lay-button size="xs" @click="next">下一步</lay-button>
</div> </div>
</template> </template>
@ -337,6 +379,50 @@ export default {
::: :::
::: title 简洁版
:::
简洁版不支持`垂直``横向``描述``排版`
::: demo
<template>
<div>
<lay-step :active="active" simple @onChange="onChange">
<lay-step-item title="First"></lay-step-item>
<lay-step-item title="Second"></lay-step-item>
<lay-step-item title="Third"></lay-step-item>
</lay-step>
</div>
</template>
<script>
import { ref } from 'vue';
export default {
setup() {
const loading = ref(true);
const active = ref(0);
const next = () => {
if (active.value++ >=2) active.value = 0
};
const previous = () => {
if (active.value-- ===0) active.value = 0
};
const onChange = (index) => {
active.value = index
};
return {
loading,
active
}
}
}
</script>
:::
::: title step步骤条属性 ::: title step步骤条属性
::: :::
@ -348,7 +434,10 @@ export default {
| center | 居中布局 | boolean | `true` `false` | `false` | | center | 居中布局 | boolean | `true` `false` | `false` |
| direction | 垂直/平行布局 | string |`horizontal` `vertical` | `horizontal` | | direction | 垂直/平行布局 | string |`horizontal` `vertical` | `horizontal` |
| space | 宽度 | string | - | `auto` | | space | 宽度 | string | - | `auto` |
| currentStatus | 当前状态显示 | string | `primary` `success` `fail` `warning` | `primary` | | currentStatus | 当前状态显示 | string | `primary` `success` `fail` `warning` | `success` |
| composition | 排版 | string | `default` `row` | `default` |
| simple | 简洁版 | boolean | `true` `false` |`false`|
| onChange | 点击切换时监听 | function | - |function(index){}|
::: :::

View File

@ -365,7 +365,7 @@ export default {
{ {
id: 99, id: 99,
title: "分步", title: "分步",
subTitle: "setup", subTitle: "step",
path: "/zh-CN/components/step", path: "/zh-CN/components/step",
}, },
], ],

View File

@ -1,11 +1,16 @@
@width-height-pace: 20px; @width-height-pace: 24px;
@step-color: #5FB878; @step-color: @step-success-color;
@step-fail-color: #FF5722;
@step-primary-color: #1E9FFF;
@step-warning-color: #FFB800;
@step-success-color: #5FB878;
.lay-step{ .lay-step{
display: flex; display: flex;
flex-wrap: nowrap; flex-wrap: nowrap;
.lay-step-item{ .lay-step-item{
flex-grow: 1; flex-grow: 1;
position: relative;
} }
.is-item-center{ .is-item-center{
@ -16,9 +21,10 @@
flex-grow: 0 !important; flex-grow: 0 !important;
} }
.lay-step-item-pace{ .lay-step-item-pace{
cursor: pointer;
width: @width-height-pace; width: @width-height-pace;
height: @width-height-pace; height: @width-height-pace;
border: 2px #8D8D8D solid; border: 1px #8D8D8D solid;
border-radius: 50%; border-radius: 50%;
text-align: center; text-align: center;
line-height: @width-height-pace; line-height: @width-height-pace;
@ -28,69 +34,88 @@
margin: 0 auto; margin: 0 auto;
} }
.lay-step-item-active{ .lay-step-item-active{
border: 2px @step-color solid; border: 1px @step-color solid;
color: #FFFFFF; color: @step-color;
background: @step-color;
} }
.lay-step-item-wait{ .lay-step-item-wait{
border: 2px #000000 solid; border: 1px #000000 solid;
color: #000000; color: #000000;
} }
.lay-step-item--success { .lay-step-item--success {
border: 2px @step-color solid; border: 1px @step-color solid;
color: #FFFFFF; color: #FFFFFF;
background: @step-color; background: @step-color;
} }
.lay-step-item--fail{ .lay-step-item--fail{
border: 2px #FF5722 solid; border: 1px @step-fail-color solid;
color: #FFFFFF; color: #FFFFFF;
background: #FF5722; background: @step-fail-color;
} }
.lay-step-item--warning{ .lay-step-item--warning{
border: 2px #FFB800 solid; border: 1px @step-warning-color solid;
color: #FFFFFF; color: #FFFFFF;
background: #FFB800; background: @step-warning-color;
} }
.lay-step-item--primary{ .lay-step-item--primary{
border: 2px #1E9FFF solid; border: 1px @step-primary-color solid;
color: #FFFFFF; color: #FFFFFF;
background: #1E9FFF; background: @step-primary-color;
} }
.lay-step-item-success { .lay-step-item-success {
border: 2px @step-color solid; border: 1px @step-color solid;
color: #FFFFFF; color: #FFFFFF;
background: @step-color; background: @step-color;
} }
.lay-step-item-fail{ .lay-step-item-fail{
border: 2px #FF5722 solid; border: 1px @step-fail-color solid;
color: #FFFFFF; color: #FFFFFF;
background: #FF5722; background: @step-fail-color;
} }
.lay-step-item-warning{ .lay-step-item-warning{
border: 2px #FFB800 solid; border: 1px @step-warning-color solid;
color: #FFFFFF; color: #FFFFFF;
background: #FFB800; background: @step-warning-color;
} }
.lay-step-item-primary{ .lay-step-item-primary{
border: 2px #1E9FFF solid; border: 1px @step-primary-color solid;
color: #FFFFFF; color: #FFFFFF;
background: #1E9FFF; background: @step-primary-color;
} }
.lay-step-item-content{ .lay-step-item-content{
color: #8D8D8D; color: #8D8D8D;
cursor: pointer;
.lay-step-item-content-title{ .lay-step-item-content-title{
font-weight: bold; font-weight: bold;
font-size: 16px; font-size: 16px;
} }
} }
.lay-step-item-content-row {
color: #8D8D8D;
position: absolute;
top: 5px;
left: 24px;
width: calc( 100% - 26px );
.lay-step-item-content-title{
word-wrap:break-word;
max-width: calc(100% - 8px);
font-weight: bold;
display: inline-block;
margin-left: 2px;
background: #ffffff;
padding: 0 8px;
font-size: 16px;
}
}
.lay-step-item-content-active{ .lay-step-item-content-active{
color: @step-color; color: @step-color;
} }
@ -99,13 +124,13 @@
color: @step-color; color: @step-color;
} }
.lay-step-item-content--fail{ .lay-step-item-content--fail{
color: #FF5722; color: @step-fail-color;
} }
.lay-step-item-content--warning{ .lay-step-item-content--warning{
color: #FFB800; color: @step-warning-color;
} }
.lay-step-item-content--primary{ .lay-step-item-content--primary{
color: #1E9FFF; color: @step-primary-color;
} }
.lay-step-item-content-wait{ .lay-step-item-content-wait{
@ -115,13 +140,13 @@
color: @step-color; color: @step-color;
} }
.lay-step-item-content-fail{ .lay-step-item-content-fail{
color: #FF5722; color: @step-fail-color;
} }
.lay-step-item-content-warning{ .lay-step-item-content-warning{
color: #FFB800; color: @step-warning-color;
} }
.lay-step-item-content-primary{ .lay-step-item-content-primary{
color: #1E9FFF; color: @step-primary-color;
} }
@ -134,9 +159,9 @@
content: ""; content: "";
position: absolute; position: absolute;
top: 50%; top: 50%;
transform: translateY(-50%); // transform: translateY(-50%);
display: block; display: block;
height: 2px; height: 1px;
width: 100%; width: 100%;
background: #C9C5C5; background: #C9C5C5;
} }
@ -146,22 +171,99 @@
.lay-step-item-line-active:before { .lay-step-item-line-active:before {
transition: background 150ms; transition: background 150ms;
background: #5FB878 !important; background: @step-success-color !important;
} }
.lay-step-item-line-fail:before { .lay-step-item-line-fail:before {
transition: background 150ms; transition: background 150ms;
background: #FF5722 !important; background: @step-fail-color !important;
} }
.lay-step-item-line-warning:before { .lay-step-item-line-warning:before {
transition: background 150ms; transition: background 150ms;
background: #FFB800 !important; background: @step-warning-color !important;
} }
.lay-step-item-line-primary:before { .lay-step-item-line-primary:before {
transition: background 150ms; transition: background 150ms;
background: #1E9FFF !important; background: @step-primary-color !important;
}
.lay-step-simple{
height: 30px;
padding: 0 8px;
line-height: 30px;
color: #ffffff;
background-color: #cecece;
cursor: pointer;
}
.lay-step-item-simple{
padding: 0 18px;
}
.lay-step-item-simple:after{
content: "";
position: absolute;
top: 0;
left: 0;
right: auto;
bottom: auto;
border: 15px solid;
border-color: transparent transparent transparent #cecece;
background-color: transparent;
border-radius: 0;
display: block;
height: auto;
width: auto;
}
.lay-step-item-simple:before{
content: "";
position: absolute;
top: 0;
left: 0;
right: auto;
bottom: auto;
border: 15px solid;
border-color: transparent transparent transparent #cecece;
background-color: transparent;
border-radius: 0;
display: block;
height: auto;
width: auto;
}
.lay-step-item-simple-border:before{
left: 1px;
border-color: transparent transparent transparent #ffffff;
}
.lay-step-item-simple-active {
background-color: #9fd4ae;
}
.lay-step-item-simple-success {
background-color: @step-color;
}
.lay-step-item-simple-fail {
background-color: @step-fail-color;
}
.lay-step-item-simple-warning {
background-color: @step-warning-color;
}
.lay-step-item-simple-primary {
background-color: @step-primary-color;
}
.lay-step-item-simple-active-border:after{
border-color: transparent transparent transparent #9fd4ae !important;
}
.lay-step-item-simple-success-border:after{
border-color: transparent transparent transparent @step-success-color!important;
}
.lay-step-item-simple-fail-border:after{
border-color: transparent transparent transparent @step-fail-color!important;
}
.lay-step-item-simple-warning-border:after{
border-color: transparent transparent transparent @step-warning-color!important;
}
.lay-step-item-simple-primary-border:after{
border-color: transparent transparent transparent @step-primary-color!important;
} }
} }
@ -179,12 +281,15 @@
position: absolute; position: absolute;
top: 0; top: 0;
left: 50%; left: 50%;
transform: translateX(-50%); // transform: translateX(-50%);
display: block; display: block;
width: 2px; width: 1px;
height: 100%; height: 100%;
background: #C9C5C5; background: #C9C5C5;
} }
.lay-step-item-content{
margin-left: 8px;
}
.is-vertical{ .is-vertical{
display: flex; display: flex;
} }

View File

@ -5,7 +5,14 @@
</template> </template>
<script setup name="layStep" lang="ts"> <script setup name="layStep" lang="ts">
import { ref, watch, provide, defineProps, withDefaults } from "vue"; import {
ref,
watch,
provide,
defineProps,
withDefaults,
defineEmits,
} from "vue";
import "./index.less"; import "./index.less";
export interface LayStepProps { export interface LayStepProps {
@ -14,6 +21,8 @@ export interface LayStepProps {
direction?: string; direction?: string;
space?: string; space?: string;
currentStatus?: string; currentStatus?: string;
composition?: string;
simple?: boolean;
} }
const props = withDefaults(defineProps<LayStepProps>(), { const props = withDefaults(defineProps<LayStepProps>(), {
@ -21,11 +30,19 @@ const props = withDefaults(defineProps<LayStepProps>(), {
center: false, center: false,
direction: "horizontal", direction: "horizontal",
space: "auto", space: "auto",
currentStatus: "primary", currentStatus: "success",
composition: "default",
simple: false,
}); });
const steps = ref([]); const steps = ref([]);
const emits = defineEmits(["onChange"]);
const change = (index) => {
emits("onChange", index - 1);
};
watch(steps, () => { watch(steps, () => {
steps.value.forEach( steps.value.forEach(
(instance: { setIndex: (arg0: any) => void }, index: any) => { (instance: { setIndex: (arg0: any) => void }, index: any) => {
@ -37,6 +54,7 @@ watch(steps, () => {
provide("LayStep", { provide("LayStep", {
props, props,
steps, steps,
change,
}); });
</script> </script>

View File

@ -1,8 +1,9 @@
<template> <template>
<div <div
v-if="!simple"
:class="[ :class="[
'lay-step-item', 'lay-step-item',
isLast && !isCenter ? 'lay-step-item-last' : '', isLast && !isCenter && composition !== 'row' ? 'lay-step-item-last' : '',
isCenter ? 'is-item-center' : '', isCenter ? 'is-item-center' : '',
isVertical ? 'is-vertical' : '', isVertical ? 'is-vertical' : '',
]" ]"
@ -27,6 +28,7 @@
isWait ? 'lay-step-item-wait' : '', isWait ? 'lay-step-item-wait' : '',
isCenter ? 'is-center' : '', isCenter ? 'is-center' : '',
]" ]"
@click="onChange(index + 1)"
> >
<slot name="pace"> <slot name="pace">
<template v-if="icon"> <template v-if="icon">
@ -42,21 +44,41 @@
</slot> </slot>
</div> </div>
</div> </div>
<slot>
<div <div
:class="[ :class="[
'lay-step-item-content', 'lay-step-item-content',
composition === 'row' ? 'lay-step-item-content-row' : '',
isActive ? `lay-step-item-content-active` : '', isActive ? `lay-step-item-content-active` : '',
isCurrent === index ? `lay-step-item-content--${currentStatus}` : '', isCurrent === index ? `lay-step-item-content--${currentStatus}` : '',
status ? `lay-step-item-content-${status}` : '', status ? `lay-step-item-content-${status}` : '',
isWait ? 'lay-step-item-content-wait' : '', isWait ? 'lay-step-item-content-wait' : '',
]" ]"
@click="onChange(index + 1)"
> >
<slot>
<div class="lay-step-item-content-title">{{ title }}</div> <div class="lay-step-item-content-title">{{ title }}</div>
<p>{{ content }}</p> <p>{{ content }}</p>
</div>
</slot> </slot>
</div> </div>
</div>
<div
v-else
:class="[
'lay-step-item',
'lay-step-simple',
!isStart ? 'lay-step-item-simple' : '',
'lay-step-item-simple-border',
isActive ? 'lay-step-item-simple-active' : '',
isCurrent === index ? `lay-step-item-simple-${currentStatus}` : '',
isCurrentBorder === index
? `lay-step-item-simple-${currentStatus}-border`
: '',
isSimpleActive ? 'lay-step-item-simple-active-border' : '',
]"
@click="onChange(index + 1)"
>
<slot>{{ index + 1 }}.{{ title }}</slot>
</div>
</template> </template>
<script setup name="LayStepItem" lang="ts"> <script setup name="LayStepItem" lang="ts">
@ -95,6 +117,10 @@ const setIndex = (val: number) => {
index.value = val; index.value = val;
}; };
const onChange = (index) => {
parents.change(index);
};
const stepsCount = computed(() => { const stepsCount = computed(() => {
return parents.steps.value.length; return parents.steps.value.length;
}); });
@ -102,10 +128,21 @@ const stepsCount = computed(() => {
const currentStatus = computed(() => { const currentStatus = computed(() => {
return parents.props.currentStatus; return parents.props.currentStatus;
}); });
const simple = computed(() => {
return parents.props.simple;
});
const composition = computed(() => {
return parents.props.composition;
});
const isCurrent = computed(() => { const isCurrent = computed(() => {
return parents.props.active; return parents.props.active;
}); });
console.log(isCurrent);
const isCurrentBorder = computed(() => {
return parents.props.active + 1;
});
const space = computed(() => { const space = computed(() => {
return parents.props.space; return parents.props.space;
}); });
@ -126,6 +163,10 @@ const isWait: ComputedRef<boolean> = computed(() => {
return index.value === parents.props.active + 1; return index.value === parents.props.active + 1;
}); });
const isSimpleActive: ComputedRef<boolean> = computed(() => {
return index.value - 1 <= parents.props.active;
});
const isActive: ComputedRef<boolean> = computed(() => { const isActive: ComputedRef<boolean> = computed(() => {
return index.value <= parents.props.active; return index.value <= parents.props.active;
}); });
@ -135,6 +176,10 @@ const isLast: ComputedRef<boolean> = computed(() => {
); );
}); });
const isStart: ComputedRef<boolean> = computed(() => {
return parents.steps.value[0]?.itemId === currentInstance.uid;
});
const stepItemState = reactive({ const stepItemState = reactive({
itemId: computed(() => currentInstance?.uid), itemId: computed(() => currentInstance?.uid),
setIndex, setIndex,