可自定义设置以下属性:
分割线标题的位置(orientation),类型:'left' | 'center' | 'right',默认 'center'
标题和最近 left/right 边框之间的距离,去除了分割线,同时 orientation 必须为 left 或 right(disabled),类型:string | number,默认 ''
分割线宽度(borderWidth),单位 px,类型:number,默认 1
分割线样式(borderStyle),类型:'solid' | 'dashed' | 'dotted' | 'double' | 'groove' | 'ridge' | 'inset' | 'outset',默认 'solid'
分割线颜色(borderColor),类型:string,默认 'rgba(5, 5, 5, 0.06)'
是否垂直分割(vertical),类型:boolean,默认 false
垂直分割线高度(height),仅当 vertical: true 时生效,类型:string | number,默认 '0.9em'
效果如下图:
在线预览
① 创建分割线组件Divider.vue:
其中引入使用了以下工具函数:
- 监听插槽存在 useSlotsExist
<script setup lang="ts"> import { computed } from 'vue' import { useSlotsExist } from 'components/utils' export interface Props { orientation?: 'left' | 'center' | 'right' // 分割线标题的位置 orientationMargin?: string | number // 标题和最近 left/right 边框之间的距离,去除了分割线,同时 orientation 必须为 left 或 right borderWidth?: number // 分割线宽度,单位 px borderStyle?: 'solid' | 'dashed' | 'dotted' | 'double' | 'groove' | 'ridge' | 'inset' | 'outset' // 分割线样式 borderColor?: string // 分割线颜色 vertical?: boolean // 是否垂直分割 height?: string | number // 垂直分割线高度,仅当 vertical: true 时生效 } const props = withDefaults(defineProps<Props>(), { orientation: 'center', orientationMargin: undefined, borderWidth: 1, borderStyle: 'solid', borderColor: 'rgba(5, 5, 5, 0.06)', vertical: false, height: '0.9em' }) const slotsExist = useSlotsExist(['default']) const margin = computed(() => { if (typeof props.orientationMargin === 'number') { return `${props.orientationMargin}px` } return props.orientationMargin }) const lineHeight = computed(() => { if (typeof props.height === 'number') { return `${props.height}px` } return props.height }) const showText = computed(() => { return slotsExist.default }) </script> <template> <div class="divider-wrap" :class="[ vertical ? 'divider-vertical' : 'divider-horizontal', { 'divider-with-text': showText, 'divider-with-text-center': showText && orientation === 'center', 'divider-with-text-left': showText && orientation === 'left', 'divider-with-text-right': showText && orientation === 'right', 'divider-orientation-margin-left': showText && orientation === 'left' && orientationMargin !== undefined, 'divider-orientation-margin-right': showText && orientation === 'right' && orientationMargin !== undefined } ]" :style="`--border-width: ${borderWidth}px; --border-style: ${borderStyle}; --border-color: ${borderColor}; --margin: ${margin}; --line-height: ${lineHeight};`" > <span v-if="showText" class="divider-text"> <slot></slot> </span> </div> </template> <style lang="less" scoped> .divider-wrap { color: rgba(0, 0, 0, 0.88); font-size: 14px; line-height: 1.5714285714285714; border-top: var(--border-width) var(--border-style) var(--border-color); .divider-text { display: inline-block; padding: 0 1em; } } .divider-horizontal { display: flex; clear: both; width: 100%; min-width: 100%; margin: 24px 0; } .divider-vertical { position: relative; top: -0.06em; display: inline-block; height: var(--line-height); margin: 0 8px; vertical-align: middle; border-top: 0; border-left: var(--border-width) var(--border-style) var(--border-color); } .divider-with-text { display: flex; align-items: center; margin: 16px 0; color: rgba(0, 0, 0, 0.88); font-weight: 500; font-size: 16px; white-space: nowrap; text-align: center; border-top: 0 var(--border-color); &::before, &::after { position: relative; width: 50%; border-top-width: var(--border-width); border-top-style: var(--border-style); border-top-color: inherit; transform: translateY(50%); content: ''; } } .divider-with-text-left { &::before { width: 5%; } &::after { width: 95%; } } .divider-with-text-right { &::before { width: 95%; } &::after { width: 5%; } } .divider-orientation-margin-left { &::before { width: 0; } &::after { width: 100%; } .divider-text { margin-left: var(--margin); padding-left: 0; } } .divider-orientation-margin-right { &::before { width: 100%; } &::after { width: 0; } .divider-text { margin-right: var(--margin); padding-right: 0; } } </style>②在要使用的页面引入:
<script setup lang="ts"> import Divider from './Divider.vue' </script> <template> <div> <h1>{{ $route.name }} {{ $route.meta.title }}</h1> <h2 class="mt30 mb10">基本使用</h2> <Divider>Center Text</Divider> <Divider border-style="dashed">Center Text</Divider> <h2 class="mt30 mb10">中间无文字</h2> <Divider /> <Divider border-style="dashed" /> <h2 class="mt30 mb10">指定文字位置</h2> <Divider>Center Text</Divider> <Divider orientation="left">Left Text</Divider> <Divider orientation="right">Right Text</Divider> <h2 class="mt30 mb10">自定义文字边距</h2> <h3 class="mb10">文字居左(右)并距左(右)边 120px</h3> <Divider orientation="left" :orientation-margin="120">Left Text</Divider> <Divider orientation="right" :orientation-margin="120">Right Text</Divider> <h2 class="mt30 mb10">垂直分割线</h2> <div> Text <Divider vertical /> <a href="#">Link</a> <Divider vertical /> <a href="#">Link</a> </div> <h2 class="mt30 mb10">自定义垂直线高度</h2> <Divider vertical :border-width="3" :height="60" /> <Divider vertical :border-width="3" :height="60" border-style="dashed" /> <Divider vertical :border-width="3" :height="60" border-style="dotted" /> <h2 class="mt30 mb10">自定义样式</h2> <Divider :border-width="3" border-color="orange" /> <Divider :border-width="3" border-style="dashed" border-color="orange" /> <Divider :border-width="3" border-style="dotted" border-color="orange" /> <Flex style="height: 120px"> <Divider vertical :border-width="3" border-color="orange" height="auto" /> <Divider vertical :border-width="3" border-style="dashed" border-color="orange" :height="120" /> <Divider vertical :border-width="3" border-style="dotted" border-color="orange" height="100%" /> </Flex> </div> </template>