@daflow-ui/block-album-list
v0.1.2
Published
Album list component for DaFlow UI
Readme
@daflow-ui/block-album-list
Album list component for DaFlow UI component library.
Installation
pnpm add @daflow-ui/block-album-listUsage
全局引入样式(在 main.ts 中):
import '@daflow-ui/block-album-list/style.css';在组件中使用:
<script setup lang="ts">
import { DfAlbumList, CONTROL_ACTIONS } from '@daflow-ui/block-album-list';
import type { AlbumListItem, AlbumListPagination, AlbumListActionDef } from '@daflow-ui/block-album-list';
</script>
<template>
<DfAlbumList
:items="items"
:pagination="{ currentPage: 1, pageSize: 10, total: 100 }"
/>
</template>API
Props
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| items | AlbumListItem[] | [] | 列表数据 |
| pagination | AlbumListPagination | { currentPage: 1, pageSize: 10, total: 0 } | 分页参数 |
| loading | boolean | false | 加载状态 |
| variant | 'detailed' \| 'compact' \| 'control' | 'detailed' | 展示变体 |
| controlActions | AlbumListActionDef[] | [] | control 变体追加的自定义操作 |
| defaultControlActionVisible | Partial<Record<DefaultControlActionKey, boolean>> | - | control 变体默认 4 个操作的显示状态 |
| controlActionDisabled | Partial<Record<AlbumListActionDef['key'], boolean>> \| (row: AlbumListItem) => Partial<Record<AlbumListActionDef['key'], boolean>> | - | control 变体各操作的禁用状态(平面对象或每行函数) |
| showSelection | boolean | false | 是否显示复选框(仅 control 变体) |
| selectedIds | string[] | - | 受控选中的专辑 ID 列表 |
Events
| 事件名 | 参数 | 说明 |
|--------|------|------|
| page-change | (page: number) => void | 分页变化 |
| album-detail-click | (id: string) => void | 专辑详情点击 |
| track-list-click | (id: string) => void | 歌曲列表点击 |
| release-status-click | (id: string) => void | 发行状态点击 |
| authorization-contract-click | (id: string) => void | 授权合同点击 |
| control-action-click | (key: AlbumListActionDef['key'], row: AlbumListItem) => void | control 变体操作点击 |
| batch-action | (actionKey: BatchActionKey, selectedIds: string[]) => void | 批量操作点击 |
| update:selectedIds | (ids: string[]) => void | 选中状态变化 |
Exports
export type DefaultControlActionKey = 'detail' | 'track-list' | 'release' | 'contract'
export type AlbumListBuiltInActionIcon = 'eye' | 'list' | 'clock' | 'file'
export type AlbumListActionIcon = AlbumListBuiltInActionIcon | Component
export type AlbumListActionIconResolver = (row: AlbumListItem) => AlbumListActionIcon
// 操作项定义
export interface AlbumListActionDef {
key: string
label: string | ((row: AlbumListItem) => string)
icon: AlbumListActionIcon
iconResolver?: AlbumListActionIconResolver
}
export interface DefaultControlActionDef extends AlbumListActionDef {
key: DefaultControlActionKey
icon: AlbumListBuiltInActionIcon
}
// control 变体支持的操作列表
export const CONTROL_ACTIONS: DefaultControlActionDef[]
// 批量操作定义
export interface BatchActionDef {
key: BatchActionKey
label: string
icon: string
}
export type BatchActionKey = 'publish' | 'take-down' | 'delete'
// 批量操作列表
export const BATCH_ACTIONS: BatchActionDef[]Variants
detailed (默认)
信息优先,需要浏览完整专辑信息。
┌─────────────────────────────────────────────────────────────────────────┐
│ 专辑信息 │ 附加信息 │ 授权状态 │ 发行状态 │ 操作 │
└─────────────────────────────────────────────────────────────────────────┘compact
单行高密度展示,适合快速浏览。
┌─────────────────────────────────────────────────────────────────────────┐
│ 封面 │ 专辑名 │ 艺人 │ UPC │ 歌曲数量 │ 操作 │
└─────────────────────────────────────────────────────────────────────────┘control
操作优先展示,仅保留专辑信息(封面 + 标题)和操作列,支持隐藏默认操作并追加自定义操作。
┌─────────────────────────────────────────────────────────────────────────┐
│ 专辑信息 │ 操作 │
│ [封面] 专辑名称 (2 行) │ [icon] [icon] [icon] [icon] │
└─────────────────────────────────────────────────────────────────────────┘Operation Permission Control
组件采用「哑组件」设计原则:
- 默认操作可配置显示/隐藏:通过
defaultControlActionVisible全局控制 4 个内置操作 - 支持追加自定义操作:通过
controlActions在默认操作后追加业务按钮 - 无权限时禁用:通过
disabled状态表示当前不可用 - 判断逻辑外置:组件只负责展示,权限判断由外部业务层处理
使用示例
<script setup lang="ts">
import { defineComponent, h } from 'vue'
import { DfAlbumList, CONTROL_ACTIONS } from '@daflow-ui/block-album-list'
import type { AlbumListActionDef, AlbumListItem } from '@daflow-ui/block-album-list'
const defaultControlActionVisible = {
detail: true,
'track-list': true,
release: false,
contract: true
}
const AnalyticsIcon = defineComponent({
name: 'AnalyticsIcon',
setup() {
return () => h(
'svg',
{ viewBox: '0 0 24 24', 'aria-hidden': 'true', focusable: 'false' },
[h('path', { fill: 'currentColor', d: 'M4 19h16v2H2V3h2v16Zm2-2V9h3v8H6Zm5 0V5h3v12h-3Zm5 0v-6h3v6h-3Z' })]
)
}
})
const customActions: AlbumListActionDef[] = [
{ key: 'analytics', label: '数据概览', icon: AnalyticsIcon }
]
// 方式一:平面对象(所有行共用状态)
const actionDisabled = {
detail: false,
'track-list': false,
release: true,
contract: true,
analytics: false
}
// 方式二:函数(每行独立状态)
const getActionDisabled = (row: AlbumListItem) => ({
detail: false,
'track-list': row.authorizationStatus?.label !== '已授权',
release: row.authorizationStatus?.label !== '已授权',
contract: false,
analytics: false
})
const handleActionClick = (key: AlbumListActionDef['key'], row: AlbumListItem) => {
console.log('action clicked:', key, row.id)
}
</script>
<template>
<!-- 方式一:平面对象 -->
<DfAlbumList
:items="items"
variant="control"
:default-control-action-visible="defaultControlActionVisible"
:control-actions="customActions"
:control-action-disabled="actionDisabled"
@control-action-click="handleActionClick"
/>
<!-- 方式二:每行函数 -->
<DfAlbumList
:items="items"
variant="control"
:default-control-action-visible="defaultControlActionVisible"
:control-actions="customActions"
:control-action-disabled="getActionDisabled"
@control-action-click="handleActionClick"
/>
</template>iconResolver 示例
当同一个操作需要根据当前行的 releaseStatuses 切换图标和文案时,建议保持 key 和点击事件不变,只通过 label 和 iconResolver 返回不同结果:
<script setup lang="ts">
import { defineComponent, h } from 'vue'
import { DfAlbumList } from '@daflow-ui/block-album-list'
import type { AlbumListActionDef, AlbumListItem } from '@daflow-ui/block-album-list'
const PublishIcon = defineComponent({
name: 'PublishIcon',
setup() {
return () => h(
'svg',
{ viewBox: '0 0 24 24', 'aria-hidden': 'true', focusable: 'false' },
[h('path', { fill: 'currentColor', d: 'M12 21a1 1 0 0 1-1-1v-8.59l-2.3 2.3a1 1 0 1 1-1.4-1.42l4-4a1 1 0 0 1 1.4 0l4 4a1 1 0 1 1-1.4 1.42L13 11.41V20a1 1 0 0 1-1 1Zm-8-15a1 1 0 0 1 1-1h14a1 1 0 1 1 0 2H5a1 1 0 0 1-1-1Z' })]
)
}
})
const TakeDownIcon = defineComponent({
name: 'TakeDownIcon',
setup() {
return () => h(
'svg',
{ viewBox: '0 0 24 24', 'aria-hidden': 'true', focusable: 'false' },
[h('path', { fill: 'currentColor', d: 'M12 3a1 1 0 0 1 1 1v8.59l2.3-2.3a1 1 0 1 1 1.4 1.42l-4 4a1 1 0 0 1-1.4 0l-4-4a1 1 0 1 1 1.4-1.42l2.3 2.3V4a1 1 0 0 1 1-1Zm-8 11a1 1 0 0 1 1 1v3h14v-3a1 1 0 1 1 2 0v3a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-3a1 1 0 0 1 1-1Z' })]
)
}
})
const hasReleaseStatus = (row: AlbumListItem, label: string) =>
row.releaseStatuses?.some((status) => status.label === label) ?? false
const controlActions: AlbumListActionDef[] = [
{
key: 'release-toggle',
label: (row) => hasReleaseStatus(row, '已上架') ? '下架专辑' : '上架专辑',
icon: PublishIcon,
iconResolver: (row) => hasReleaseStatus(row, '已上架') ? TakeDownIcon : PublishIcon
}
]
const handleControlActionClick = (key: AlbumListActionDef['key'], row: AlbumListItem) => {
if (key === 'release-toggle') {
// 基于 releaseStatuses 判断当前是执行上架还是下架
console.log('toggle publish status', row.id)
}
}
</script>
<template>
<DfAlbumList
:items="items"
variant="control"
:control-actions="controlActions"
@control-action-click="handleControlActionClick"
/>
</template>Batch Actions (多选批量操作)
当启用 showSelection 时,会显示复选框列和底部批量操作栏。
批量操作
| 操作 | key | 说明 |
|------|-----|------|
| 批量上架 | publish | 触发批量上架事件 |
| 批量下架 | take-down | 触发批量下架事件 |
| 删除 | delete | 触发删除事件 |
使用示例
<script setup lang="ts">
import { ref } from 'vue'
import { DfAlbumList } from '@daflow-ui/block-album-list'
import type { AlbumListItem, AlbumListPagination, BatchActionKey } from '@daflow-ui/block-album-list'
const selectedIds = ref<string[]>([])
// 外部判断哪些记录可以执行操作
const canExecuteAction = (id: string, actionKey: BatchActionKey) => {
// 根据业务逻辑判断
return true
}
const handleBatchAction = (actionKey: BatchActionKey, ids: string[]) => {
// 过滤出可以执行的记录
const validIds = ids.filter(id => canExecuteAction(id, actionKey))
switch (actionKey) {
case 'publish':
batchPublish(validIds)
break
case 'take-down':
batchRemove(validIds)
break
case 'delete':
batchDelete(ids) // 删除不需要判断状态
break
}
}
</script>
<template>
<DfAlbumList
v-model:selected-ids="selectedIds"
:show-selection="true"
@batch-action="handleBatchAction"
/>
</template>Development
Install dependencies
pnpm installStart playground (at monorepo root)
cd ../.. # 回到 monorepo 根目录
pnpm dev # 启动统一 playground,自动发现组件组件会自动出现在 playground 导航中(通过 dev/index.vue)。
Build
pnpm buildType check
pnpm typecheckLint
pnpm lint
pnpm lint:fixLicense
MIT
