b6fb767928
- 新建 stores/screen.ts(id用 crypto.randomUUID 唯一生成、addScreen/removeScreen/renameScreen actions) - 新建 screen-panel.vue 替换 canvas-area.vue(NTab + NTabs type=card + addable/closable) - 添加屏幕增删的二次确认弹窗(window.$dialog.warning/info) - 双击Tab弹出重命名输入框(沿用删除dialog的交互风格) - 调整 onClose 入参命名为 id,语义与 store 一致 - 包裹 Tab 区域加 user-select: none,防止双击/拖动时文字被选中 - 附带:config-panel.vue 同步 Prettier 格式化(无逻辑改动)
59 lines
1.5 KiB
TypeScript
59 lines
1.5 KiB
TypeScript
import { defineStore } from 'pinia'
|
|
import { ref } from 'vue'
|
|
|
|
export interface Screen {
|
|
id: string
|
|
name: string
|
|
}
|
|
|
|
let counter = 4
|
|
|
|
const genId = (): string => `screen-${crypto.randomUUID()}`
|
|
|
|
const defaultName = (n: number): string => `屏幕 ${n}`
|
|
|
|
export const useScreenStore = defineStore('vimp-screen', () => {
|
|
const screens = ref<Screen[]>([
|
|
{ id: 'screen-1', name: '屏幕 1' },
|
|
{ id: 'screen-2', name: '屏幕 2' },
|
|
{ id: 'screen-3', name: '屏幕 3' },
|
|
{ id: 'screen-4', name: '屏幕 4' },
|
|
])
|
|
|
|
const activeScreenId = ref<string>(screens.value[0]?.id ?? '')
|
|
|
|
const addScreen = () => {
|
|
const id = genId()
|
|
screens.value.push({ id, name: defaultName(screens.value.length + 1) })
|
|
activeScreenId.value = id
|
|
}
|
|
|
|
const removeScreen = (id: string) => {
|
|
if (screens.value.length <= 1) return
|
|
const index = screens.value.findIndex(s => s.id === id)
|
|
if (index === -1) return
|
|
screens.value.splice(index, 1)
|
|
if (activeScreenId.value === id) {
|
|
const fallback = screens.value[index] ?? screens.value[index - 1]
|
|
if (fallback) activeScreenId.value = fallback.id
|
|
}
|
|
}
|
|
|
|
const renameScreen = (id: string, name: string) => {
|
|
const target = screens.value.find(s => s.id === id)
|
|
if (!target) return
|
|
const trimmed = name.trim()
|
|
if (trimmed.length === 0) return
|
|
if (trimmed === target.name) return
|
|
target.name = trimmed
|
|
}
|
|
|
|
return {
|
|
screens,
|
|
activeScreenId,
|
|
addScreen,
|
|
removeScreen,
|
|
renameScreen,
|
|
}
|
|
})
|