This commit is contained in:
oneao committed 2025-09-13 17:28:55 +08:00
1 parent 985b42cafb
commit 5e3dccc88b
25 files changed
+931 -543

No files matched your search

@@ -0,0 +1,55 @@
<script setup lang="ts">
</script>
<template>
<div style="padding:20px; max-width:600px;">
<h3>1. 简单水平分割线</h3>
<ASeparator />
<h3>2. 垂直分割线</h3>
<div style="display:flex; align-items:center; gap:16px;">
<span>左</span>
<ASeparator layout="vertical" />
<span>右</span>
</div>
<h3>3. 虚线分割线</h3>
<ASeparator dashed />
<div style="display:flex; align-items:center; gap:16px; margin-top:8px;">
<span>左</span>
<ASeparator layout="vertical" dashed />
<span>右</span>
</div>
<h3>4. 水平分割线带文字</h3>
<ASeparator content="分割文字" align="center" />
<ASeparator content="左侧文字" align="left" />
<ASeparator content="右侧文字" align="right" />
<h3>5. 使用插槽自定义内容</h3>
<ASeparator>
<strong style="color:red">自定义内容</strong>
</ASeparator>
<h3>6. 配合 ASpace 使用 separator</h3>
<ASpace size="middle" separator>
<div style="width:60px;height:40px;background:#eee;">
A
</div>
<div style="width:60px;height:40px;background:#ccc;">
B
</div>
<div style="width:60px;height:40px;background:#aaa;">
C
</div>
</ASpace>
<h3>7. 带自定义 margin</h3>
<ASeparator :margin="12" />
<div style="display:flex; align-items:center; gap:16px; margin-top:8px;">
<span>左</span>
<ASeparator layout="vertical" :margin="[0, 8]" />
<span>右</span>
</div>
</div>
</template>
@@ -0,0 +1,78 @@
@use '../_styles/_variables.scss' as *;
@use 'sass:color';
$separator-prefix: '#{$prefix}-separator';
.#{$separator-prefix} {
margin: 0;
padding: 0;
list-style: none;
font-size: 14px;
font-family: 'PingFang SC', 'Microsoft YaHei', 'Helvetica Neue', Helvetica, Arial, sans-serif;
color: $text-color-base;
box-sizing: border-box;
&.#{$separator-prefix}-layout-horizontal {
width: 100%;
display: flex;
border-top: 1px solid $separator-color;
margin: 6px 0;
align-self: center;
}
&.#{$separator-prefix}-layout-vertical {
border-top: 0;
display: inline-block;
height: 0.9em;
vertical-align: middle;
border-left: 1px solid $separator-color;
margin: 0 4px;
}
&.#{$separator-prefix}-dashed {
// 水平虚线
&.#{$separator-prefix}-layout-horizontal {
border-top-style: dashed;
}
// 垂直虚线
&.#{$separator-prefix}-layout-vertical {
border-left-style: dashed;
}
}
&.#{$separator-prefix}-text {
display: flex;
white-space: nowrap;
align-items: center;
border-top: 0;
&::before,
&::after {
content: '';
width: 50%;
border-top: 1px solid $separator-color;
}
}
& .#{$separator-prefix}-text-inner:not(:empty) {
padding: 0 1em;
display: inline-block;
}
&.#{$separator-prefix}-text-left {
&::before {
width: 10%;
}
&::after {
width: 90%;
}
}
&.#{$separator-prefix}-text-right {
&::before {
width: 90%;
}
&::after {
width: 10%;
}
}
}
@@ -0,0 +1,86 @@
import type { PropType, VNode } from 'vue'
import { defineComponent } from 'vue'
import { getPrefixCls } from '../_utils/getPrefixCls'
export default defineComponent({
name: 'Separator',
props: {
layout: {
type: String as PropType<'horizontal' | 'vertical'>,
default: 'horizontal',
},
dashed: {
type: Boolean,
default: false,
},
align: {
type: String as PropType<'left' | 'right' | 'center'>,
default: 'center',
},
margin: {
type: [Number, Array] as any,
default: null,
},
content: {
type: [String, Object, Function] as unknown as () => string | VNode | (() => VNode),
default: '',
},
class: {
type: [String, Array, Object],
default: '',
},
style: {
type: Object,
default: () => ({}),
},
},
emits: [],
setup(props, { slots }) {
const prefixCls = getPrefixCls('separator')
// 根据 props.margin 生成样式
const marginStyle = () => {
if (props.margin == null)
return {}
if (typeof props.margin === 'number') {
return props.layout === 'horizontal'
? { margin: `${props.margin}px 0` }
: { margin: `0 ${props.margin}px` }
}
if (Array.isArray(props.margin)) {
return { margin: props.margin.map(v => `${v}px`).join(' ') }
}
return {}
}
// 渲染文字或默认插槽
const renderContent = (content: string | VNode | (() => VNode)) => {
if (slots.default)
return slots.default()
if (typeof content === 'function')
return content()
if (typeof content === 'string')
return <span class={`${prefixCls}-content`}>{content}</span>
return content
}
const isHorizontal = props.layout === 'horizontal'
const hasContent = !!(slots.default?.().length || props.content)
return () => (
<div
class={[
prefixCls,
`${prefixCls}-layout-${props.layout}`,
props.dashed ? `${prefixCls}-dashed` : '',
isHorizontal && hasContent ? `${prefixCls}-text` : '',
isHorizontal && hasContent ? `${prefixCls}-text-${props.align}` : '',
props.class,
]}
style={{ ...marginStyle(), ...props.style }}
>
{isHorizontal ? <span class={`${prefixCls}-text-inner`}>{renderContent(props.content)}</span> : null}
</div>
)
},
})