组件封装 - steps组件

news2024/12/26 20:49:04

首先, 我先来看看效果

steps 组件的封装和 tabs 组件还是相似的

都会去指定两个组件来完成(仿Element UI), 都会去使用 jsx 的语法

让其中一个组件去规定样式和排版, 另外一个组件去接收父组件传入的动态数据

但和面包屑组件还是有区别的(面包屑组件封装):

相同点都是使用两个组件来完成(一个指定排版, 另外一个指定内容), 都是使用 render 函数来进行渲染

不同点是, bread 组件使用的是 h 函数来创建虚拟节点; 然后使用 render 来进行渲染

而 tabs 和 steps 使用的是 jsx 语法来指定标签(使用 jsx 的原因是, 需要指定两个以上的标签且有嵌套关系, 如果使用 h 函数的话太麻烦了)

第一步: 

1. 创建 steps 和 steps-item 组件

2. steps-item 组件接收 title 和 desc 数据

<template>
  <div class="steps">
    <div class="steps-item active" v-for="i in 5" :key="i">
      <div class="step"><span>{{i}}</span></div>
      <div class="title">提交订单</div>
      <div class="desc">2021-03-18 02:11:47</div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'Steps'
}
</script>

<style lang="less">
.steps {
  display: flex;
  text-align: center;
  &-item {
    flex: 1;
    &:first-child {
      .step {
        &::before {
          display: none;
        }
      }
    }
    &:last-child {
      .step {
        &::after {
          display: none;
        }
      }
    }
    &.active {
      .step {
        > span {
          border-color: @xtxColor;
          background: @xtxColor;
          color: #fff
        }
        &::before,&::after {
          background: @xtxColor;
        }
      }
      .title {
        color: @xtxColor;
      }
    }
    .step {
      position: relative;
      > span {
        width: 48px;
        height: 48px;
        font-size: 28px;
        border: 2px solid #e4e4e4;
        background: #fff;
        border-radius: 50%;
        line-height: 44px;
        color: #ccc;
        display: inline-block;
        position: relative;
        z-index: 1;
      }
      &::after,&::before{
        content: "";
        position: absolute;
        top: 23px;
        width: 50%;
        height: 2px;
        background: #e4e4e4;
      }
      &::before {
         left: 0;
      }
      &::after {
         right: 0;
       }
    }
    .title {
      color: #999;
      padding-top: 12px;
    }
    .desc {
      font-size: 12px;
      color: #999;
      padding-top: 6px;
    }
  }
}
</style>

steps-item 主要是去接收外部传入的 title 和 desc 的动态数据, 然后将这些数据直接给到 steps 来进行出来

所以不需要使用 <slot /> 

<script>
export default {
  name: 'StepsItem',
  props: {
    title: {
      type: String,
      default: ''
    },
    desc: {
      type: String,
      default: ''
    }
  }
}
</script>

第二步:

1. 显示 steps 组件数据

也就是在 steps 组件中接收到一个 active 的数据(父组件发送请求获取过来的节点数据)

首先需要拿到所有的 steps-item 组件数据(通过 $slots.default)

然后, 判断 $slots.default 返回的数据中对象中的 type 数据是否为代码片段(这里的详细讲解在 tabs 组件封装时讲过了(tabs 组件封装)

然后指定显示内容

<script>
import { getCurrentInstance } from 'vue'
export default {
  name: 'Steps',
  render () {
    // 这是在proxy的作用相当于vue2中的this
    // 这里其实也可以直接使用this, 因为不是在setup中; 都无所谓的
    const { proxy } = getCurrentInstance()
    const items = proxy.$slots.default()
    const dynamicItems = []
    items.forEach(item => {
      if (item.type.name === 'StepsItem') {
        dynamicItems.push(item)
      } else {
        item.children.forEach(c => {
          dynamicItems.push(c)
        })
      }
    })
    const itemsJsx = dynamicItems.map((item, i) => {
      return <div class="steps-item">
        <div class="step"><span>{i + 1}</span></div>
        <div class="title">{item.props.title}</div>
        <div class="desc">{item.props.desc}</div>
      </div>
    })
    return <div class="steps">{itemsJsx}</div>
  }
}
</script>

<style lang="less">
.steps {
  display: flex;
  text-align: center;
  &-item {
    flex: 1;
    &:first-child {
      .step {
        &::before {
          display: none;
        }
      }
    }
    &:last-child {
      .step {
        &::after {
          display: none;
        }
      }
    }
    &.active {
      .step {
        > span {
          border-color: @xtxColor;
          background: @xtxColor;
          color: #fff
        }
        &::before,&::after {
          background: @xtxColor;
        }
      }
      .title {
        color: @xtxColor;
      }
    }
    .step {
      position: relative;
      > span {
        width: 48px;
        height: 48px;
        font-size: 28px;
        border: 2px solid #e4e4e4;
        background: #fff;
        border-radius: 50%;
        line-height: 44px;
        color: #ccc;
        display: inline-block;
        position: relative;
        z-index: 1;
      }
      &::after,&::before{
        content: "";
        position: absolute;
        top: 23px;
        width: 50%;
        height: 2px;
        background: #e4e4e4;
      }
      &::before {
         left: 0;
      }
      &::after {
         right: 0;
       }
    }
    .title {
      color: #999;
      padding-top: 12px;
    }
    .desc {
      font-size: 12px;
      color: #999;
      padding-top: 6px;
    }
  }
}
</style>

第三步:

1. 在 steps 组件中接收 active 数据, 然后根据 active 数据动态显示 steps 的节点

<script>
import { getCurrentInstance } from 'vue'
export default {
  name: 'Steps',
  props: {
    active: {
      type: Number,
      default: 1
    }
  },
  render () {
    // 这是在proxy的作用相当于vue2中的this
    // 这里其实也可以直接使用this, 因为不是在setup中; 都无所谓的
    const { proxy } = getCurrentInstance()
    const items = proxy.$slots.default()
    const dynamicItems = []
    items.forEach(item => {
      if (item.type.name === 'StepsItem') {
        dynamicItems.push(item)
      } else {
        item.children.forEach(c => {
          dynamicItems.push(c)
        })
      }
    })
    const itemsJsx = dynamicItems.map((item, i) => {
      // 只要是下标值i小于active的div标签都会添加上active类
      return <div class="xtx-steps-item" class={{ active: i < props.active }}>
        <div class="step"><span>{i + 1}</span></div>
        <div class="title">{item.props.title}</div>
        <div class="desc">{item.props.desc}</div>
      </div>
    })
    return <div class="steps">{itemsJsx}</div>
  }
}
</script>

<style lang="less">
.steps {
  display: flex;
  text-align: center;
  &-item {
    flex: 1;
    &:first-child {
      .step {
        &::before {
          display: none;
        }
      }
    }
    &:last-child {
      .step {
        &::after {
          display: none;
        }
      }
    }
    &.active {
      .step {
        > span {
          border-color: @xtxColor;
          background: @xtxColor;
          color: #fff
        }
        &::before,&::after {
          background: @xtxColor;
        }
      }
      .title {
        color: @xtxColor;
      }
    }
    .step {
      position: relative;
      > span {
        width: 48px;
        height: 48px;
        font-size: 28px;
        border: 2px solid #e4e4e4;
        background: #fff;
        border-radius: 50%;
        line-height: 44px;
        color: #ccc;
        display: inline-block;
        position: relative;
        z-index: 1;
      }
      &::after,&::before{
        content: "";
        position: absolute;
        top: 23px;
        width: 50%;
        height: 2px;
        background: #e4e4e4;
      }
      &::before {
         left: 0;
      }
      &::after {
         right: 0;
       }
    }
    .title {
      color: #999;
      padding-top: 12px;
    }
    .desc {
      font-size: 12px;
      color: #999;
      padding-top: 6px;
    }
  }
}
</style>

父组件中使用情况

根据后端的数据来决定 steps 的节点数据

<template>
  <div class="detail-steps">
    <Steps :active="order.orderState===6 ? 1: order.orderState">
      <StepsItem title="提交订单" :desc="order.createTime" />
      <StepsItem title="付款成功" :desc="order.payTime" />
      <StepsItem title="商品发货" :desc="order.consignTime" />
      <StepsItem title="确认收货" :desc="order.evaluationTime" />
      <StepsItem title="订单完成" :desc="order.endTime" />
    </Steps>
  </div>
</template>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/164142.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

v-for 的“就地更新”策略

前言 我们平时使用v-for的时候通常都是加一个唯一标识key&#xff0c;因为不加的时候Vue会给我们发出警告。其实我们加上key的操作&#xff0c;就是为了避免它的“就地更新”策略。我们来看一下官网对“就地更新”的解释&#xff1a; 当 Vue 正在更新使用 v-for 渲染的元素列表…

jsp文化活动系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 JSP 文化活动系统 是一套完善的web设计系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统采用web模式开发&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5开发&#xff0c;数…

第4章 任务看门狗

任务看门狗 主任务死循环 在app_main任务中死循环 #include <stdio.h> #include "esp_log.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h"const char *TAG "COUNTER";int count 0;void app_main(void) {wh…

[翻译]PG15新特性-加速WAL日志归档

PG15新特性-加速WAL日志归档PG15通过&#xff1a;一次扫描64个待归档的日志&#xff0c;将其放到一个数组中以供归档&#xff0c;当处理完这64个文件后&#xff0c;再进行下一次扫描。这样达到减少archive_status目录扫描次数提升性能的目的。WAL归档介绍PG15如何加速归档前&am…

C++ · 入门 · 05 | 内联函数

啊我摔倒了..有没有人扶我起来学习.... &#x1f471;个人主页&#xff1a;《CGod的个人主页》\color{Darkorange}{《CGod的个人主页》}《CGod的个人主页》交个朋友叭~ &#x1f492;个人社区&#xff1a;《编程成神技术交流社区》\color{Darkorange}{《编程成神技术交流社区》…

SegFormer学习笔记(4)train续2

这次关注一下最关键的东西&#xff1a;用什么网络&#xff0c;用什么数据&#xff0c;预训练数据在哪里呢&#xff1f;为了方便&#xff0c;重新贴一下 train.pyimport torch import argparse import yaml import time import multiprocessing as mp from tabulate import tab…

JVM笔记——根据黑马jvm课程课件+自己总结

JVM一、内存结构1、程序计数器&#xff08;PC Register&#xff09;2、虚拟机栈&#xff08;JVM Stacks&#xff09;3、本地方法栈&#xff08;Native Method Stacks&#xff09;4、堆&#xff08;Heap&#xff09;5、方法区&#xff08;Method Area&#xff09;6、直接内存二、…

【爬虫】第七部分 scrapy

【爬虫】第七部分 scrapy 文章目录【爬虫】第七部分 scrapy7. scrapy7.1 基本使用7.2 项目的文件结构7.3 response的方法和属性7.4 小案例7.5 scrapy 工作原理7.6 管道的使用7.7 多管道下载7.8 下载分页类型和get请求的使用7.9 下载多层级类型7.10 post请求的使用总结7. scrapy…

清华大学出版——C语言从入门到精通(第4版)

《C语言从入门到精通&#xff08;第4版&#xff09;》是清华大学出版社出版的图书&#xff0c;该书从初学者的角度出发&#xff0c;以通俗易懂的语言&#xff0c;丰富多彩的实例&#xff0c;详细介绍了使用C语言进行程序开发需要掌握的各方面知识。《C语言从入门到精通&#xf…

YOLO v8详解

回顾一下YOLOv5 Backbone&#xff1a;CSPDarkNet结构&#xff0c;主要结构思想的体现在C3模块&#xff0c;这里也是梯度分流的主要思想所在的地方&#xff1b;PAN-FPN&#xff1a;双流的FPN&#xff0c;但是量化还是有些需要图优化才可以达到最优的性能&#xff0c;比如cat前后…

VSCode 配置Go环境,弹出警告“golps”等插件要求下载但下载时超时、失去连接等 解决方案

1. 背景&#xff1a; 下载完GO环境和VSCode的GO配套插件后&#xff0c;试图运行hello world程序&#xff0c;此时VSCode弹出警告&#xff1a; 提示有几个go的工具没有下载&#xff0c;于是我点击install 下载&#xff1a; 》下载时报错&#xff0c;一般是出现超时timeout错误…

57 mac 中 SIGINFO 信号, jdk8 支持, 但是 jdk9 不支持?

前言 问题来自于文章 shell脚本 后台启动 程序1 “tail -f log“, ctrl c 导致程序1中断 中的测试用例 Test07Signal2ParentProcess, 可以看到 我当时标记了一个 "todo, not work in hostpostVM9" 然后 问题是这样的, 我同一台机器, 然后 jdk8 带上 SIGINFO 去执行…

【已解决】右键以某应用打开xx文件时,没有“默认”选项怎么办

问题解决方案简单来说详细操作解释问题 右键以某应用打开xx文件时&#xff0c;没有“默认”选项 解决方案 简单来说 在注册表&#xff1a;计算机\HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\找到要打开的文件后缀名&#xff0c;删除…

mybatis plus基本使用初体验01

我们都知道MyBatis是目前比较常用的持久层框架&#xff1b;这个框架的使用也是很简单的&#xff0c;我们在使用的时候&#xff0c;只需要关注mapper的接口层和对应的xml文件即可。 但是MyBatis作为一个半自动框架&#xff0c;是需要我们自己手动编写sql语句的&#xff0c;对于…

Linux系统软件安装

在Linux上部署各类软件MySQL数据库管理系统安装部署简介注意MySQL5.7版本在CentOS系统安装安装配置MySQL8.0版本在CentOS系统安装安装配置MySQL5.7版本在Ubuntu&#xff08;WSL环境&#xff09;系统安装安装MySQL8.0版本在Ubuntu&#xff08;WSL环境&#xff09;系统安装安装To…

Web服务统一身份认证协议设计与实现

单点登录(SSO)是目前比较流行的企业业务整合的解决方案之一,它的机制是在企业网络用户访问企业网站时作一次身份认证,随后就可以对所有被授权的网络资源进行无缝的访问,而不需要多次输入自己的认证信息.Web服务具有松散耦合、语言中立、平台无关性、开放性的特性,通过对集中单点…

Qt扫盲-Qt 属性系统记录

Qt 属性系统记录一、概述二、属性声明三、通过元对象系统读写属性四、简单例子五、动态属性六、对一个类添加额外的属性一、概述 Qt 提供了一个复杂的属性系统&#xff0c;类似于一些编译器供应商提供的系统。然而&#xff0c;作为一个独立于编译器和平台的库&#xff0c;Qt并…

Java基础07——集合

Java基础07——集合一、集合和数组的对比二、ArrayList成员方法三、集合练习1. 添加数字并遍历2. 添加学生对象并遍历学生类测试类输出结果3. 添加用户对象并判断是否存在用户类测试类输出结果4. 添加手机对象并返回要求的数据&#xff08;返回多个数据&#xff09;手机类测试类…

【算法】Day06

努力经营当下&#xff0c;直至未来明朗&#xff01; 文章目录1. BST二叉搜索树的后序遍历序列2. 二叉树中和为某一值的路径&#xff08;二&#xff09;[回溯法]3. 字符串的排列 [全排列问题]4. 最小的K个数 [topK问题]普通小孩也要热爱生活&#xff01; 1. BST二叉搜索树的后序…

IF:6+ 综合分析揭示了一种炎症性癌症相关的成纤维细胞亚型在预测膀胱癌患者的预后和免疫治疗反应方面具有重要意义...

桓峰基因的教程不但教您怎么使用&#xff0c;还会定期分析一些相关的文章&#xff0c;学会教程只是基础&#xff0c;但是如果把分析结果整合到文章里面才是目的&#xff0c;觉得我们这些教程还不错&#xff0c;并且您按照我们的教程分析出来不错的结果发了文章记得告知我们&…