未验证 提交 f9506d70 编写于 作者: L love_forever 提交者: GitHub

Merge pull request #447 from ailululu/next

steps
...@@ -373,6 +373,24 @@ ...@@ -373,6 +373,24 @@
"sort": 16, "sort": 16,
"show": true, "show": true,
"author": "Drjingfubo" "author": "Drjingfubo"
},
{
"name": "Steps",
"sort": 17,
"cName": "步骤条",
"type": "component",
"show": true,
"desc": "步骤条",
"author": "ailululu"
},
{
"name": "Step",
"sort": 17,
"cName": "步骤条子组件",
"type": "component",
"show": false,
"desc": "步骤条子组件",
"author": "ailululu"
} }
] ]
}, },
......
.nut-step {
flex-grow: 0;
flex-shrink: 0;
flex-basis: 33.34%;
text-align: center;
font-size: 0;
&-head {
position: relative;
display: block;
margin-bottom: 10px;
}
&-line {
position: absolute;
top: 11px;
left: 50%;
right: -50%;
display: inline-block;
height: 1px;
background: #909ca4;
}
&-icon {
position: relative;
display: inline-block;
width: 25px;
height: 25px;
line-height: 25px;
font-family: PingFangSC-Medium;
font-size: 13px;
// border-color: #909CA4;
z-index: 1;
.nut-icon {
width: 100%;
height: 100%;
}
&.is-text {
border-radius: 50%;
border-width: 1px;
border-style: solid;
}
&.is-icon {
border-radius: 50%;
border-width: 1px;
border-style: solid;
background-color: transparent;
}
}
&-main {
display: inline-block;
padding-left: 10%;
padding-right: 10%;
text-align: center;
}
&-title {
display: block;
margin-bottom: 10px;
font-size: 14px;
color: #909ca4;
}
&-content {
display: block;
font-size: 14px;
color: #666;
}
&:last-child {
.nut-step-line {
display: none;
}
}
&.nut-step-finish {
.nut-step-head {
color: #3790ff;
border-color: #3790ff;
}
.nut-step-icon.is-text {
background-color: #fff;
}
.nut-step-icon.is-icon {
background-color: #fff;
}
.nut-step-line {
background: #3790ff;
}
.nut-step-title {
color: #3790ff;
}
}
&.nut-step-process {
.nut-step-head {
color: #fff;
border-color: #3790ff;
}
.nut-step-icon.is-text {
background-color: #3790ff;
}
.nut-step-icon.is-icon {
background-color: #3790ff;
}
.nut-step-title {
color: #3790ff;
}
}
&.nut-step-wait {
.nut-step-head {
color: #909ca4;
border-color: #909ca4;
}
.nut-step-icon.is-text {
background-color: #fff;
}
.nut-step-icon.is-icon {
background-color: #fff;
}
.nut-step-content {
color: #909ca4;
}
}
&.nut-step-error {
.nut-step-head {
color: #fff;
border-color: #fa2c19;
}
.nut-step-icon.is-text {
background-color: #fa2c19;
}
.nut-step-icon.is-icon {
background-color: #fa2c19;
}
.nut-step-line {
background: #3790ff;
}
}
}
.nut-steps-vertical {
.nut-step {
display: flex;
height: 33.34%;
}
.nut-step-line {
position: absolute;
display: inline-block;
width: 1px;
height: 100%;
background: #909ca4;
}
.nut-step-main {
display: inline-block;
padding-left: 6%;
text-align: left;
}
&.nut-steps-dot {
.nut-step-head {
margin-top: 7px;
margin-bottom: 0;
}
.nut-step-line {
top: 7px;
left: 50%;
right: -50%;
}
.nut-step-icon {
width: 8px;
height: 8px;
background: #3790ff;
border-radius: 50%;
box-sizing: content-box;
}
.nut-step-wait {
.nut-step-icon {
background-color: #959fb1;
}
.nut-step-content {
color: #909ca4;
}
}
.nut-step-finish {
.nut-step-icon {
background-color: #3790ff;
}
}
.nut-step-process {
.nut-step-icon {
position: relative;
background-color: #3790ff;
&:before {
content: '';
display: inline-block;
position: absolute;
left: 50%;
top: 50%;
margin-left: -7px;
margin-top: -7px;
width: 14px;
height: 14px;
background-color: rgba(55, 144, 255, 0.23);
border-radius: 50%;
}
}
}
}
}
<template>
<view :class="classes">
<view class="nut-step-head">
<view class="nut-step-line"></view>
<view
class="nut-step-icon"
:class="[!state.dot ? (icon ? 'is-icon' : 'is-text') : '']"
>
<template v-if="icon">
<nut-icon class="nut-step-icon-inner" :class="icon" />
</template>
<template v-else-if="state.dot"></template>
<template v-else>
<view class="nut-step-inner">{{ state.index }}</view>
</template>
</view>
</view>
<view class="nut-step-main">
<view class="nut-step-title">
{{ title }}
</view>
<view class="nut-step-content">
{{ content }}
</view>
</view>
</view>
</template>
<script lang="ts">
import { reactive, computed, inject } from 'vue';
import { createComponent } from '@/utils/create';
const { create, componentName } = createComponent('step');
export default create({
props: {
title: {
type: String,
default: ''
},
content: {
type: String,
default: ''
},
icon: {
type: String,
default: null
},
status: {
type: String,
default: null
},
data: {
type: String,
default: null
}
},
setup(props, context) {
const steps: any = inject('stepsParent');
const defaults = context.slots?.default();
console.log('defaults', context.slots);
console.log('steps', steps.props.progressDot);
const state = reactive({
data: [],
index: context.slots.default()[0]?.children - 1,
dot: steps.props.progressDot
});
console.log('dot', state.dot);
// console.log('context', steps.state.steps[state.index])
const classes = computed(() => {
const prefixCls = componentName;
return {
[prefixCls]: true,
[props.status
? 'nut-step-' + props.status
: steps.state.steps[state.index].currentStatus]: true
};
});
return {
state,
classes
};
}
});
</script>
<style scoped lang="scss">
@import 'index.scss';
</style>
<template>
<div class="demo">
<h2>基本用法</h2>
<nut-steps current="1">
<nut-step title="进行中">1</nut-step>
<nut-step title="未开始">2</nut-step>
<nut-step title="未开始">3</nut-step>
</nut-steps>
<h2>标题和描述信息</h2>
<nut-steps current="2">
<nut-step
title="已完成"
content="步骤描述"
icon="nutui-iconfont nut-icon-wanshangshide"
>1</nut-step
>
<nut-step title="进行中" content="步骤描述">2</nut-step>
<nut-step title="未开始" content="步骤描述">3</nut-step>
</nut-steps>
<h2>自定义图标</h2>
<nut-steps current="1">
<nut-step
title="已完成"
icon="nutui-iconfont nut-icon-wanshangshide"
status="error"
>1</nut-step
>
<nut-step title="进行中" icon="nutui-iconfont nut-icon-notice"
>2</nut-step
>
<nut-step
class="nut-step-wait"
title="未开始"
icon="nutui-iconfont nut-icon-notice"
>3</nut-step
>
</nut-steps>
<h2>竖向步骤条</h2>
<div style="height: 300px">
<nut-steps direction="vertical" current="2">
<nut-step
title="已完成"
icon="nutui-iconfont nut-icon-wanshangshide"
content="您的订单已经打包完成,商品已发出"
>1</nut-step
>
<nut-step title="进行中" content="您的订单正在配送途中">2</nut-step>
<nut-step
title="未开始"
content="收货地址为:北京市经济技术开发区科创十一街18号院京东大厦"
>3</nut-step
>
</nut-steps>
</div>
<div style="height: 300px">
<nut-steps direction="vertical" progressDot current="2">
<nut-step title="已完成" content="您的订单已经打包完成,商品已发出"
>1</nut-step
>
<nut-step title="进行中" content="您的订单正在配送途中">2</nut-step>
<nut-step
title="未开始"
content="收货地址为:北京市经济技术开发区科创十一街18号院京东大厦"
>3</nut-step
>
</nut-steps>
</div>
</div>
</template>
<script lang="ts">
import { createComponent } from '@/utils/create';
const { createDemo } = createComponent('steps');
export default createDemo({
props: {},
setup() {
return {};
}
});
</script>
<style lang="scss" scoped>
.demo-box {
}
</style>
# Steps 步骤条 组件
### 介绍
拆分展示某项流程的步骤,引导用户按流程完成任务或向用户展示当前状态。
### 安装
```javascript
import { createApp } from 'vue';
import { Steps } from '@nutui/nutui';
const app = createApp();
app.use(Steps);
```
## 代码演示
### 基本用法
```html
<nut-steps current="1">
<nut-step title="进行中">1</nut-step>
<nut-step title="未开始">2</nut-step>
<nut-step title="未开始">3</nut-step>
</nut-steps>
```
### 标题和描述信息
```html
<nut-steps current="2">
<nut-step title="已完成" content="步骤描述" icon="nutui-iconfont nut-icon-wanshangshide">1</nut-step>
<nut-step title="进行中" content="步骤描述">2</nut-step>
<nut-step title="未开始" content="步骤描述">3</nut-step>
</nut-steps>
```
### 自定义图标
```html
<nut-steps current="1">
<nut-step title="已完成" icon="nutui-iconfont nut-icon-wanshangshide" status="error">1</nut-step>
<nut-step title="进行中" icon="nutui-iconfont nut-icon-notice">2</nut-step>
<nut-step class="nut-step-wait" title="未开始" icon="nutui-iconfont nut-icon-notice">3</nut-step>
</nut-steps>
```
### 竖向步骤条
```html
<nut-steps direction="vertical" current="2">
<nut-step title="已完成" icon="nutui-iconfont nut-icon-wanshangshide" content="您的订单已经打包完成,商品已发出" >1</nut-step>
<nut-step title="进行中" content="您的订单正在配送途中" >2</nut-step>
<nut-step title="未开始" content="收货地址为:北京市经济技术开发区科创十一街18号院京东大厦">3</nut-step>
</nut-steps>
```
### 点状步骤和垂直方向
```html
<nut-steps direction="vertical" progressDot current="2">
<nut-step title="已完成" content="您的订单已经打包完成,商品已发出" >1</nut-step>
<nut-step title="进行中" content="您的订单正在配送途中">2</nut-step>
<nut-step title="未开始" content="收货地址为:北京市经济技术开发区科创十一街18号院京东大厦">3</nut-step>
</nut-steps>
```
## API
### Props
#### nut-steps
| 参数 | 说明 | 类型 | 默认值 |
| ---------------------- | ----------------------------------------------------------- | -------------- | ----------- |
| direction | 显示方向,`horizontal`,`vertical` | String | horizontal |
| current | 当前所在的步骤 | Number、String | 0 |
| progressDot | 点状步骤条 | Boolean | false |
#### nut-step
| 参数 | 说明 | 类型 | 默认值 |
| ---------------- | ---------------------- | ------------ | ----------- |
| title | 流程步骤的标题 | String | 步骤 |
| content | 流程步骤的描述性文字 | String | 步骤描述 |
| icon | 图标 | String | - |
| status | 流程状态 | String | String、Number | "process"(可选值 "wait"、"process"、"finish"、"error" |
\ No newline at end of file
.nut-steps {
display: flex;
}
.nut-steps-vertical {
height: 100%;
flex-flow: column;
}
<template>
<view :class="classes">
<slot></slot>
</view>
</template>
<script lang="ts">
import {
provide,
computed,
onMounted,
reactive,
watch,
onBeforeMount
} from 'vue';
import step from '@/packages/step/index.vue';
import { createComponent } from '@/utils/create';
const { create, componentName } = createComponent('steps');
export default create({
children: [step],
props: {
direction: {
type: String,
default: 'horizontal'
},
current: {
type: String,
default: 'false'
},
status: {
validator(value) {
return ['wait', 'process', 'finish', 'error'].includes(value);
},
default: 'process'
},
progressDot: {
type: Boolean,
default: false
}
},
setup(props, { emit, slots }) {
const state = reactive({
steps: {},
children: []
});
const classes = computed(() => {
const prefixCls = componentName;
return {
[prefixCls]: true,
['nut-steps-' + props.direction]: true,
[props.progressDot ? 'nut-steps-dot' : '']: true
};
});
onBeforeMount(() => {
console.log('onBeforeMount');
init();
});
onMounted(() => {
console.log('onMounted');
// init();
});
// watch(
// () => props.current,
// val => {
// console.log()
// states();
// }
// );
// watch(
// () => props.source,
// val => {
// init();
// }
// )
const init = () => {
state.steps = (slots as any)?.default();
stepStates();
};
const stepStates = () => {
if (props.progressDot) {
console.log('state.steps', state.steps);
state.steps.dot = true;
}
const total = state.steps.length;
state.steps.forEach((child, index) => {
child.stepNumber = index + 1;
state.children = index;
// console.log('data', state.children)
if (props.direction === 'horizontal') {
child.total = total;
}
// console.log('父', child);
if (!child.currentStatus) {
if (index == props.current - 1) {
if (props.status != 'error') {
child.currentStatus = 'nut-step-process';
} else {
child.currentStatus = 'error';
}
} else if (index < props.current) {
child.currentStatus = 'nut-step-finish';
} else {
child.currentStatus = 'nut-step-wait';
}
}
if (index + 1 === total) {
child.currentStatus += ' nut-step-last';
}
});
};
// provide('parent', {
// slots
// });
provide('stepsParent', {
props,
state
});
return {
classes,
stepStates
};
}
});
</script>
<style scoped lang="scss">
@import 'index.scss';
</style>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册