带有 title 的分割线
带有 title 的分割线
这就是title
这就是title
这就是title
这就是title
这就是title
这就是title3
这就是title2
这就是title
这就是title
调用代码展示
vue
<script setup lang="ts">
import Line from "./Line.vue";
import LineTsx from "./index.tsx";
</script>
<template>
<Line style="margin-top: 20px" title="这就是title" lineStyle="dashed" :lineWidth="5"></Line>
<Line style="margin-top: 20px" title="这就是title" :position="'center'" lineStyle="dotted" color="rgb(206, 46, 17)"></Line>
<Line style="margin-top: 20px" title="这就是title" :position="'right'"></Line>
<Line style="margin-top: 20px" :title="['这就是title']" :position="['left', 'center']"></Line>
<Line style="margin-top: 20px" :title="['这就是title', '这就是title2', '这就是title3']" :position="['right', 'center', 'left']">
</Line>
<LineTsx style="margin-top: 20px" title="这就是title" lineStyle="dashed" :lineWidth="2" :color="`rgb(206, 46, 17)`"
position="center">
</LineTsx>
</template>
组件源码
vue
<!--
/** author:Jinke Yan
time:2023-04-17 18:32:17
*/
-->
<template>
<div class="line">
<div v-if="isShow('left')" class="line-text line-left">
{{ viewTitle("left") }}
</div>
<div class="line-online" :style="computedLineStyle"></div>
<div v-if="isShow('center')" class="line-text line-center">
{{ viewTitle("center") }}
</div>
<div class="line-online" :style="computedLineStyle"></div>
<div v-if="isShow('right')" class="line-text line-right">
{{ viewTitle("right") }}
</div>
</div>
</template>
<script setup lang="ts">
import { computed } from "vue";
import type { StyleValue } from "vue";
import type { position, numberRange10, color, lineStyle } from "docs/types";
interface Props {
lineTitle: string | string[];
linePosition: position | position[];
}
const props = withDefaults(
defineProps<{
title?: Props["lineTitle"];
position?: Props["linePosition"];
lineWidth?: numberRange10;
color?: color;
lineStyle?: lineStyle;
}>(),
{
title: "",
position: "left",
lineWidth: 1,
color: "rgb(220, 220, 220)",
lineStyle: "solid",
}
);
const computedLineStyle = computed<StyleValue>(() => {
return {
flex: 1,
borderTop: `${props.lineWidth}px ${props.lineStyle} ${props.color}`,
};
});
const isShow = (position: position): boolean => {
const positionArray = Array.isArray(props.position)
? props.position
: [props.position];
return positionArray.includes(position);
};
const viewTitle = (position: position): string => {
const titleArray = Array.isArray(props.title) ? props.title : [props.title];
const positionArray = Array.isArray(props.position)
? props.position
: [props.position];
return titleArray[
Math.min(titleArray.length - 1, positionArray.indexOf(position))
];
};
</script>
<style lang="scss" scoped>
@import "./style.module.scss";
</style>
TSX 写法组件源码
tsx
import { defineComponent, computed } from "vue";
import type { PropType } from "vue";
import type { position, numberRange10, color, lineStyle } from "docs/types";
import style from "./style.module.scss";
interface Props {
lineTitle: string | string[];
linePosition: position | position[] | "line";
}
type domType = position | "line";
export default defineComponent({
name: "Line",
props: {
title: {
type: String as PropType<Props["lineTitle"]>,
default: "",
},
position: {
type: String as PropType<Props["linePosition"]>,
default: "left",
},
lineWidth: {
type: Number as PropType<numberRange10>,
default: 1,
},
color: {
type: String as PropType<color>,
default: "rgb(220, 220, 220)",
},
lineStyle: {
type: String as PropType<lineStyle>,
default: "solid",
},
},
setup(props) {
// 获取插槽数据
const computedLineStyle = computed(() => {
return {
flex: 1,
borderTop: `${props.lineWidth}px ${props.lineStyle} ${props.color}`,
};
});
const isShow = (position: position): boolean => {
const positionArray = Array.isArray(props.position)
? props.position
: [props.position];
return positionArray.includes(position);
};
const viewTitle = (position: position): string => {
const titleArray = Array.isArray(props.title)
? props.title
: [props.title];
const positionArray = Array.isArray(props.position)
? props.position
: [props.position];
return titleArray[
Math.min(titleArray.length - 1, positionArray.indexOf(position))
];
};
const itemTypeArr: domType[] = ["left", "line", "center", "line", "right"];
// 渲染组件
return () => (
<div class={style.line}>
{itemTypeArr.map((item) => {
return item === "line" ? (
<div class={style.line} style={computedLineStyle.value}></div>
) : (
isShow(item) && (
<div class={(style.lineText, style[`line-${item}`])}>
{viewTitle(item)}
</div>
)
);
})}
</div>
);
},
});
样式外联
scss
.line {
width: 100%;
display: flex;
align-items: center;
.line-text {
font-weight: bold;
}
&-online {
transform: scaleY(0.5);
}
&-left {
margin-right: 12px;
}
&-center {
margin-right: 12px;
margin-left: 12px;
}
&-right {
margin-left: 12px;
}
}