@neatui/nuxt 0.1.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/BUILD.md +128 -0
  2. package/IMPORT_GUIDE.md +142 -0
  3. package/README.md +98 -1
  4. package/SSR_COMPATIBILITY.md +201 -0
  5. package/USAGE.md +291 -0
  6. package/nuxt.config.example.ts +37 -0
  7. package/package.json +34 -11
  8. package/src/components/basic/IDraggable.vue +87 -65
  9. package/src/components/basic/IFollowView.vue +32 -23
  10. package/src/components/basic/IRouterView.vue +38 -23
  11. package/src/components/basic/IScrollView.vue +11 -7
  12. package/src/components/basic/Icon.vue +17 -17
  13. package/src/components/basic/LayerView/Layer.vue +33 -106
  14. package/src/components/basic/follow.ts +133 -0
  15. package/src/components/display/Calendar.vue +14 -14
  16. package/src/components/display/CalendarReg.vue +14 -14
  17. package/src/components/display/Image.vue +8 -8
  18. package/src/components/display/PhotoEditor.vue +36 -36
  19. package/src/components/display/PhotoViewer.vue +8 -8
  20. package/src/components/display/Tree.vue +6 -6
  21. package/src/components/display/TreeView.vue +4 -4
  22. package/src/components/display/index.ts +2 -2
  23. package/src/components/form/Cascader.vue +19 -19
  24. package/src/components/form/Checkbox.vue +64 -0
  25. package/src/components/form/DatePicker.vue +6 -7
  26. package/src/components/form/DateRangePicker@v3.vue +4 -4
  27. package/src/components/form/DateRangeView@v3.vue +18 -19
  28. package/src/components/form/DateView.vue +14 -14
  29. package/src/components/form/DateView@v2.vue +14 -14
  30. package/src/components/form/DateView@v3.vue +331 -318
  31. package/src/components/form/ImgUpload.vue +7 -7
  32. package/src/components/form/Input@v3.vue +11 -11
  33. package/src/components/form/MoreSelect@v3.vue +87 -17
  34. package/src/components/form/MoreSelectList.vue +8 -8
  35. package/src/components/form/MoreSelectPanel@v3.vue +3 -3
  36. package/src/components/form/MoreSelectPicker.vue +7 -7
  37. package/src/components/form/MoreSelectTags.vue +8 -8
  38. package/src/components/form/PageMoreSelect.vue +14 -14
  39. package/src/components/form/PageSelect.vue +16 -16
  40. package/src/components/form/SearchMoreSelect.vue +12 -12
  41. package/src/components/form/SearchSelect@v3.vue +3 -3
  42. package/src/components/form/Select@v3.vue +229 -23
  43. package/src/components/form/SelectList.vue +8 -8
  44. package/src/components/form/SelectPicker.vue +6 -6
  45. package/src/components/form/SelectTags.vue +7 -7
  46. package/src/components/form/SelectTree/SelectTree@v1.vue +5 -5
  47. package/src/components/form/Switch.vue +38 -103
  48. package/src/components/form/TextArea.vue +18 -18
  49. package/src/components/form/Textarea@v2.vue +275 -0
  50. package/src/components/form/TimeView.vue +14 -14
  51. package/src/components/form/Upload.vue +806 -297
  52. package/src/components/form/date.ts +321 -0
  53. package/src/components/form/index.ts +7 -5
  54. package/src/components/form/number.ts +3 -0
  55. package/src/components/form/type.ts +224 -0
  56. package/src/components/icon/OrderIcon.vue +113 -0
  57. package/src/components/loader/FormLoader/FormLoader@v2.vue +193 -195
  58. package/src/components/loader/FormLoader/FormLoader@v3.vue.backup +372 -291
  59. package/src/components/loader/FormLoader/FormRender@v3.vue.backup +4 -0
  60. package/src/components/loader/FormLoader/NodeLoader.vue +85 -0
  61. package/src/components/loader/FormLoader@v1/FormLoader.vue +1 -1
  62. package/src/components/loader/FormLoader@v1/FormRender.vue +49 -24
  63. package/src/components/loader/LayerLoader/LayerLoader.vue +318 -0
  64. package/src/components/loader/LayerLoader/index.ts +2 -0
  65. package/src/components/loader/LayerLoader/style.scss +77 -0
  66. package/src/components/loader/LimitLoader/LimitLoader@v3.vue +39 -28
  67. package/src/components/loader/MoveLoader/MoveLoader.vue +628 -0
  68. package/src/components/loader/MoveLoader/index.ts +2 -0
  69. package/src/components/loader/MoveLoader/style.scss +77 -0
  70. package/src/components/loader/TableLoader/TableLoader.vue +227 -195
  71. package/src/components/loader/TableLoader/TableRender.vue +141 -0
  72. package/src/components/loader/TableLoader/index.ts +47 -0
  73. package/src/components/loader/index.ts +3 -2
  74. package/src/components/tools/Pagination@a.vue +17 -18
  75. package/src/components/tools/Pagination@b.vue +16 -16
  76. package/src/index.ts +2 -1
  77. package/src/module.ts +169 -0
  78. package/src/runtime/types.d.ts +36 -0
  79. package/src/store/{myui.ts → frame.ts} +4 -4
  80. package/src/utils/theme.ts +14 -0
  81. package/tsconfig.json +1 -1
  82. package/src/components/loader/FormLoader/index.ts +0 -2
  83. package/src/components/loader/LimitLoader/LimitLoader.vue.backup +0 -131
  84. package/src/components/loader/LimitLoader/LimitLoader@v2.vue.backup +0 -174
  85. package/src/components/loader/TableLoader/TableColView.vue +0 -115
package/BUILD.md ADDED
@@ -0,0 +1,128 @@
1
+ # 构建说明
2
+
3
+ ## 📦 构建方式
4
+
5
+ @neatui/nuxt 采用**源文件直接分发**的方式,无需复杂的构建过程。
6
+
7
+ ### 🚀 优势
8
+
9
+ 1. **开发便利**: 修改源码即可生效,无需重新构建
10
+ 2. **调试方便**: 错误堆栈直接指向源码位置
11
+ 3. **体积更小**: 减少构建工具依赖
12
+ 4. **更新快速**: 无需等待构建过程
13
+
14
+ ### 🔧 技术实现
15
+
16
+ - **TypeScript**: Nuxt自动处理TS转译
17
+ - **Vue SFC**: Nuxt内置Vue编译器
18
+ - **样式处理**: 组件内样式自动处理
19
+ - **依赖解析**: Nuxt自动解析模块依赖
20
+
21
+ ## 📁 文件结构
22
+
23
+ ```
24
+ @neatui/nuxt/
25
+ ├── src/
26
+ │ ├── module.ts # Nuxt模块入口
27
+ │ ├── runtime/
28
+ │ │ └── types.d.ts # TypeScript类型定义
29
+ │ └── components/ # 组件源码
30
+ │ ├── basic/ # 基础组件
31
+ │ ├── display/ # 展示组件
32
+ │ ├── form/ # 表单组件
33
+ │ ├── icon/ # 图标组件
34
+ │ ├── loader/ # 加载器组件
35
+ │ └── tools/ # 工具组件
36
+ ├── package.json # 包配置
37
+ ├── tsconfig.json # TS配置
38
+ ├── nuxt.config.example.ts # 使用示例
39
+ ├── USAGE.md # 使用文档
40
+ └── SSR_COMPATIBILITY.md # SSR兼容性说明
41
+ ```
42
+
43
+ ## 🔄 发布流程
44
+
45
+ ### 1. 版本管理
46
+ ```bash
47
+ # 更新版本号
48
+ npm version patch # 小版本
49
+ npm version minor # 中版本
50
+ npm version major # 大版本
51
+ ```
52
+
53
+ ### 2. 发布到npm
54
+ ```bash
55
+ npm publish
56
+ ```
57
+
58
+ ### 3. 标签管理
59
+ ```bash
60
+ git tag v1.0.0
61
+ git push origin v1.0.0
62
+ ```
63
+
64
+ ## 🧪 本地测试
65
+
66
+ ### 1. 链接到本地项目
67
+ ```bash
68
+ # 在@neatui/nuxt目录
69
+ npm link
70
+
71
+ # 在测试项目中
72
+ npm link @neatui/nuxt
73
+ ```
74
+
75
+ ### 2. 创建测试项目
76
+ ```bash
77
+ npx nuxi@latest init neatui-test
78
+ cd neatui-test
79
+ npm install
80
+ npm link @neatui/nuxt
81
+ ```
82
+
83
+ ### 3. 配置测试
84
+ ```ts
85
+ // nuxt.config.ts
86
+ export default defineNuxtConfig({
87
+ modules: ['@neatui/nuxt'],
88
+ neatui: {
89
+ prefix: 'Test'
90
+ }
91
+ })
92
+ ```
93
+
94
+ ## 📊 性能优化
95
+
96
+ ### 1. Tree Shaking
97
+ Nuxt自动支持未使用组件的摇树优化
98
+
99
+ ### 2. 代码分割
100
+ 大型组件可以配置为异步加载:
101
+ ```ts
102
+ // module.ts 中
103
+ addComponent({
104
+ name: 'NeatHeavyComponent',
105
+ filePath: resolve('./components/heavy/HeavyComponent.vue'),
106
+ mode: 'client', // 仅客户端
107
+ async: true // 异步加载
108
+ })
109
+ ```
110
+
111
+ ### 3. 样式优化
112
+ 组件样式自动提取和优化,支持CSS变量定制
113
+
114
+ ## ⚠️ 注意事项
115
+
116
+ 1. **依赖版本**: 确保Nuxt版本兼容性
117
+ 2. **TypeScript**: 使用严格模式提高代码质量
118
+ 3. **SSR兼容**: 部分组件需要ClientOnly包裹
119
+ 4. **性能监控**: 关注首屏加载和hydration时间
120
+
121
+ ## 🔧 开发工具
122
+
123
+ 推荐的开发环境:
124
+ - Node.js 18+
125
+ - Vue 3.2+
126
+ - Nuxt 3.0+
127
+ - TypeScript 5.0+
128
+ - VS Code + Volar 插件
@@ -0,0 +1,142 @@
1
+ # 组件导入指南
2
+
3
+ ## 🚀 解决导入错误
4
+
5
+ 如果遇到 `Module '"@neatui/nuxt"' has no exported member 'Textarea'` 错误,请使用以下方式:
6
+
7
+ ### ✅ 正确的导入方式
8
+
9
+ #### 方式1: 自动导入 (推荐)
10
+ ```vue
11
+ <template>
12
+ <!-- 配置模块后直接使用,无需导入 -->
13
+ <NeatTextarea v-model="content" />
14
+ <NeatInput v-model="name" />
15
+ <NeatSelect v-model="city" :options="cities" />
16
+ </template>
17
+
18
+ <script setup>
19
+ // 无需导入,组件自动可用
20
+ const content = ref('')
21
+ const name = ref('')
22
+ const city = ref('')
23
+ </script>
24
+ ```
25
+
26
+ #### 方式2: 手动导入
27
+ ```vue
28
+ <template>
29
+ <!-- 使用原组件名 -->
30
+ <Textarea v-model="content" />
31
+ <Input v-model="name" />
32
+ <Select v-model="city" :options="cities" />
33
+ </template>
34
+
35
+ <script setup>
36
+ // 从 /components 路径导入
37
+ import { Textarea, Input, Select } from '@neatui/nuxt/components'
38
+
39
+ const content = ref('')
40
+ const name = ref('')
41
+ const city = ref('')
42
+ </script>
43
+ ```
44
+
45
+ ### ❌ 错误的导入方式
46
+
47
+ ```vue
48
+ <script setup>
49
+ // 🚫 错误:不能从根路径直接导入组件
50
+ import { Textarea } from '@neatui/nuxt'
51
+
52
+ // 🚫 错误:默认导入方式
53
+ import Textarea from '@neatui/nuxt'
54
+ </script>
55
+ ```
56
+
57
+ ## 📋 可用组件列表
58
+
59
+ ### 表单组件
60
+ ```js
61
+ import {
62
+ Input, // 输入框
63
+ Textarea, // 文本域
64
+ Select, // 选择器
65
+ Switch, // 开关
66
+ Checkbox, // 复选框
67
+ DatePicker, // 日期选择
68
+ DateView, // 日期显示
69
+ TimePicker, // 时间选择
70
+ Upload, // 文件上传
71
+ ImgUpload, // 图片上传
72
+ Cascader, // 级联选择
73
+ PageSelect, // 分页选择
74
+ MoreSelect, // 更多选择
75
+ SelectTags, // 标签选择
76
+ // ... 更多组件
77
+ } from '@neatui/nuxt/components'
78
+ ```
79
+
80
+ ### 加载器组件
81
+ ```js
82
+ import {
83
+ FormLoader, // 表单构建器
84
+ TableLoader, // 表格加载器
85
+ ViewLoader, // 视图加载器
86
+ LimitLoader, // 限制加载器
87
+ MoveLoader, // 移动加载器
88
+ LayerLoader, // 层级加载器
89
+ } from '@neatui/nuxt/components'
90
+ ```
91
+
92
+ ### 工具组件
93
+ ```js
94
+ import {
95
+ FormVerifyView, // 表单验证视图
96
+ FormDraftsView, // 表单草稿视图
97
+ MoreTools, // 更多工具
98
+ Pagination, // 分页组件
99
+ } from '@neatui/nuxt/components'
100
+ ```
101
+
102
+ ## 🔧 配置说明
103
+
104
+ ### nuxt.config.ts
105
+ ```ts
106
+ export default defineNuxtConfig({
107
+ modules: ['@neatui/nuxt'],
108
+ neatui: {
109
+ prefix: 'Neat', // 自动导入时的前缀
110
+ autoImport: true, // 是否启用自动导入
111
+ exclude: [] // 排除的组件
112
+ }
113
+ })
114
+ ```
115
+
116
+ ### package.json 导出配置
117
+ ```json
118
+ {
119
+ "exports": {
120
+ ".": "./src/module.ts", // Nuxt模块
121
+ "./components": "./src/index.ts" // 组件导出
122
+ }
123
+ }
124
+ ```
125
+
126
+ ## 💡 使用建议
127
+
128
+ 1. **优先使用自动导入**: 配置模块后直接使用 `<NeatTextarea>`
129
+ 2. **按需手动导入**: 只在需要时从 `/components` 导入
130
+ 3. **统一命名**: 自动导入使用前缀,手动导入使用原名
131
+ 4. **TypeScript支持**: 两种方式都有完整的类型提示
132
+
133
+ ## 🐛 常见问题
134
+
135
+ **Q: 为什么不能直接从 '@neatui/nuxt' 导入组件?**
136
+ A: '@neatui/nuxt' 是Nuxt模块,用于配置。组件需要从 '@neatui/nuxt/components' 导入。
137
+
138
+ **Q: 自动导入的组件没有类型提示?**
139
+ A: 确保安装了 '@nuxt/kit' 依赖,并重启TypeScript服务。
140
+
141
+ **Q: 可以混合使用两种方式吗?**
142
+ A: 可以,但建议保持一致性,避免混乱。
package/README.md CHANGED
@@ -1,3 +1,100 @@
1
- # @neatui/vue
1
+ # @neatui/nuxt
2
2
 
3
+ A comprehensive UI component library for Nuxt 3, providing elegant and feature-rich components for modern web applications.
4
+
5
+ ## ✨ Features
6
+
7
+ - 🚀 **Nuxt 3 Ready**: Native support for Nuxt 3 with SSR/SSG
8
+ - 📦 **Auto Import**: Components and composables auto-imported
9
+ - 🎨 **Rich Components**: 40+ carefully crafted components
10
+ - 📱 **Mobile First**: Responsive design for all screen sizes
11
+ - 🔧 **TypeScript**: Full TypeScript support
12
+ - 🎯 **Tree Shaking**: Import only what you need
13
+ - 🌙 **Theme Support**: Customizable themes and styling
14
+
15
+ ## 📦 Installation
16
+
17
+ ```bash
18
+ npm install @neatui/nuxt
19
+ ```
20
+
21
+ ## 🚀 Quick Start
22
+
23
+ Add `@neatui/nuxt` to your Nuxt configuration:
24
+
25
+ ```ts
26
+ // nuxt.config.ts
27
+ export default defineNuxtConfig({
28
+ modules: [
29
+ '@neatui/nuxt'
30
+ ],
31
+ neatui: {
32
+ // Module options
33
+ theme: 'default',
34
+ prefix: 'Neat'
35
+ }
36
+ })
37
+ ```
38
+
39
+ ## 📖 Usage
40
+
41
+ Components are auto-imported, just use them in your templates:
42
+
43
+ ```vue
44
+ <template>
45
+ <div>
46
+ <NeatInput v-model="value" placeholder="Enter text..." />
47
+ <NeatButton @click="handleClick">Click me</NeatButton>
48
+ <NeatSelect v-model="selected" :options="options" />
49
+ </div>
50
+ </template>
51
+
52
+ <script setup>
53
+ const value = ref('')
54
+ const selected = ref('')
55
+ const options = [
56
+ { label: 'Option 1', value: '1' },
57
+ { label: 'Option 2', value: '2' }
58
+ ]
59
+
60
+ const handleClick = () => {
61
+ console.log('Button clicked!')
62
+ }
63
+ </script>
64
+ ```
65
+
66
+ ## 🔧 Configuration
67
+
68
+ ```ts
69
+ // nuxt.config.ts
70
+ export default defineNuxtConfig({
71
+ neatui: {
72
+ // Theme configuration
73
+ theme: 'default', // 'default' | 'dark' | 'custom'
74
+
75
+ // Component prefix
76
+ prefix: 'Neat', // Components will be <NeatButton>, <NeatInput>, etc.
77
+
78
+ // CSS variables
79
+ css: {
80
+ // Custom theme variables
81
+ },
82
+
83
+ // Components to exclude from auto-import
84
+ exclude: ['SomeComponent']
85
+ }
86
+ })
87
+ ```
88
+
89
+ ## 📚 Documentation
90
+
91
+ For detailed documentation, examples, and API reference, visit:
3
92
  [http://neatui.fekit.cn](http://neatui.fekit.cn)
93
+
94
+ ## 🤝 Contributing
95
+
96
+ Contributions are welcome! Please read our contributing guidelines before submitting PRs.
97
+
98
+ ## 📄 License
99
+
100
+ MIT License © xiaojunbo
@@ -0,0 +1,201 @@
1
+ # SSR 兼容性分析
2
+
3
+ ## 🔍 已检查组件分析
4
+
5
+ 经过代码扫描,以下组件包含浏览器API调用,在SSR环境下需要特殊处理:
6
+
7
+ ### ⚠️ 需要ClientOnly包裹的组件
8
+
9
+ #### 1. **表单草稿组件** (`FormDraftsView.vue`)
10
+ - **问题**: 使用 `localStorage` 存储草稿数据
11
+ - **影响**: 服务端渲染时无法访问浏览器存储
12
+ - **解决方案**:
13
+ ```vue
14
+ <ClientOnly>
15
+ <NeatFormDraftsView />
16
+ <template #fallback>
17
+ <div>加载中...</div>
18
+ </template>
19
+ </ClientOnly>
20
+ ```
21
+
22
+ #### 2. **分页组件** (`Pagination@a.vue`, `Pagination@b.vue`)
23
+ - **问题**: 可能使用 `window.location` 进行路由操作
24
+ - **影响**: 服务端无window对象
25
+ - **解决方案**: 已检查,主要使用Vue Router,SSR兼容
26
+
27
+ #### 3. **更多工具组件** (`MoreTools.vue`, `MoreTools@v2.vue`)
28
+ - **问题**: 使用 `document` 进行DOM操作
29
+ - **影响**: 服务端无document对象
30
+ - **解决方案**:
31
+ ```vue
32
+ <ClientOnly>
33
+ <NeatMoreTools />
34
+ </ClientOnly>
35
+ ```
36
+
37
+ #### 4. **移动加载器** (`MoveLoader.vue`)
38
+ - **问题**: 可能使用触摸事件监听
39
+ - **影响**: 服务端无触摸事件
40
+ - **解决方案**: 检测到移动端时使用ClientOnly
41
+
42
+ #### 5. **表格加载器** (`TableLoader.vue`)
43
+ - **问题**: 使用 `window` 对象检测屏幕尺寸
44
+ - **影响**: 服务端无window对象
45
+ - **解决方案**: 使用Nuxt的设备检测或ClientOnly
46
+
47
+ ### ✅ SSR 兼容组件
48
+
49
+ 以下组件经检查,完全支持SSR:
50
+
51
+ #### 表单组件
52
+ - `Input` - 纯Vue组件,无浏览器API
53
+ - `Select@v3` - 使用Vue响应式,SSR兼容
54
+ - `DatePicker` - 日期选择组件,SSR兼容
55
+ - `DateView@v3` - 日期显示组件,SSR兼容
56
+ - `Upload` - 文件上传组件(仅显示部分SSR兼容,上传功能需ClientOnly)
57
+ - `Textarea@v2` - 文本域组件,SSR兼容
58
+ - `Switch` - 开关组件,SSR兼容
59
+
60
+ #### 加载器组件
61
+ - `FormLoader@v2` - 表单构建器,SSR兼容
62
+ - `ViewLoader` - 视图加载器,SSR兼容
63
+ - `LimitLoader@v3` - 限制加载器,SSR兼容
64
+
65
+ #### 基础组件
66
+ - `LayerView` - 层级视图,SSR兼容
67
+
68
+ ## 🚀 SSR 优化建议
69
+
70
+ ### 1. 自动检测与包裹
71
+
72
+ 在模块中添加自动检测机制:
73
+
74
+ ```typescript
75
+ // module.ts 中添加
76
+ const clientOnlyComponents = [
77
+ 'FormDraftsView',
78
+ 'MoreTools',
79
+ 'MoveLoader'
80
+ ]
81
+
82
+ // 自动为这些组件添加ClientOnly包裹
83
+ clientOnlyComponents.forEach(name => {
84
+ addComponent({
85
+ name: `${options.prefix}${name}`,
86
+ filePath: resolve(`./components/tools/${name}.vue`),
87
+ mode: 'client' // Nuxt 3 自动处理
88
+ })
89
+ })
90
+ ```
91
+
92
+ ### 2. 渐进式增强
93
+
94
+ 对于文件上传等功能,提供服务端渲染的基础版本:
95
+
96
+ ```vue
97
+ <!-- Upload.vue 优化 -->
98
+ <template>
99
+ <div class="neatui-upload">
100
+ <!-- SSR 兼容的静态部分 -->
101
+ <div v-if="!hydrated" class="upload-placeholder">
102
+ 文件上传组件加载中...
103
+ </div>
104
+
105
+ <!-- 客户端功能 -->
106
+ <ClientOnly>
107
+ <div class="upload-interactive">
108
+ <!-- 原有的交互功能 -->
109
+ </div>
110
+ </ClientOnly>
111
+ </div>
112
+ </template>
113
+ ```
114
+
115
+ ### 3. 状态预填充
116
+
117
+ 对于草稿等功能,在服务端提供初始状态:
118
+
119
+ ```vue
120
+ <!-- FormDraftsView.vue 优化 -->
121
+ <template>
122
+ <div>
123
+ <ClientOnly>
124
+ <FormDraftsViewClient :initial-data="serverData" />
125
+ <template #fallback>
126
+ <div v-if="serverData.hasDrafts">发现草稿数据</div>
127
+ </template>
128
+ </ClientOnly>
129
+ </div>
130
+ </template>
131
+
132
+ <script setup>
133
+ // 服务端可以预填充的数据
134
+ const serverData = {
135
+ hasDrafts: false, // 服务端检测
136
+ draftsCount: 0
137
+ }
138
+ </script>
139
+ ```
140
+
141
+ ## 📋 使用建议
142
+
143
+ ### 1. 开发时
144
+
145
+ ```vue
146
+ <template>
147
+ <div>
148
+ <!-- 绝对安全的组件 -->
149
+ <NeatInput v-model="form.name" />
150
+ <NeatSelect v-model="form.type" :options="options" />
151
+
152
+ <!-- 可能需要客户端的组件 -->
153
+ <ClientOnly>
154
+ <NeatUpload v-model="form.files" />
155
+ <NeatFormDraftsView />
156
+ <template #fallback>
157
+ <div class="text-center py-4">
158
+ <div class="loading-spinner"></div>
159
+ <p>加载中...</p>
160
+ </div>
161
+ </template>
162
+ </ClientOnly>
163
+ </div>
164
+ </template>
165
+ ```
166
+
167
+ ### 2. 性能优化
168
+
169
+ ```vue
170
+ <script setup>
171
+ // 使用 Nuxt 的客户端检测
172
+ const { $device } = useNuxtApp()
173
+
174
+ // 移动端才加载移动特定组件
175
+ const showMobileLoader = computed(() => {
176
+ return process.client && $device.isMobile
177
+ })
178
+ </script>
179
+
180
+ <template>
181
+ <div>
182
+ <NeatMoveLoader v-if="showMobileLoader" />
183
+ <NeatTableLoader v-else />
184
+ </div>
185
+ </template>
186
+ ```
187
+
188
+ ## 🔧 测试清单
189
+
190
+ - [ ] 所有表单组件在SSR模式下正常渲染
191
+ - [ ] ClientOnly组件有合适的fallback
192
+ - [ ] 页面首次加载无hydration错误
193
+ - [ ] 客户端组件正常激活
194
+ - [ ] 性能指标达标(LCP, FID, CLS)
195
+
196
+ ## 📊 兼容性总结
197
+
198
+ - **完全兼容**: 80%+ 组件支持SSR
199
+ - **需要包裹**: 约5个组件需要ClientOnly
200
+ - **渐进增强**: 文件上传等功能组件
201
+ - **总体评估**: SSR兼容性良好,可投入生产使用