首先, 我先来看看效果

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>

组件封装 - steps组件相关推荐

  1. vue3中,echarts使用(四)02——柱状图之堆叠条形图-定制化 封装切换tag标签组件 封装title组件

    vue3中,echarts使用(四)02--柱状图之堆叠条形图-定制化 & 封装切换tag标签组件 & 封装title组件 效果 代码 1.主页面 index.vue <temp ...

  2. 《微信小程序-进阶篇》组件封装-Icon组件的实现(一)

    大家好,这是小程序系列的第九篇文章,从这篇开始我们将进入提高篇,在这一个阶段,我们的目标是可以较为深入的了解组件化开发,并且实践积累一些后续项目也就是原神资料站中用得着的组件: 1.<微信小程序 ...

  3. Vue 组件封装、组件传值、数据修改

    Vue 组件封装 封装的意义 当一个页面元素过多或者一个组件在多个页面都会被使用,就可以进行组件封装,可以对单个页面解耦,增加代码的可读性,并且多次使用的组件方便修改,只用修改一个地方就能对用到这个组 ...

  4. Vue2组件封装 Vue组件封装

    写在前面 虽然是Vue2组件封装,主要的内容是记录一下我对封装组件的一些要点和我的看法 --原学习视频来源于b站黑马从0到1封装组件库 什么是组件 都说Vue是组件化开发,确实有道理,别说按钮输入框这 ...

  5. 组件封装--button组件

    模仿elementUI组件库,封装自己的组件库. 一.  主要实现代码 刚开始想要封装width,height属性,可以让用户修改按钮大小.但是会出现一个问题,如果按钮文字 子组件<templa ...

  6. Vue组件封装 ——button组件

    一.基础准备工作 1.创建一个基础的vue项目包 2.创建components文件夹,用于存放组件,新建button.vue组件,可以自己取个名字 <script> export defa ...

  7. 封装Vue组件的原则及技巧

    封装Vue组件的原则及技巧 Vue的组件系统 Vue组件的API主要包含三部分:prop.event.slot props表示组件接收的参数,最好用对象的写法,这样可以针对每个属性设置类型.默认值或自 ...

  8. 2.vue3医疗在线问诊项目 - _登录模块 ==> 代码片段、css变量主题定制、cp-nav-bar组件封装、svg打包精灵图插件、cp-icon组件封装、表单校验、密码登录、短信验证码登录及两者

    2.医疗在线问诊项目 - _登录模块 ==> 代码片段.css变量主题定制.cp-nav-bar组件封装.svg打包精灵图插件.cp-icon组件封装.表单校验.密码登录.短信验证码登录及两者的 ...

  9. 封装 vue 组件的过程记录

    在我们使用vue的开发过程中总会遇到这样的场景,封装自己的业务组件. 封装页面组件前要考虑几个问题: 1.该业务组件的使用场景 2.在什么条件下展示一些什么数据,数据类型是什么样的,及长度颜色等 3. ...

最新文章

  1. VS2013\VS2017 使用git 总是需要输入账号密码
  2. java for循环乘法表_JAVA-for循环案例(冒泡、九九乘法表、素数、菱形)
  3. 调用webservice查询手机号码归属地信息
  4. 【数据结构与算法】2.深度优先搜索DFS、广度优先搜索BFS
  5. 用Python写网络爬虫pdf
  6. Excel条件格式化(conditional formatting)应用
  7. linux添加pacman命令,pacman 命令详解
  8. Python容器专题 - deque(队列)--双向队列对象
  9. 基于boost库的搜索引擎项目
  10. 使用Rufus制作LINUX启动安装U盘(成功)
  11. linux暗黑2黑屏,如何在Ubuntu 20.04中启用全局暗黑模式
  12. 安装包制作工具 SetupFactory 详解
  13. 让游戏沉浸感炸裂的实时3D音效技术原理与实践(上)
  14. Photoshop抠图(磁性套索工具及几个常用案例)
  15. php continue什么意思,php switch continue 什么意思??
  16. 团伙分类:有一份数据部分如下,比如:刘备和关羽有关系,说明他们是一个团伙
  17. [重装系统系列]fcitx 小企鹅输入法 安装 in ubuntu 15.04
  18. (华硕)笔记本电脑启动提示BOOTMEG is missing
  19. 怎么将heic转为jpg格式,哪个图片转换器好用
  20. 关于echart没有数据显示暂无数据

热门文章

  1. 使用PID—tuner做参数整定
  2. 冒泡排序法(C语言)
  3. 电力电子中的宽禁带器件
  4. python怎么打印奇数菱形_python怎么打印菱形
  5. HTTP 、HTTPS
  6. Word表格跨页自动显示表头 自动添加标题
  7. 数据库附加出错解决方法
  8. 中文颜色名称与RGB颜色对照表
  9. Intellij IDEA使用(一)—— 安装Intellij IDEA(ideaIU-2017.2.3)并完成Intellij IDEA的简单配置
  10. 欧拉(Euler)定理