You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
135 lines
3.1 KiB
Vue
135 lines
3.1 KiB
Vue
<template>
|
|
<view
|
|
@click="handleClick"
|
|
:class="`wd-sidebar-item ${active ? 'wd-sidebar-item--active' : ''} ${prefix ? 'wd-sidebar-item--prefix' : ''} ${
|
|
suffix ? 'wd-sidebar-item--suffix' : ''
|
|
} ${disabled ? 'wd-sidebar-item--disabled' : ''} ${customClass}`"
|
|
:style="customStyle"
|
|
>
|
|
<slot name="icon"></slot>
|
|
<template v-if="!$slots.icon && icon">
|
|
<wd-icon custom-class="wd-sidebar-item__icon" :name="icon" size="20px"></wd-icon>
|
|
</template>
|
|
<wd-badge :model-value="badge" :is-dot="isDot" :max="max" v-bind="badgeProps" custom-class="wd-sidebar-item__badge">
|
|
{{ label }}
|
|
</wd-badge>
|
|
</view>
|
|
</template>
|
|
|
|
<script lang="ts">
|
|
export default {
|
|
name: 'wd-sidebar-item',
|
|
options: {
|
|
addGlobalClass: true,
|
|
virtualHost: true,
|
|
styleIsolation: 'shared'
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<script lang="ts" setup>
|
|
import { computed } from 'vue'
|
|
import { useParent } from '../composables/useParent'
|
|
import { SIDEBAR_KEY } from '../wd-sidebar/types'
|
|
|
|
type BadgeType = 'primary' | 'success' | 'warning' | 'danger' | 'info'
|
|
interface BadgeProps {
|
|
modelValue?: number | string | null
|
|
bgColor?: string
|
|
max?: number
|
|
isDot?: boolean
|
|
hidden?: boolean
|
|
type?: BadgeType
|
|
top?: number
|
|
right?: number
|
|
customClass?: string
|
|
customStyle?: string
|
|
}
|
|
|
|
interface Props {
|
|
// 当前选项标题
|
|
label: string
|
|
// 当前选项的值,唯一标识
|
|
value: number | string
|
|
// 徽标显示值
|
|
badge?: number | string | null
|
|
// 徽标属性,透传给 Badge 组件
|
|
badgeProps?: BadgeProps
|
|
// 图标
|
|
icon?: string
|
|
// 是否点状徽标
|
|
isDot?: boolean
|
|
// 徽标最大值
|
|
max?: number
|
|
// 是否禁用
|
|
disabled?: boolean
|
|
// 自定义样式
|
|
customStyle?: string
|
|
// 自定义样式类
|
|
customClass?: string
|
|
}
|
|
const props = withDefaults(defineProps<Props>(), {
|
|
disabled: false,
|
|
max: 99,
|
|
customStyle: '',
|
|
customClass: ''
|
|
})
|
|
|
|
const { parent: sidebar } = useParent(SIDEBAR_KEY)
|
|
|
|
const active = computed(() => {
|
|
let active: boolean = false
|
|
if (sidebar && sidebar.props.modelValue === props.value) {
|
|
active = true
|
|
}
|
|
return active
|
|
})
|
|
|
|
const prefix = computed(() => {
|
|
let prefix: boolean = false
|
|
if (sidebar) {
|
|
let activeIndex: number = sidebar.children.findIndex((c: any) => {
|
|
return c.value === sidebar.props.modelValue
|
|
})
|
|
|
|
let currentIndex: number = sidebar.children.findIndex((c: any) => {
|
|
return c.value === props.value
|
|
})
|
|
|
|
if (currentIndex === activeIndex - 1) {
|
|
prefix = true
|
|
}
|
|
}
|
|
return prefix
|
|
})
|
|
|
|
const suffix = computed(() => {
|
|
let suffix: boolean = false
|
|
if (sidebar) {
|
|
let activeIndex: number = sidebar.children.findIndex((c: any) => {
|
|
return c.value === sidebar.props.modelValue
|
|
})
|
|
|
|
let currentIndex: number = sidebar.children.findIndex((c: any) => {
|
|
return c.value === props.value
|
|
})
|
|
|
|
if (currentIndex === activeIndex + 1) {
|
|
suffix = true
|
|
}
|
|
}
|
|
return suffix
|
|
})
|
|
|
|
function handleClick() {
|
|
if (props.disabled) {
|
|
return
|
|
}
|
|
sidebar && sidebar.setChange(props.value, props.label)
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
@import './index.scss';
|
|
</style>
|