Vue3步骤条(Steps)

68 篇文章 4 订阅
66 篇文章 3 订阅

Vue2步骤条(Steps)

可自定义设置以下属性:

  • 步骤数组(steps),类型:Array<{title?: string, description?: string}>,默认 []

  • 当前选中的步骤,设置 v-model 后,Steps 变为可点击状态(v-model:current),类型:number,默认 1,从1开始计数

  • 步骤条总宽度(width),类型:string | number,默认 '100%'

  • 描述文本最大宽度(descMaxWidth),类型:number,单位px,默认 120

效果如下图:在线预览

①创建步骤条组件Steps.vue:

<script setup lang="ts">
import { computed } from 'vue'
interface Step {
  title?: string // 标题
  description?: string // 描述
}
interface Props {
  steps: Step[] // 步骤数组
  current?: number // 当前选中的步骤(v-model),设置 v-model 后,Steps 变为可点击状态。从1开始计数
  width?: number|string // 步骤条总宽度
  descMaxWidth?: number // 描述文本最大宽度
}
const props = withDefaults(defineProps<Props>(), {
  steps: () => [],
  current: 1,
  width: '100%',
  descMaxWidth: 120
})
const totalWidth = computed(() => {
  if (typeof props.width === 'number') {
    return props.width + 'px'
  } else {
    return props.width
  }
})
const totalSteps = computed(() => { // 步骤总数
  return props.steps.length
})
const currentStep = computed(() => {
  if (props.current < 1) {
    return 1
  } else if (props.current > totalSteps.value + 1) {
    return totalSteps.value + 1
  } else {
    return props.current
  }
})
// 若当前选中步骤超过总步骤数,则默认选择步骤1
const emits = defineEmits(['update:current', 'change'])
function onChange (index: number) { // 点击切换选择步骤
  if (currentStep.value !== index) {
    emits('update:current', index)
    emits('change', index)
  }
}
</script>
<template>
  <div class="m-steps-area" :style="`width: ${totalWidth};`">
    <div class="m-steps">
      <div :class="['m-steps-item',
          {
            'finish': currentStep > index + 1,
            'process': currentStep === index + 1,
            'wait': currentStep < index + 1
          }
        ]"
        v-for="(step, index) in steps" :key="index">
        <div class="m-info-wrap" @click="onChange(index + 1)">
          <div class="m-steps-icon">
            <span class="u-num" v-if="currentStep <= index + 1">{{ index + 1 }}</span>
            <svg class="u-icon" v-else viewBox="64 64 896 896" data-icon="check" aria-hidden="true" focusable="false"><path d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 0 0-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z"></path></svg>
          </div>
          <div class="m-steps-content">
            <div class="u-steps-title">{{ step.title }}</div>
            <div class="u-steps-description" v-show="step.description" :style="`max-width: ${descMaxWidth}px;`">{{ step.description }}</div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
<style lang="less" scoped>
.m-steps-area {
  margin: 0 auto;
  .m-steps {
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
    .m-steps-item {
      display: inline-block;
      overflow: hidden;
      font-size: 16px;
      &:not(:last-child) {
        flex: 1; // 弹性盒模型对象的子元素都有相同的长度,且忽略它们内部的内容
        .u-steps-title {
          &::after {
            background: #e8e8e8;
            position: absolute;
            top: 16px;
            left: 100%;
            display: block;
            width: 3000px;
            height: 1px;
            content: "";
            cursor: auto;
            transition: all .3s;
          }
        }
      }
      .m-info-wrap {
        display: inline-block;
        .m-steps-icon {
          display: inline-flex;
          align-items: center;
          justify-content: center;
          margin-right: 8px;
          width: 32px;
          height: 32px;
          border-radius: 50%;
          text-align: center;
          background-color: rgba(0, 0, 0, .06);
          border: 1px solid transparent;
          transition: all .3s;
          .u-num {
            display: inline-block;
            font-size: 16px;
            line-height: 1;
            color: rgba(0, 0, 0, .65);
            transition: all .3s;
          }
          .u-icon {
            display: inline-block;
            fill: @themeColor;
            width: 16px;
            height: 16px;
          }
        }
        .m-steps-content {
          display: inline-block;
          vertical-align: top;
          .u-steps-title {
            position: relative;
            display: inline-block;
            padding-right: 16px;
            color: rgba(0, 0, 0, .45);
            line-height: 32px;
            transition: all .3s;
          }
          .u-steps-description {
            font-size: 14px;
            color: rgba(0, 0, 0, .45);
            line-height: 22px;
            word-break: break-all;
            transition: all .3s;
          }
        }
      }
    }
    .finish {
      .m-info-wrap {
        cursor: pointer;
        .m-steps-icon {
          background-color: #e6f4ff;
          border-color: #e6f4ff;
        }
        .m-steps-content {
          .u-steps-title {
            color: rgba(0, 0, 0, .88);
            &::after {
              background: @themeColor;
            }
          }
          .u-steps-description {
            color: rgba(0, 0, 0, .45);
          }
        }
        &:hover {
          .m-steps-icon {
            border-color: @themeColor;
          }
          .m-steps-content {
            .u-steps-title {
              color: @themeColor;
            }
            .u-steps-description {
              color: @themeColor;
            }
          }
        }
      }
    }
    .process {
      .m-info-wrap {
        .m-steps-icon {
          background: @themeColor;
          border: 1px solid rgba(0, 0, 0, .25);
          border-color: @themeColor;
          .u-num {
            color: #fff;
          }
        }
        .m-steps-content {
          .u-steps-title {
            color: rgba(0, 0, 0, .88);
          }
          .u-steps-description {
            color: rgba(0, 0, 0, .88);
          }
        }
      }
    }
    .wait {
      .m-info-wrap {
        cursor: pointer;
        &:hover {
          .m-steps-icon {
            border-color: @themeColor;
            .u-num {
              color: @themeColor;
            }
          }
          .m-steps-content {
            .u-steps-title {
              color: @themeColor;
            }
            .u-steps-description {
              color: @themeColor;
            }
          }
        }
      }
    }
  }
}
</style>

②在要使用的页面引入:

<script setup lang="ts">
import Steps from './Steps.vue'
import { ref, watch } from 'vue'
const steps = ref([
  {
    title: 'Step 1',
    description: 'description 1'
  },
  {
    title: 'Step 2',
    description: 'description 2'
  },
  {
    title: 'Step 3',
    description: 'description 3'
  },
  {
    title: 'Step 4',
    description: 'description 4'
  },
  {
    title: 'Step 5',
    description: 'description 5'
  }
])
const current = ref(3)
watch(current, (to) => {
  console.log('p to:', to)
})

function onChange (index: number) { // 父组件获取切换后的选中步骤
  console.log('current:', index)
}
function onPrevious () {
  if (current.value > 1) {
    current.value--
  }
}
function onNext () {
  if (steps.value.length >= current.value) {
    current.value++
  }
}
</script>
<template>
  <div>
    <h2 class="mb10">Steps 步骤条基本使用</h2>
    <Steps
      :steps="steps"
      :width="'100%'"
      :descMaxWidth="160"
      :current="current"
      @change="onChange" />
    <h2 class="mt30 mb10">步骤条设置 v-model: current 后可点击</h2>
    <Steps
      :steps="steps"
      :width="'100%'"
      :descMaxWidth="160"
      v-model:current="current"
      @change="onChange" />
    <Button @click="onPrevious()" size="large" class="mt30 mr30">Previous</Button>
    <Button @click="onNext()" size="large">Next</Button>
  </div>
</template>
<style lang="less" scoped>
</style>
  • 7
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
Vue2的步骤Steps)是一种常用的UI组件,用于展示多个步骤的进度和状态。下面是使用Vue2步骤的一般步骤: 1. 首先,确保你已经安装了Vue.js和Vue2步骤的依赖包。可以通过npm或者yarn进行安装。 2. 在你的Vue组件中引入Vue2步骤的库文件。可以使用import语句将其引入到你的组件中。 3. 在Vue组件的template中,使用`<steps>`标签来创建步骤组件。可以通过设置不同的属性来定义步骤的样式和行为。 4. 在`<steps>`标签内部,使用`<step>`标签来定义每个步骤。可以设置不同的属性来定义每个步骤的标题、描述和状态。 5. 在Vue组件的script中,可以通过data属性来定义步骤的数据。例如,可以使用一个数组来存储每个步骤的信息。 6. 可以通过methods属性来定义一些方法,用于处理步骤的交互逻辑。例如,可以定义一个方法来处理点击某个步骤时的事件。 7. 最后,在Vue组件的style中,可以定义一些样式来美化步骤的外观。 这是一个简单的示例代码,展示了如何使用Vue2步骤: ```html <template> <div> <steps :current="currentStep"> <step title="Step 1" description="This is step 1"></step> <step title="Step 2" description="This is step 2"></step> <step title="Step 3" description="This is step 3"></step> </steps> </div> </template> <script> import { Steps, Step } from 'vue2-steps'; export default { components: { Steps, Step }, data() { return { currentStep: 0 }; }, methods: { handleStepClick(index) { this.currentStep = index; } } }; </script> <style> /* 样式定义 */ </style> ``` 这样,你就可以在你的Vue应用中使用步骤组件了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值