跳转正文

Settings Composition ​

适用范围:Legacy Admin Kit / Schema 与旧 admin-vue。新 admin-nuxtui 的开发入口见管理端 Nuxt UI 指南。

Settings Composition 用现有 Page Frame、Tabs 与表单布局组件组织设置任务。它不是新的 YSettingsSurface,也不拥有字段草稿、权限或保存请求。

文档内可运行示例 ​

可运行示例

分类与保存边界

修改名称后切换分类,输入仍保留。清空名称并保存会显示字段关联错误;独立导出不保存设置。

查看同源 Vue 代码
<script setup lang="ts">
import { reactive, ref } from 'vue'
import { YButton, YInput, YSettingRow, YSwitch, YTabs } from '@yoyoboot/yoyo-admin-kit'

const category = ref('general')
const draft = reactive({ name: '开发团队', notifications: true })
const error = ref('')
const result = ref('尚未保存;所有操作仅在浏览器内存中运行。')
const exportCount = ref(0)
const categories = [{ id: 'general', label: '基本设置' }, { id: 'notifications', label: '通知设置' }]

function save() {
  error.value = draft.name.trim() ? '' : '请填写团队名称。'
  if (error.value) {
    category.value = 'general'
    return
  }
  result.value = `整体保存:${draft.name};通知${draft.notifications ? '开启' : '关闭'}。未发送网络请求。`
}
</script>

<template>
  <form @submit.prevent="save">
    <YTabs v-model="category" :items="categories">
      <template #general>
        <YSettingRow label="团队名称" description="切换分类保留未保存输入。" :error="error">
          <template #default="{ labelId, describedBy, invalid }">
            <YInput v-model="draft.name" :aria-labelledby="labelId" :aria-describedby="describedBy" :aria-invalid="invalid" />
          </template>
        </YSettingRow>
      </template>
      <template #notifications>
        <YSettingRow label="接收通知" description="与团队名称一起整体保存。">
          <template #default="{ labelId, describedBy }">
            <YSwitch v-model="draft.notifications" :aria-labelledby="labelId" :aria-describedby="describedBy" />
          </template>
        </YSettingRow>
      </template>
    </YTabs>
    <YButton type="submit">保存全部设置</YButton>
    <p role="status">{{ result }}</p>
  </form>
  <section aria-label="独立操作">
    <p>导出是独立操作,不提交或清除上面的设置草稿。</p>
    <YButton type="button" variant="outline" @click="exportCount += 1">演示独立导出</YButton>
    <p>独立导出次数:{{ exportCount }}(不生成真实文件)</p>
  </section>
</template>

本例只消费公开组件,演示内存中的设置草稿,不请求 Profile/System Settings API,也不代表当前源码版本已经发布到 npm。

组合方式 ​

text
YPageContainer + YPageHeader
└─ YTabs(分类入口)
   └─ YFormSection
      ├─ YFormGrid
      └─ YSettingRow(说明 / 控件 / 就近错误)
  • 分类只改变当前可见分区,页面 feature 继续持有同一份草稿;切换分类不会重新加载或丢弃未保存值。
  • YSettingRow 通过 scoped slot 提供 label、description、error 的 ARIA 关联;文本控件使用合理最大宽度,窄屏自动堆叠。
  • 页面草稿通过宿主现有 dirty registry 接入统一离开确认,不建立第二草稿或确认 owner。
  • 主题、语言等 Shell 偏好继续归 Preference Drawer,不复制到个人设置。

保存边界 ​

个人设置 ​

apps/yoyo-admin/admin-vue/src/app/account/profile/index.vue 的三个任务保持独立:

  • 个人资料只调用 UpdateCurrentUserProfile;邮箱只读,提交使用服务端加载值。
  • 修改密码只调用 ChangePassword,成功后清空密码输入。
  • 个人数据导出只启动既有异步导出任务。

任一操作失败只在对应分区显示错误并保留输入,不以一个按钮合并这些业务动作。

系统设置 ​

apps/yoyo-admin/admin-vue/src/app/administration/configuration/settings.vue 根据当前身份选择 Host 或 Tenant 权限与 DTO。分类只是呈现方式,页面始终通过既有 UpdateAllSettings 一次保存完整设置模型;不能因为出现多个分区而伪造局部保存能力。

无编辑权限时控件与保存入口禁用。保存失败保留完整草稿;成功后重新加载权威设置并重建 dirty 基线。

响应式与错误 ​

  • 桌面使用说明列和受约束的控件列;安全选项可使用两列网格。
  • 窄屏由 YSettingRow/YFormGrid 回落为单列,操作保持可到达且不横向溢出。
  • 加载、权限、操作错误和成功反馈仍由页面 feature 呈现;通用组件不解析业务错误。

不做 ​

开发者接入继续阅读 Authoring 与 External Consumption;本地演示不证明 npm 已发布,版本状态见版本兼容说明。

  • 不建立万能 Settings schema/runtime。
  • 不把 Host/Tenant DTO、权限或 API 请求迁入 Admin Kit。
  • 不把资料、密码、导出或 Shell 偏好合并为单一保存事务。

YoyoBoot · 从真实项目走向可复用能力