vue封装步骤条组件(文字可上下显示)

因在使用vant时文字不支持上下显示,后自行封装,目前存在一定的问题,请指教

属性介绍
属性类型必传

active

Number | String

index

Number | String

top

String

left

Number | String

子组件

<template>
	<div :class="{ stepItem: true }" :style="flexNum">
		<div
			class="content"
			:class="{ headLeftClass: headLeft && left === 0 }"
			:style="{ left: formatLeft(left) }"
		>
			<div
				@click="emitText"
				class="text"
				:class="{
					textTop: isTop === 'top',
					textBottom: isTop === 'bottom',
					textColor: activeList.includes(index),
				}"
			>
				<slot></slot>
			</div>
			<slot name="icon">
				<div
					class="icon-default"
					:class="{ 'icon-active': activeList.includes(index) }"
				></div>
			</slot>
		</div>
		<div class="line" :class="{ 'line-active': activeList.includes(index) }"></div>
	</div>
</template>

<script>
export default {
	name: 'step0', // 步骤条子级
	props: {
		// 当前组件为唯一标识
		index: {
			type: Number | String,
			default: 0,
			required: true,
		},
		// top 文字显示在上面 bottom 文字显示在下面
		isTop: {
			type: String,
			default: 'top',
		},
		// 控制图标及文字距离右边的距离支持 px %
		left: {
			type: Number | String,
			default: 0,
		},
	},
	data() {
		return {
			flexNum: null, // 首尾flex占比
			headLeft: false, // 第一个子组件默认距离左边的距离
			activeList: [],
		};
	},
	mounted() {
		const arr = [];
		this.$parent.$children.find(item => {
			arr.push(item.index);
			if (item.index === this.$parent.active) return true;
		});
		this.activeList = arr;
		const indexTail = this.$parent.$children[this.$parent.$children.length - 1]._uid;
		const indexHead = this.$parent.$children[0]._uid;
		if (indexHead === this._uid) {
			this.flexNum = {
				flex: 1.3,
			};
			this.headLeft = true;
		} else if (indexTail === this._uid) {
			this.flexNum = {
				flex: 0.3,
			};
		} else {
			this.flexNum = null;
		}
	},
	methods: {
		formatLeft(val) {
			if (typeof val === 'string') {
				return val;
			} else if (typeof val === 'number') {
				return val + 'px';
			} else {
				return 0;
			}
		},
		emitText() {
			this.$parent.$emit('stepItem', this.index);
		},
	},
};
</script>

<style scoped lang="less">
.stepItem {
	position: relative;
	flex: 1;
	width: 100%;
	height: 100%;
	font-size: 14px;
	.headLeftClass {
		left: 18px !important;
	}

	.content {
		position: absolute;
		top: 50%;
		transform: translate(0, -50%);
		width: 1px;
		height: 1px;
		z-index: 2;
		.text {
			position: absolute;
			transform: translate(-50%);
			white-space: nowrap;
			color: #bcbcbc;
		}

		// 完成的文字状态
		.textColor {
			color: #000;
		}
		.textTop:extend(.text) {
			bottom: 12px;
		}
		.textBottom {
			top: 12px;
		}
		.icon-default {
			position: absolute;
			top: -50%;
			transform: translate(-50%, -30%);
			width: 5px;
			height: 5px;
			border-radius: 50%;
			background: #fff;
			border: 1px solid #bcbcbc;
		}
		// 完成的图标样式
		.icon-active {
			width: 10px;
			height: 10px;
			border: 1px solid #d53736;
		}
	}
	.line {
		position: absolute;
		top: 50%;
		left: 0;
		width: 100%;
		height: 1px;
		z-index: 0;
		background: #bcbcbc;
	}
	.line-active {
		background: #d53736;
	}
}
.stepFlex {
	flex: 0.4 !important;
}
</style>

 父组件

<template>
	<div class="steps-content">
		<div class="steps">
			<slot></slot>
		</div>
	</div>
</template>

<script>
export default {
	name: 'steps0', // 步骤条父组件
	props: {
		active: {
			type: Number | String,
			default: 0,
			required: true,
		},
	},
};
</script>

<style scoped lang="less">
.steps-content {
	// overflow: hidden; // 建议打开,需要自行调试文字距离
	padding: 8px 8px;
	.steps {
		display: flex;
		height: 60px;
		padding: 0 10px;
	}
}
</style>

使用

<template>
	<div>
		<div class="testContent">
			<steps :active="1" @stepItem="stepItem">
				<step isTop="bottom" :index="0">
					<div style="text-align: center">
						开始
						<br />
						2019-3-15
					</div>
				</step>
				<step :index="1">待审核</step>
				<step isTop="bottom" :index="2">审核中</step>
				<step :index="3">审核完成</step>
				<step isTop="bottom" :index="4">审核通过</step>
				<step :index="5">完成</step>
			</steps>
		</div>
	</div>
</template>

<script>
import steps from './steps.vue';
import step from './step.vue';
export default {
	name: 'test',
	components: {
		steps,
		step,
	},
	data() {
		return {
			active: 1,
		};
	},
	methods: {
		stepItem(index) {
			console.log('index', index);
		},
	},
};
</script>

<style scoped lang="less">
.testContent {
	width: 99%;
	height: 200px;
	border: 1px solid red;
}
</style>

展示

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值