@uxda/appkit 4.3.23 → 4.3.25
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.
- package/.cursor/rules/nutshell.mdc +2166 -0
- package/.cursor/rules/project.mdc +209 -0
- package/.cursor/skills/appkit-build-update-component-rules/SKILL.md +49 -0
- package/{COMPONENT_USAGE.md → Appkit/347/273/204/344/273/266/344/275/277/347/224/250/350/247/204/345/210/231.md} +212 -11
- package/README.md +8 -1
- package/dist/index.js +3 -31
- package/package.json +1 -1
- package/src/payment/components/RechargeView.vue +1 -3
- package/src/payment/components/TradeView.vue +2 -4
|
@@ -0,0 +1,2166 @@
|
|
|
1
|
+
---
|
|
2
|
+
alwaysApply: true
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Nutshell UI 组件库使用规则 - 移动端
|
|
6
|
+
|
|
7
|
+
> 基于 Vue 3 + NutUI + Taro 的移动端组件库
|
|
8
|
+
> 版本:1.6.92
|
|
9
|
+
> 支持:H5、微信小程序
|
|
10
|
+
|
|
11
|
+
## 📚 目录
|
|
12
|
+
|
|
13
|
+
- [快速开始](#快速开始)
|
|
14
|
+
- [平台支持](#平台支持)
|
|
15
|
+
- [基础组件](#基础组件)
|
|
16
|
+
- [表单组件](#表单组件)
|
|
17
|
+
- [数据展示组件](#数据展示组件)
|
|
18
|
+
- [反馈组件](#反馈组件)
|
|
19
|
+
- [布局组件](#布局组件)
|
|
20
|
+
- [导航组件](#导航组件)
|
|
21
|
+
- [通用属性](#通用属性)
|
|
22
|
+
- [服务方法](#服务方法)
|
|
23
|
+
- [最佳实践](#最佳实践)
|
|
24
|
+
- [移动端特性](#移动端特性)
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## 快速开始
|
|
29
|
+
|
|
30
|
+
### 安装
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npm install @uxda/nutshell
|
|
34
|
+
# 或
|
|
35
|
+
yarn add @uxda/nutshell
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### H5 项目引入
|
|
39
|
+
|
|
40
|
+
```javascript
|
|
41
|
+
import { createApp } from 'vue'
|
|
42
|
+
import Nutshell from '@uxda/nutshell/taro'
|
|
43
|
+
import '@uxda/nutshell/nutshell.css'
|
|
44
|
+
import '@uxda/nutshell/nutui.css' // 移动端样式
|
|
45
|
+
|
|
46
|
+
const app = createApp(App)
|
|
47
|
+
app.use(Nutshell)
|
|
48
|
+
app.mount('#app')
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Taro 小程序项目引入
|
|
52
|
+
|
|
53
|
+
```javascript
|
|
54
|
+
// app.ts
|
|
55
|
+
import { createApp } from 'vue'
|
|
56
|
+
import Nutshell from '@uxda/nutshell/taro'
|
|
57
|
+
|
|
58
|
+
const app = createApp({
|
|
59
|
+
// ...
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
app.use(Nutshell)
|
|
63
|
+
|
|
64
|
+
export default app
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### 按需引入组件
|
|
68
|
+
|
|
69
|
+
```javascript
|
|
70
|
+
import { NsButton, NsInput, NsList } from '@uxda/nutshell/components'
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## 平台支持
|
|
76
|
+
|
|
77
|
+
Nutshell 移动端组件库支持以下平台:
|
|
78
|
+
|
|
79
|
+
- ✅ H5(移动端网页)
|
|
80
|
+
- ✅ 微信小程序
|
|
81
|
+
- ✅ 支付宝小程序(部分)
|
|
82
|
+
- ✅ 钉钉小程序(部分)
|
|
83
|
+
|
|
84
|
+
### 平台检测
|
|
85
|
+
|
|
86
|
+
```vue
|
|
87
|
+
<script setup>
|
|
88
|
+
import { usePlatform } from '@uxda/nutshell/taro'
|
|
89
|
+
|
|
90
|
+
const platform = usePlatform()
|
|
91
|
+
|
|
92
|
+
console.log(platform.mobile) // 是否移动端
|
|
93
|
+
console.log(platform.h5) // 是否H5
|
|
94
|
+
console.log(platform.weixin) // 是否微信环境
|
|
95
|
+
console.log(platform.android) // 是否Android
|
|
96
|
+
console.log(platform.ios) // 是否iOS
|
|
97
|
+
</script>
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## 基础组件
|
|
103
|
+
|
|
104
|
+
### 1. Button 按钮
|
|
105
|
+
|
|
106
|
+
**组件名称**: `<ns-button>`
|
|
107
|
+
|
|
108
|
+
**用途**: 触发操作、提交表单、跳转页面等交互行为
|
|
109
|
+
|
|
110
|
+
**Props**:
|
|
111
|
+
|
|
112
|
+
| 属性名 | 类型 | 默认值 | 说明 |
|
|
113
|
+
|--------|------|--------|------|
|
|
114
|
+
| `label` | `string` | - | 按钮文字 |
|
|
115
|
+
| `color` | `Color` | - | 按钮颜色 |
|
|
116
|
+
| `size` | `'xs'\|'sm'\|'md'\|'lg'\|'xl'` | `'md'` | 按钮尺寸 |
|
|
117
|
+
| `variant` | `'solid'\|'outlined'\|'soft'\|'plain'` | - | 按钮样式风格 |
|
|
118
|
+
| `disabled` | `boolean` | `false` | 是否禁用 |
|
|
119
|
+
| `loading` | `boolean` | `false` | 是否显示加载状态 |
|
|
120
|
+
| `icon` | `string` | - | 图标名称 |
|
|
121
|
+
| `block` | `boolean` | `false` | 是否块级元素(宽度100%) |
|
|
122
|
+
|
|
123
|
+
**Slots**:
|
|
124
|
+
|
|
125
|
+
- `default`: 按钮内容
|
|
126
|
+
- `icon`: 自定义图标
|
|
127
|
+
|
|
128
|
+
**示例**:
|
|
129
|
+
|
|
130
|
+
```vue
|
|
131
|
+
<!-- 基础用法 -->
|
|
132
|
+
<ns-button label="提交" />
|
|
133
|
+
|
|
134
|
+
<!-- 块级按钮 -->
|
|
135
|
+
<ns-button label="立即购买" color="primary" block />
|
|
136
|
+
|
|
137
|
+
<!-- 带图标 -->
|
|
138
|
+
<ns-button label="分享" icon="share" />
|
|
139
|
+
|
|
140
|
+
<!-- 加载状态 -->
|
|
141
|
+
<ns-button label="提交中..." :loading="true" />
|
|
142
|
+
|
|
143
|
+
<!-- 不同尺寸 -->
|
|
144
|
+
<ns-button label="小按钮" size="sm" />
|
|
145
|
+
<ns-button label="中按钮" size="md" />
|
|
146
|
+
<ns-button label="大按钮" size="lg" />
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
### 2. Icon 图标
|
|
152
|
+
|
|
153
|
+
**组件名称**: `<ns-icon>`
|
|
154
|
+
|
|
155
|
+
**用途**: 展示图标
|
|
156
|
+
|
|
157
|
+
**Props**:
|
|
158
|
+
|
|
159
|
+
| 属性名 | 类型 | 默认值 | 说明 |
|
|
160
|
+
|--------|------|--------|------|
|
|
161
|
+
| `name` | `string` | - | 图标名称 |
|
|
162
|
+
| `size` | `Size\|number` | `'md'` | 图标尺寸 |
|
|
163
|
+
| `fill` | `Color` | - | 图标颜色 |
|
|
164
|
+
|
|
165
|
+
**示例**:
|
|
166
|
+
|
|
167
|
+
```vue
|
|
168
|
+
<ns-icon name="home" />
|
|
169
|
+
<ns-icon name="user" size="lg" fill="primary" />
|
|
170
|
+
<ns-icon name="setting" :size="24" />
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
### 3. Avatar 头像
|
|
176
|
+
|
|
177
|
+
**组件名称**: `<ns-avatar>`
|
|
178
|
+
|
|
179
|
+
**用途**: 展示用户头像
|
|
180
|
+
|
|
181
|
+
**Props**:
|
|
182
|
+
|
|
183
|
+
| 属性名 | 类型 | 默认值 | 说明 |
|
|
184
|
+
|--------|------|--------|------|
|
|
185
|
+
| `src` | `string` | - | 头像图片地址 |
|
|
186
|
+
| `size` | `Size\|number` | `'md'` | 头像尺寸 |
|
|
187
|
+
| `shape` | `'circle'\|'square'` | `'circle'` | 头像形状 |
|
|
188
|
+
|
|
189
|
+
**示例**:
|
|
190
|
+
|
|
191
|
+
```vue
|
|
192
|
+
<ns-avatar src="/avatar.jpg" />
|
|
193
|
+
<ns-avatar size="lg" shape="square">用</ns-avatar>
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
### 4. Image 图片
|
|
199
|
+
|
|
200
|
+
**组件名称**: `<ns-image>`
|
|
201
|
+
|
|
202
|
+
**用途**: 展示图片,支持懒加载、预览
|
|
203
|
+
|
|
204
|
+
**Props**:
|
|
205
|
+
|
|
206
|
+
| 属性名 | 类型 | 默认值 | 说明 |
|
|
207
|
+
|--------|------|--------|------|
|
|
208
|
+
| `src` | `string` | - | 图片地址 |
|
|
209
|
+
| `width` | `string\|number` | - | 图片宽度 |
|
|
210
|
+
| `height` | `string\|number` | - | 图片高度 |
|
|
211
|
+
| `fit` | `'fill'\|'contain'\|'cover'\|'none'\|'scale-down'` | `'cover'` | 图片填充模式 |
|
|
212
|
+
| `lazy` | `boolean` | `false` | 是否懒加载 |
|
|
213
|
+
| `preview` | `boolean` | `false` | 是否支持预览 |
|
|
214
|
+
|
|
215
|
+
**示例**:
|
|
216
|
+
|
|
217
|
+
```vue
|
|
218
|
+
<ns-image
|
|
219
|
+
src="/photo.jpg"
|
|
220
|
+
width="200"
|
|
221
|
+
height="200"
|
|
222
|
+
lazy
|
|
223
|
+
preview
|
|
224
|
+
/>
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
### 5. Chip 标签
|
|
230
|
+
|
|
231
|
+
**组件名称**: `<ns-chip>`
|
|
232
|
+
|
|
233
|
+
**用途**: 展示标签或状态
|
|
234
|
+
|
|
235
|
+
**Props**:
|
|
236
|
+
|
|
237
|
+
| 属性名 | 类型 | 默认值 | 说明 |
|
|
238
|
+
|--------|------|--------|------|
|
|
239
|
+
| `label` | `string` | - | 标签文字 |
|
|
240
|
+
| `color` | `Color` | - | 标签颜色 |
|
|
241
|
+
| `size` | `Size` | `'md'` | 标签尺寸 |
|
|
242
|
+
| `closable` | `boolean` | `false` | 是否可关闭 |
|
|
243
|
+
|
|
244
|
+
**示例**:
|
|
245
|
+
|
|
246
|
+
```vue
|
|
247
|
+
<ns-chip label="新品" color="danger" />
|
|
248
|
+
<ns-chip label="热销" color="warning" />
|
|
249
|
+
<ns-chip label="标签" closable @close="handleClose" />
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
### 6. Chips 标签组
|
|
255
|
+
|
|
256
|
+
**组件名称**: `<ns-chips>`
|
|
257
|
+
|
|
258
|
+
**用途**: 展示多个标签
|
|
259
|
+
|
|
260
|
+
**Props**:
|
|
261
|
+
|
|
262
|
+
| 属性名 | 类型 | 默认值 | 说明 |
|
|
263
|
+
|--------|------|--------|------|
|
|
264
|
+
| `items` | `ChipItem[]` | `[]` | 标签数据 |
|
|
265
|
+
|
|
266
|
+
**示例**:
|
|
267
|
+
|
|
268
|
+
```vue
|
|
269
|
+
<ns-chips
|
|
270
|
+
:items="[
|
|
271
|
+
{ text: 'JavaScript', color: 'warning' },
|
|
272
|
+
{ text: 'Vue.js', color: 'success' },
|
|
273
|
+
{ text: 'TypeScript', color: 'primary' }
|
|
274
|
+
]"
|
|
275
|
+
/>
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
|
|
280
|
+
## 表单组件
|
|
281
|
+
|
|
282
|
+
### 1. Form 表单
|
|
283
|
+
|
|
284
|
+
**组件名称**: `<ns-form>`
|
|
285
|
+
|
|
286
|
+
**用途**: 表单容器,用于数据收集、校验和提交
|
|
287
|
+
|
|
288
|
+
**Props**:
|
|
289
|
+
|
|
290
|
+
| 属性名 | 类型 | 默认值 | 说明 |
|
|
291
|
+
|--------|------|--------|------|
|
|
292
|
+
| `modelValue` | `object` | - | 表单数据对象 |
|
|
293
|
+
| `name` | `string` | - | 表单名称 |
|
|
294
|
+
| `failed` | `'toast'\|'notice'\|'none'` | `'toast'` | 校验失败时的提示方式 |
|
|
295
|
+
|
|
296
|
+
**Events**:
|
|
297
|
+
|
|
298
|
+
| 事件名 | 参数 | 说明 |
|
|
299
|
+
|--------|------|------|
|
|
300
|
+
| `update:modelValue` | `(value: Record<string, any>)` | 表单数据更新 |
|
|
301
|
+
|
|
302
|
+
**Methods**:
|
|
303
|
+
|
|
304
|
+
| 方法名 | 参数 | 返回值 | 说明 |
|
|
305
|
+
|--------|------|--------|------|
|
|
306
|
+
| `validate` | `nameList?: NamePath` | `Promise<boolean>` | 触发表单验证 |
|
|
307
|
+
| `resetFields` | `nameList?: NamePath[]` | - | 重置表单字段 |
|
|
308
|
+
| `reset` | - | - | 重置整个表单 |
|
|
309
|
+
| `clearValidate` | `nameList?: NamePath[]` | - | 移除表单校验结果 |
|
|
310
|
+
|
|
311
|
+
**示例**:
|
|
312
|
+
|
|
313
|
+
```vue
|
|
314
|
+
<template>
|
|
315
|
+
<ns-form v-model="formData" ref="formRef">
|
|
316
|
+
<ns-input
|
|
317
|
+
name="username"
|
|
318
|
+
label="用户名"
|
|
319
|
+
:rules="['required']"
|
|
320
|
+
placeholder="请输入用户名"
|
|
321
|
+
/>
|
|
322
|
+
<ns-input
|
|
323
|
+
name="phone"
|
|
324
|
+
label="手机号"
|
|
325
|
+
:rules="['required', 'mobile']"
|
|
326
|
+
placeholder="请输入手机号"
|
|
327
|
+
/>
|
|
328
|
+
<ns-button label="提交" block @click="handleSubmit" />
|
|
329
|
+
</ns-form>
|
|
330
|
+
</template>
|
|
331
|
+
|
|
332
|
+
<script setup>
|
|
333
|
+
import { ref } from 'vue'
|
|
334
|
+
import { useNutshell } from '@uxda/nutshell/taro'
|
|
335
|
+
|
|
336
|
+
const $n = useNutshell()
|
|
337
|
+
const formRef = ref()
|
|
338
|
+
const formData = ref({
|
|
339
|
+
username: '',
|
|
340
|
+
phone: ''
|
|
341
|
+
})
|
|
342
|
+
|
|
343
|
+
const handleSubmit = async () => {
|
|
344
|
+
const valid = await formRef.value.validate()
|
|
345
|
+
if (valid) {
|
|
346
|
+
$n.toast('提交成功', { type: 'success' })
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
</script>
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
---
|
|
353
|
+
|
|
354
|
+
### 2. Input 输入框
|
|
355
|
+
|
|
356
|
+
**组件名称**: `<ns-input>`
|
|
357
|
+
|
|
358
|
+
**用途**: 单行文本输入
|
|
359
|
+
|
|
360
|
+
**Props**:
|
|
361
|
+
|
|
362
|
+
| 属性名 | 类型 | 默认值 | 说明 |
|
|
363
|
+
|--------|------|--------|------|
|
|
364
|
+
| `modelValue` | `string\|number` | - | 输入值(v-model) |
|
|
365
|
+
| `name` | `string` | - | 表单项名称(必填) |
|
|
366
|
+
| `label` | `string` | - | 标签文字 |
|
|
367
|
+
| `type` | `'text'\|'number'\|'tel'\|'password'` | `'text'` | 输入框类型 |
|
|
368
|
+
| `placeholder` | `string` | - | 占位符 |
|
|
369
|
+
| `maxlength` | `number` | - | 最大输入长度 |
|
|
370
|
+
| `clearable` | `boolean` | `true` | 是否显示清空按钮 |
|
|
371
|
+
| `disabled` | `boolean` | `false` | 是否禁用 |
|
|
372
|
+
| `readonly` | `boolean` | `false` | 是否只读 |
|
|
373
|
+
| `rules` | `ValidationRule[]` | - | 校验规则 |
|
|
374
|
+
| `textAlign` | `'left'\|'right'\|'center'` | `'left'` | 文字对齐方向 |
|
|
375
|
+
|
|
376
|
+
**Events**:
|
|
377
|
+
|
|
378
|
+
| 事件名 | 参数 | 说明 |
|
|
379
|
+
|--------|------|------|
|
|
380
|
+
| `update:modelValue` | `(value: string\|number)` | 值更新 |
|
|
381
|
+
| `change` | `(value: string\|number)` | 值改变 |
|
|
382
|
+
| `blur` | `()` | 失去焦点 |
|
|
383
|
+
| `focus` | `()` | 获得焦点 |
|
|
384
|
+
| `enter` | `()` | 按下回车(H5) |
|
|
385
|
+
|
|
386
|
+
**校验规则**:
|
|
387
|
+
|
|
388
|
+
- `'required'`: 必填
|
|
389
|
+
- `'numeric'`: 纯数字
|
|
390
|
+
- `'email'`: 邮箱格式
|
|
391
|
+
- `'id'`: 身份证号
|
|
392
|
+
- `'mobile'`: 手机号
|
|
393
|
+
|
|
394
|
+
**示例**:
|
|
395
|
+
|
|
396
|
+
```vue
|
|
397
|
+
<!-- 基础输入 -->
|
|
398
|
+
<ns-input
|
|
399
|
+
v-model="username"
|
|
400
|
+
name="username"
|
|
401
|
+
label="用户名"
|
|
402
|
+
placeholder="请输入用户名"
|
|
403
|
+
/>
|
|
404
|
+
|
|
405
|
+
<!-- 手机号输入 -->
|
|
406
|
+
<ns-input
|
|
407
|
+
v-model="phone"
|
|
408
|
+
name="phone"
|
|
409
|
+
label="手机号"
|
|
410
|
+
type="tel"
|
|
411
|
+
:rules="['required', 'mobile']"
|
|
412
|
+
placeholder="请输入手机号"
|
|
413
|
+
/>
|
|
414
|
+
|
|
415
|
+
<!-- 密码输入 -->
|
|
416
|
+
<ns-input
|
|
417
|
+
v-model="password"
|
|
418
|
+
name="password"
|
|
419
|
+
label="密码"
|
|
420
|
+
type="password"
|
|
421
|
+
:rules="['required']"
|
|
422
|
+
placeholder="请输入密码"
|
|
423
|
+
/>
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
---
|
|
427
|
+
|
|
428
|
+
### 3. MobileInput 手机号输入
|
|
429
|
+
|
|
430
|
+
**组件名称**: `<ns-mobile-input>`
|
|
431
|
+
|
|
432
|
+
**用途**: 手机号输入(自动格式化为 xxx-xxxx-xxxx)
|
|
433
|
+
|
|
434
|
+
**Props**: 继承自 `NsInput`,自动设置 `type="tel"` 和 `rules="['mobile']"`
|
|
435
|
+
|
|
436
|
+
**示例**:
|
|
437
|
+
|
|
438
|
+
```vue
|
|
439
|
+
<ns-mobile-input
|
|
440
|
+
v-model="phone"
|
|
441
|
+
name="phone"
|
|
442
|
+
label="手机号"
|
|
443
|
+
/>
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
---
|
|
447
|
+
|
|
448
|
+
### 4. IdInput 身份证号输入
|
|
449
|
+
|
|
450
|
+
**组件名称**: `<ns-id-input>`
|
|
451
|
+
|
|
452
|
+
**用途**: 身份证号输入
|
|
453
|
+
|
|
454
|
+
**Props**: 继承自 `NsInput`,自动设置校验规则
|
|
455
|
+
|
|
456
|
+
**示例**:
|
|
457
|
+
|
|
458
|
+
```vue
|
|
459
|
+
<ns-id-input
|
|
460
|
+
v-model="idCard"
|
|
461
|
+
name="idCard"
|
|
462
|
+
label="身份证号"
|
|
463
|
+
/>
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
---
|
|
467
|
+
|
|
468
|
+
### 5. Textarea 多行文本框
|
|
469
|
+
|
|
470
|
+
**组件名称**: `<ns-textarea>`
|
|
471
|
+
|
|
472
|
+
**用途**: 多行文本输入
|
|
473
|
+
|
|
474
|
+
**Props**: 继承自 `NsInput`,额外支持:
|
|
475
|
+
|
|
476
|
+
| 属性名 | 类型 | 默认值 | 说明 |
|
|
477
|
+
|--------|------|--------|------|
|
|
478
|
+
| `rows` | `number` | `3` | 行数 |
|
|
479
|
+
| `autoSize` | `boolean` | `false` | 自适应高度 |
|
|
480
|
+
|
|
481
|
+
**示例**:
|
|
482
|
+
|
|
483
|
+
```vue
|
|
484
|
+
<ns-textarea
|
|
485
|
+
v-model="comment"
|
|
486
|
+
name="comment"
|
|
487
|
+
label="备注"
|
|
488
|
+
:rows="5"
|
|
489
|
+
placeholder="请输入备注"
|
|
490
|
+
/>
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
---
|
|
494
|
+
|
|
495
|
+
### 6. Select 下拉选择
|
|
496
|
+
|
|
497
|
+
**组件名称**: `<ns-select>`
|
|
498
|
+
|
|
499
|
+
**用途**: 下拉选择单个选项(移动端会弹出选择器)
|
|
500
|
+
|
|
501
|
+
**Props**:
|
|
502
|
+
|
|
503
|
+
| 属性名 | 类型 | 默认值 | 说明 |
|
|
504
|
+
|--------|------|--------|------|
|
|
505
|
+
| `modelValue` | `string\|number` | - | 选中值 |
|
|
506
|
+
| `name` | `string` | - | 表单项名称 |
|
|
507
|
+
| `label` | `string` | - | 标签文字 |
|
|
508
|
+
| `options` | `SelectOption[]` | - | 选项数据 |
|
|
509
|
+
| `placeholder` | `string` | - | 占位符 |
|
|
510
|
+
| `disabled` | `boolean` | `false` | 是否禁用 |
|
|
511
|
+
| `rules` | `ValidationRule[]` | - | 校验规则 |
|
|
512
|
+
|
|
513
|
+
**选项数据格式**:
|
|
514
|
+
|
|
515
|
+
```typescript
|
|
516
|
+
type SelectOption = {
|
|
517
|
+
text: string // 显示文字
|
|
518
|
+
value: string | number // 选项值
|
|
519
|
+
disabled?: boolean // 是否禁用
|
|
520
|
+
}
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
**示例**:
|
|
524
|
+
|
|
525
|
+
```vue
|
|
526
|
+
<template>
|
|
527
|
+
<ns-select
|
|
528
|
+
v-model="selectedCity"
|
|
529
|
+
name="city"
|
|
530
|
+
label="城市"
|
|
531
|
+
:options="cityOptions"
|
|
532
|
+
placeholder="请选择城市"
|
|
533
|
+
/>
|
|
534
|
+
</template>
|
|
535
|
+
|
|
536
|
+
<script setup>
|
|
537
|
+
import { ref } from 'vue'
|
|
538
|
+
|
|
539
|
+
const selectedCity = ref('')
|
|
540
|
+
const cityOptions = [
|
|
541
|
+
{ text: '北京', value: 'beijing' },
|
|
542
|
+
{ text: '上海', value: 'shanghai' },
|
|
543
|
+
{ text: '深圳', value: 'shenzhen' }
|
|
544
|
+
]
|
|
545
|
+
</script>
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
---
|
|
549
|
+
|
|
550
|
+
### 7. DateSelect 日期选择
|
|
551
|
+
|
|
552
|
+
**组件名称**: `<ns-date-select>`
|
|
553
|
+
|
|
554
|
+
**用途**: 日期选择(移动端友好的日期选择器)
|
|
555
|
+
|
|
556
|
+
**Props**:
|
|
557
|
+
|
|
558
|
+
| 属性名 | 类型 | 默认值 | 说明 |
|
|
559
|
+
|--------|------|--------|------|
|
|
560
|
+
| `modelValue` | `string` | - | 日期值(YYYY-MM-DD) |
|
|
561
|
+
| `name` | `string` | - | 表单项名称 |
|
|
562
|
+
| `label` | `string` | - | 标签文字 |
|
|
563
|
+
| `minDate` | `Date` | - | 最小日期 |
|
|
564
|
+
| `maxDate` | `Date` | - | 最大日期 |
|
|
565
|
+
|
|
566
|
+
**示例**:
|
|
567
|
+
|
|
568
|
+
```vue
|
|
569
|
+
<ns-date-select
|
|
570
|
+
v-model="birthDate"
|
|
571
|
+
name="birthDate"
|
|
572
|
+
label="出生日期"
|
|
573
|
+
/>
|
|
574
|
+
```
|
|
575
|
+
|
|
576
|
+
---
|
|
577
|
+
|
|
578
|
+
### 8. Checkbox 复选框
|
|
579
|
+
|
|
580
|
+
**组件名称**: `<ns-checkbox>`
|
|
581
|
+
|
|
582
|
+
**用途**: 单个复选框
|
|
583
|
+
|
|
584
|
+
**Props**:
|
|
585
|
+
|
|
586
|
+
| 属性名 | 类型 | 默认值 | 说明 |
|
|
587
|
+
|--------|------|--------|------|
|
|
588
|
+
| `modelValue` | `boolean` | - | 选中状态 |
|
|
589
|
+
| `label` | `string` | - | 标签文字 |
|
|
590
|
+
| `disabled` | `boolean` | `false` | 是否禁用 |
|
|
591
|
+
|
|
592
|
+
**示例**:
|
|
593
|
+
|
|
594
|
+
```vue
|
|
595
|
+
<ns-checkbox v-model="agreed" label="我已阅读并同意用户协议" />
|
|
596
|
+
```
|
|
597
|
+
|
|
598
|
+
---
|
|
599
|
+
|
|
600
|
+
### 9. CheckboxGroup 复选框组
|
|
601
|
+
|
|
602
|
+
**组件名称**: `<ns-checkbox-group>`
|
|
603
|
+
|
|
604
|
+
**用途**: 多个复选框组
|
|
605
|
+
|
|
606
|
+
**Props**:
|
|
607
|
+
|
|
608
|
+
| 属性名 | 类型 | 默认值 | 说明 |
|
|
609
|
+
|--------|------|--------|------|
|
|
610
|
+
| `modelValue` | `(string\|number)[]` | - | 选中值数组 |
|
|
611
|
+
| `name` | `string` | - | 表单项名称 |
|
|
612
|
+
| `options` | `SelectOption[]` | - | 选项数据 |
|
|
613
|
+
| `max` | `number` | - | 最大可选数 |
|
|
614
|
+
|
|
615
|
+
**示例**:
|
|
616
|
+
|
|
617
|
+
```vue
|
|
618
|
+
<ns-checkbox-group
|
|
619
|
+
v-model="interests"
|
|
620
|
+
name="interests"
|
|
621
|
+
:options="[
|
|
622
|
+
{ text: '篮球', value: 'basketball' },
|
|
623
|
+
{ text: '足球', value: 'football' },
|
|
624
|
+
{ text: '游泳', value: 'swimming' }
|
|
625
|
+
]"
|
|
626
|
+
:max="2"
|
|
627
|
+
/>
|
|
628
|
+
```
|
|
629
|
+
|
|
630
|
+
---
|
|
631
|
+
|
|
632
|
+
### 10. RadioGroup 单选框组
|
|
633
|
+
|
|
634
|
+
**组件名称**: `<ns-radio-group>`
|
|
635
|
+
|
|
636
|
+
**用途**: 单选框组
|
|
637
|
+
|
|
638
|
+
**Props**:
|
|
639
|
+
|
|
640
|
+
| 属性名 | 类型 | 默认值 | 说明 |
|
|
641
|
+
|--------|------|--------|------|
|
|
642
|
+
| `modelValue` | `string\|number` | - | 选中值 |
|
|
643
|
+
| `name` | `string` | - | 表单项名称 |
|
|
644
|
+
| `options` | `SelectOption[]` | - | 选项数据 |
|
|
645
|
+
| `direction` | `'horizontal'\|'vertical'` | `'vertical'` | 排列方向 |
|
|
646
|
+
|
|
647
|
+
**示例**:
|
|
648
|
+
|
|
649
|
+
```vue
|
|
650
|
+
<ns-radio-group
|
|
651
|
+
v-model="gender"
|
|
652
|
+
name="gender"
|
|
653
|
+
:options="[
|
|
654
|
+
{ text: '男', value: 'male' },
|
|
655
|
+
{ text: '女', value: 'female' }
|
|
656
|
+
]"
|
|
657
|
+
direction="horizontal"
|
|
658
|
+
/>
|
|
659
|
+
```
|
|
660
|
+
|
|
661
|
+
---
|
|
662
|
+
|
|
663
|
+
### 11. Switch 开关
|
|
664
|
+
|
|
665
|
+
**组件名称**: `<ns-switch>`
|
|
666
|
+
|
|
667
|
+
**用途**: 开关切换
|
|
668
|
+
|
|
669
|
+
**Props**:
|
|
670
|
+
|
|
671
|
+
| 属性名 | 类型 | 默认值 | 说明 |
|
|
672
|
+
|--------|------|--------|------|
|
|
673
|
+
| `modelValue` | `boolean` | - | 开关状态 |
|
|
674
|
+
| `disabled` | `boolean` | `false` | 是否禁用 |
|
|
675
|
+
| `activeText` | `string` | - | 打开时的文字 |
|
|
676
|
+
| `inactiveText` | `string` | - | 关闭时的文字 |
|
|
677
|
+
|
|
678
|
+
**示例**:
|
|
679
|
+
|
|
680
|
+
```vue
|
|
681
|
+
<ns-switch
|
|
682
|
+
v-model="enabled"
|
|
683
|
+
active-text="开启"
|
|
684
|
+
inactive-text="关闭"
|
|
685
|
+
/>
|
|
686
|
+
```
|
|
687
|
+
|
|
688
|
+
---
|
|
689
|
+
|
|
690
|
+
### 12. Rating 评分
|
|
691
|
+
|
|
692
|
+
**组件名称**: `<ns-rating-input>`
|
|
693
|
+
|
|
694
|
+
**用途**: 星级评分输入
|
|
695
|
+
|
|
696
|
+
**Props**:
|
|
697
|
+
|
|
698
|
+
| 属性名 | 类型 | 默认值 | 说明 |
|
|
699
|
+
|--------|------|--------|------|
|
|
700
|
+
| `modelValue` | `number` | - | 评分值 |
|
|
701
|
+
| `name` | `string` | - | 表单项名称 |
|
|
702
|
+
| `count` | `number` | `5` | 星星总数 |
|
|
703
|
+
| `allowHalf` | `boolean` | `false` | 是否允许半星 |
|
|
704
|
+
| `disabled` | `boolean` | `false` | 是否禁用 |
|
|
705
|
+
|
|
706
|
+
**示例**:
|
|
707
|
+
|
|
708
|
+
```vue
|
|
709
|
+
<ns-rating-input
|
|
710
|
+
v-model="rating"
|
|
711
|
+
name="rating"
|
|
712
|
+
:count="5"
|
|
713
|
+
allow-half
|
|
714
|
+
/>
|
|
715
|
+
```
|
|
716
|
+
|
|
717
|
+
---
|
|
718
|
+
|
|
719
|
+
### 13. Stepper 步进器
|
|
720
|
+
|
|
721
|
+
**组件名称**: `<ns-stepper>`
|
|
722
|
+
|
|
723
|
+
**用途**: 数字增减器
|
|
724
|
+
|
|
725
|
+
**Props**:
|
|
726
|
+
|
|
727
|
+
| 属性名 | 类型 | 默认值 | 说明 |
|
|
728
|
+
|--------|------|--------|------|
|
|
729
|
+
| `modelValue` | `number` | - | 数字值 |
|
|
730
|
+
| `min` | `number` | `0` | 最小值 |
|
|
731
|
+
| `max` | `number` | `999` | 最大值 |
|
|
732
|
+
| `step` | `number` | `1` | 步长 |
|
|
733
|
+
| `disabled` | `boolean` | `false` | 是否禁用 |
|
|
734
|
+
| `inputWidth` | `string` | `'40px'` | 输入框宽度 |
|
|
735
|
+
|
|
736
|
+
**示例**:
|
|
737
|
+
|
|
738
|
+
```vue
|
|
739
|
+
<ns-stepper
|
|
740
|
+
v-model="quantity"
|
|
741
|
+
:min="1"
|
|
742
|
+
:max="99"
|
|
743
|
+
:step="1"
|
|
744
|
+
/>
|
|
745
|
+
```
|
|
746
|
+
|
|
747
|
+
---
|
|
748
|
+
|
|
749
|
+
### 14. Upload 文件上传
|
|
750
|
+
|
|
751
|
+
**组件名称**: `<ns-upload>`
|
|
752
|
+
|
|
753
|
+
**用途**: 文件/图片上传
|
|
754
|
+
|
|
755
|
+
**Props**:
|
|
756
|
+
|
|
757
|
+
| 属性名 | 类型 | 默认值 | 说明 |
|
|
758
|
+
|--------|------|--------|------|
|
|
759
|
+
| `modelValue` | `File[]` | - | 文件列表 |
|
|
760
|
+
| `accept` | `string` | `'image/*'` | 接受的文件类型 |
|
|
761
|
+
| `multiple` | `boolean` | `false` | 是否支持多选 |
|
|
762
|
+
| `maxSize` | `number` | - | 最大文件大小(字节) |
|
|
763
|
+
| `maxCount` | `number` | `9` | 最大文件数量 |
|
|
764
|
+
| `capture` | `boolean` | `false` | 是否调起摄像头 |
|
|
765
|
+
|
|
766
|
+
**示例**:
|
|
767
|
+
|
|
768
|
+
```vue
|
|
769
|
+
<!-- 图片上传 -->
|
|
770
|
+
<ns-upload
|
|
771
|
+
v-model="images"
|
|
772
|
+
accept="image/*"
|
|
773
|
+
:max-count="9"
|
|
774
|
+
multiple
|
|
775
|
+
/>
|
|
776
|
+
|
|
777
|
+
<!-- 拍照上传 -->
|
|
778
|
+
<ns-upload
|
|
779
|
+
v-model="photo"
|
|
780
|
+
capture
|
|
781
|
+
/>
|
|
782
|
+
```
|
|
783
|
+
|
|
784
|
+
---
|
|
785
|
+
|
|
786
|
+
## 数据展示组件
|
|
787
|
+
|
|
788
|
+
### 1. List 列表
|
|
789
|
+
|
|
790
|
+
**组件名称**: `<ns-list>`
|
|
791
|
+
|
|
792
|
+
**用途**: 展示列表数据,支持下拉刷新、上拉加载
|
|
793
|
+
|
|
794
|
+
**Props**:
|
|
795
|
+
|
|
796
|
+
| 属性名 | 类型 | 默认值 | 说明 |
|
|
797
|
+
|--------|------|--------|------|
|
|
798
|
+
| `data` | `any[]` | `[]` | 列表数据 |
|
|
799
|
+
| `loading` | `boolean` | `false` | 是否加载中 |
|
|
800
|
+
| `finished` | `boolean` | `false` | 是否加载完成 |
|
|
801
|
+
| `refreshable` | `boolean` | `false` | 是否支持下拉刷新 |
|
|
802
|
+
| `loadmore` | `boolean` | `false` | 是否支持上拉加载更多 |
|
|
803
|
+
|
|
804
|
+
**Events**:
|
|
805
|
+
|
|
806
|
+
| 事件名 | 参数 | 说明 |
|
|
807
|
+
|--------|------|------|
|
|
808
|
+
| `refresh` | `()` | 下拉刷新 |
|
|
809
|
+
| `load` | `()` | 上拉加载更多 |
|
|
810
|
+
|
|
811
|
+
**示例**:
|
|
812
|
+
|
|
813
|
+
```vue
|
|
814
|
+
<template>
|
|
815
|
+
<ns-list
|
|
816
|
+
:data="items"
|
|
817
|
+
:loading="loading"
|
|
818
|
+
:finished="finished"
|
|
819
|
+
refreshable
|
|
820
|
+
loadmore
|
|
821
|
+
@refresh="handleRefresh"
|
|
822
|
+
@load="handleLoad"
|
|
823
|
+
>
|
|
824
|
+
<template #default="{ item }">
|
|
825
|
+
<div class="list-item">
|
|
826
|
+
<h3>{{ item.title }}</h3>
|
|
827
|
+
<p>{{ item.desc }}</p>
|
|
828
|
+
</div>
|
|
829
|
+
</template>
|
|
830
|
+
</ns-list>
|
|
831
|
+
</template>
|
|
832
|
+
|
|
833
|
+
<script setup>
|
|
834
|
+
import { ref } from 'vue'
|
|
835
|
+
|
|
836
|
+
const items = ref([])
|
|
837
|
+
const loading = ref(false)
|
|
838
|
+
const finished = ref(false)
|
|
839
|
+
const page = ref(1)
|
|
840
|
+
|
|
841
|
+
const handleRefresh = async () => {
|
|
842
|
+
page.value = 1
|
|
843
|
+
finished.value = false
|
|
844
|
+
await loadData()
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
const handleLoad = async () => {
|
|
848
|
+
page.value++
|
|
849
|
+
await loadData()
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
const loadData = async () => {
|
|
853
|
+
loading.value = true
|
|
854
|
+
try {
|
|
855
|
+
const response = await api.getList(page.value)
|
|
856
|
+
if (page.value === 1) {
|
|
857
|
+
items.value = response.data
|
|
858
|
+
} else {
|
|
859
|
+
items.value.push(...response.data)
|
|
860
|
+
}
|
|
861
|
+
finished.value = !response.hasMore
|
|
862
|
+
} finally {
|
|
863
|
+
loading.value = false
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
</script>
|
|
867
|
+
```
|
|
868
|
+
|
|
869
|
+
---
|
|
870
|
+
|
|
871
|
+
### 2. Card 卡片
|
|
872
|
+
|
|
873
|
+
**组件名称**: `<ns-card>`
|
|
874
|
+
|
|
875
|
+
**用途**: 卡片容器
|
|
876
|
+
|
|
877
|
+
**Props**:
|
|
878
|
+
|
|
879
|
+
| 属性名 | 类型 | 默认值 | 说明 |
|
|
880
|
+
|--------|------|--------|------|
|
|
881
|
+
| `title` | `string` | - | 卡片标题 |
|
|
882
|
+
| `padding` | `Size` | `'md'` | 内边距 |
|
|
883
|
+
| `radius` | `Size` | `'md'` | 圆角大小 |
|
|
884
|
+
| `shadow` | `boolean` | `false` | 是否显示阴影 |
|
|
885
|
+
|
|
886
|
+
**Slots**:
|
|
887
|
+
|
|
888
|
+
- `default`: 卡片内容
|
|
889
|
+
- `header`: 自定义头部
|
|
890
|
+
- `footer`: 底部内容
|
|
891
|
+
|
|
892
|
+
**示例**:
|
|
893
|
+
|
|
894
|
+
```vue
|
|
895
|
+
<ns-card title="商品信息">
|
|
896
|
+
<p>商品名称:iPhone 15 Pro</p>
|
|
897
|
+
<p>价格:¥7999</p>
|
|
898
|
+
<template #footer>
|
|
899
|
+
<ns-button label="立即购买" block />
|
|
900
|
+
</template>
|
|
901
|
+
</ns-card>
|
|
902
|
+
```
|
|
903
|
+
|
|
904
|
+
---
|
|
905
|
+
|
|
906
|
+
### 3. Empty 空状态
|
|
907
|
+
|
|
908
|
+
**组件名称**: `<ns-empty>`
|
|
909
|
+
|
|
910
|
+
**用途**: 展示空状态
|
|
911
|
+
|
|
912
|
+
**Props**:
|
|
913
|
+
|
|
914
|
+
| 属性名 | 类型 | 默认值 | 说明 |
|
|
915
|
+
|--------|------|--------|------|
|
|
916
|
+
| `description` | `string` | `'暂无数据'` | 描述文字 |
|
|
917
|
+
| `image` | `string` | - | 空状态图片 |
|
|
918
|
+
|
|
919
|
+
**示例**:
|
|
920
|
+
|
|
921
|
+
```vue
|
|
922
|
+
<ns-empty description="暂无订单" />
|
|
923
|
+
```
|
|
924
|
+
|
|
925
|
+
---
|
|
926
|
+
|
|
927
|
+
### 4. Timeline 时间轴
|
|
928
|
+
|
|
929
|
+
**组件名称**: `<ns-timeline>`
|
|
930
|
+
|
|
931
|
+
**用途**: 展示时间流信息
|
|
932
|
+
|
|
933
|
+
**Props**:
|
|
934
|
+
|
|
935
|
+
| 属性名 | 类型 | 默认值 | 说明 |
|
|
936
|
+
|--------|------|--------|------|
|
|
937
|
+
| `items` | `TimelineItem[]` | `[]` | 时间轴数据 |
|
|
938
|
+
|
|
939
|
+
**示例**:
|
|
940
|
+
|
|
941
|
+
```vue
|
|
942
|
+
<ns-timeline
|
|
943
|
+
:items="[
|
|
944
|
+
{ time: '2024-01-01 10:00', content: '订单创建' },
|
|
945
|
+
{ time: '2024-01-01 12:00', content: '商家接单' },
|
|
946
|
+
{ time: '2024-01-01 14:00', content: '配送中' },
|
|
947
|
+
{ time: '2024-01-01 15:30', content: '订单完成' }
|
|
948
|
+
]"
|
|
949
|
+
/>
|
|
950
|
+
```
|
|
951
|
+
|
|
952
|
+
---
|
|
953
|
+
|
|
954
|
+
### 5. Facts 事实列表
|
|
955
|
+
|
|
956
|
+
**组件名称**: `<ns-facts>`
|
|
957
|
+
|
|
958
|
+
**用途**: 展示键值对信息(详情页常用)
|
|
959
|
+
|
|
960
|
+
**示例**:
|
|
961
|
+
|
|
962
|
+
```vue
|
|
963
|
+
<ns-facts>
|
|
964
|
+
<ns-facts-item label="订单号" value="202401010001" />
|
|
965
|
+
<ns-facts-item label="下单时间" value="2024-01-01 10:00" />
|
|
966
|
+
<ns-facts-item label="支付方式" value="微信支付" />
|
|
967
|
+
<ns-facts-item label="配送地址" value="北京市朝阳区..." />
|
|
968
|
+
</ns-facts>
|
|
969
|
+
```
|
|
970
|
+
|
|
971
|
+
---
|
|
972
|
+
|
|
973
|
+
### 6. Skeleton 骨架屏
|
|
974
|
+
|
|
975
|
+
**组件名称**: `<ns-skeleton>`
|
|
976
|
+
|
|
977
|
+
**用途**: 加载状态占位
|
|
978
|
+
|
|
979
|
+
**Props**:
|
|
980
|
+
|
|
981
|
+
| 属性名 | 类型 | 默认值 | 说明 |
|
|
982
|
+
|--------|------|--------|------|
|
|
983
|
+
| `loading` | `boolean` | `true` | 是否显示骨架屏 |
|
|
984
|
+
| `rows` | `number` | `3` | 骨架屏行数 |
|
|
985
|
+
| `animated` | `boolean` | `true` | 是否显示动画 |
|
|
986
|
+
|
|
987
|
+
**示例**:
|
|
988
|
+
|
|
989
|
+
```vue
|
|
990
|
+
<ns-skeleton :loading="loading" :rows="5">
|
|
991
|
+
<div v-if="!loading">
|
|
992
|
+
<!-- 实际内容 -->
|
|
993
|
+
</div>
|
|
994
|
+
</ns-skeleton>
|
|
995
|
+
```
|
|
996
|
+
|
|
997
|
+
---
|
|
998
|
+
|
|
999
|
+
### 7. Preview 图片预览
|
|
1000
|
+
|
|
1001
|
+
**组件名称**: `<ns-preview>`
|
|
1002
|
+
|
|
1003
|
+
**用途**: 图片预览(点击放大查看)
|
|
1004
|
+
|
|
1005
|
+
**Props**:
|
|
1006
|
+
|
|
1007
|
+
| 属性名 | 类型 | 默认值 | 说明 |
|
|
1008
|
+
|--------|------|--------|------|
|
|
1009
|
+
| `images` | `string[]` | - | 图片列表 |
|
|
1010
|
+
| `current` | `number` | `0` | 当前显示的图片索引 |
|
|
1011
|
+
|
|
1012
|
+
**示例**:
|
|
1013
|
+
|
|
1014
|
+
```vue
|
|
1015
|
+
<ns-preview
|
|
1016
|
+
:images="[
|
|
1017
|
+
'/image1.jpg',
|
|
1018
|
+
'/image2.jpg',
|
|
1019
|
+
'/image3.jpg'
|
|
1020
|
+
]"
|
|
1021
|
+
:current="0"
|
|
1022
|
+
/>
|
|
1023
|
+
```
|
|
1024
|
+
|
|
1025
|
+
---
|
|
1026
|
+
|
|
1027
|
+
### 8. Watermark 水印
|
|
1028
|
+
|
|
1029
|
+
**组件名称**: `<ns-watermark>`
|
|
1030
|
+
|
|
1031
|
+
**用途**: 为页面添加水印
|
|
1032
|
+
|
|
1033
|
+
**Props**:
|
|
1034
|
+
|
|
1035
|
+
| 属性名 | 类型 | 默认值 | 说明 |
|
|
1036
|
+
|--------|------|--------|------|
|
|
1037
|
+
| `content` | `string` | - | 水印文字 |
|
|
1038
|
+
| `rotate` | `number` | `-22` | 旋转角度 |
|
|
1039
|
+
| `zIndex` | `number` | `1000` | 层级 |
|
|
1040
|
+
|
|
1041
|
+
**示例**:
|
|
1042
|
+
|
|
1043
|
+
```vue
|
|
1044
|
+
<ns-watermark content="内部资料">
|
|
1045
|
+
<div>页面内容</div>
|
|
1046
|
+
</ns-watermark>
|
|
1047
|
+
```
|
|
1048
|
+
|
|
1049
|
+
---
|
|
1050
|
+
|
|
1051
|
+
## 反馈组件
|
|
1052
|
+
|
|
1053
|
+
### 1. Dialog 对话框
|
|
1054
|
+
|
|
1055
|
+
**组件名称**: `<ns-dialog>`
|
|
1056
|
+
|
|
1057
|
+
**用途**: 模态对话框
|
|
1058
|
+
|
|
1059
|
+
**Props**:
|
|
1060
|
+
|
|
1061
|
+
| 属性名 | 类型 | 默认值 | 说明 |
|
|
1062
|
+
|--------|------|--------|------|
|
|
1063
|
+
| `modelValue` | `boolean` | - | 是否显示 |
|
|
1064
|
+
| `title` | `string` | - | 对话框标题 |
|
|
1065
|
+
| `okText` | `string` | `'确定'` | 确定按钮文字 |
|
|
1066
|
+
| `cancelText` | `string` | `'取消'` | 取消按钮文字 |
|
|
1067
|
+
| `footer` | `boolean` | `true` | 是否显示底部 |
|
|
1068
|
+
| `closeOnClickOverlay` | `boolean` | `true` | 点击遮罩是否关闭 |
|
|
1069
|
+
|
|
1070
|
+
**Events**:
|
|
1071
|
+
|
|
1072
|
+
| 事件名 | 参数 | 说明 |
|
|
1073
|
+
|--------|------|------|
|
|
1074
|
+
| `ok` | `()` | 点击确定 |
|
|
1075
|
+
| `close` | `()` | 关闭对话框 |
|
|
1076
|
+
|
|
1077
|
+
**示例**:
|
|
1078
|
+
|
|
1079
|
+
```vue
|
|
1080
|
+
<template>
|
|
1081
|
+
<ns-button label="打开对话框" @click="visible = true" />
|
|
1082
|
+
|
|
1083
|
+
<ns-dialog
|
|
1084
|
+
v-model="visible"
|
|
1085
|
+
title="提示"
|
|
1086
|
+
@ok="handleOk"
|
|
1087
|
+
>
|
|
1088
|
+
<p>确定要执行此操作吗?</p>
|
|
1089
|
+
</ns-dialog>
|
|
1090
|
+
</template>
|
|
1091
|
+
|
|
1092
|
+
<script setup>
|
|
1093
|
+
import { ref } from 'vue'
|
|
1094
|
+
|
|
1095
|
+
const visible = ref(false)
|
|
1096
|
+
|
|
1097
|
+
const handleOk = () => {
|
|
1098
|
+
// 处理确定逻辑
|
|
1099
|
+
visible.value = false
|
|
1100
|
+
}
|
|
1101
|
+
</script>
|
|
1102
|
+
```
|
|
1103
|
+
|
|
1104
|
+
---
|
|
1105
|
+
|
|
1106
|
+
### 2. Sheet 底部弹出层
|
|
1107
|
+
|
|
1108
|
+
**组件名称**: `<ns-sheet>`
|
|
1109
|
+
|
|
1110
|
+
**用途**: 从底部弹出的操作菜单
|
|
1111
|
+
|
|
1112
|
+
**Props**:
|
|
1113
|
+
|
|
1114
|
+
| 属性名 | 类型 | 默认值 | 说明 |
|
|
1115
|
+
|--------|------|--------|------|
|
|
1116
|
+
| `modelValue` | `boolean` | - | 是否显示 |
|
|
1117
|
+
| `title` | `string` | - | 标题 |
|
|
1118
|
+
| `items` | `SheetItem[]` | - | 菜单项 |
|
|
1119
|
+
|
|
1120
|
+
**Events**:
|
|
1121
|
+
|
|
1122
|
+
| 事件名 | 参数 | 说明 |
|
|
1123
|
+
|--------|------|------|
|
|
1124
|
+
| `select` | `(item: SheetItem)` | 选择菜单项 |
|
|
1125
|
+
|
|
1126
|
+
**示例**:
|
|
1127
|
+
|
|
1128
|
+
```vue
|
|
1129
|
+
<ns-sheet
|
|
1130
|
+
v-model="sheetVisible"
|
|
1131
|
+
title="选择操作"
|
|
1132
|
+
:items="[
|
|
1133
|
+
{ text: '拍照', value: 'camera' },
|
|
1134
|
+
{ text: '从相册选择', value: 'album' },
|
|
1135
|
+
{ text: '取消', value: 'cancel' }
|
|
1136
|
+
]"
|
|
1137
|
+
@select="handleSelect"
|
|
1138
|
+
/>
|
|
1139
|
+
```
|
|
1140
|
+
|
|
1141
|
+
---
|
|
1142
|
+
|
|
1143
|
+
### 3. Popover 气泡弹出框
|
|
1144
|
+
|
|
1145
|
+
**组件名称**: `<ns-popover>`
|
|
1146
|
+
|
|
1147
|
+
**用途**: 气泡式提示
|
|
1148
|
+
|
|
1149
|
+
**Props**:
|
|
1150
|
+
|
|
1151
|
+
| 属性名 | 类型 | 默认值 | 说明 |
|
|
1152
|
+
|--------|------|--------|------|
|
|
1153
|
+
| `content` | `string` | - | 显示内容 |
|
|
1154
|
+
| `trigger` | `'click'\|'manual'` | `'click'` | 触发方式 |
|
|
1155
|
+
| `placement` | `'top'\|'bottom'\|'left'\|'right'` | `'bottom'` | 弹出位置 |
|
|
1156
|
+
|
|
1157
|
+
**示例**:
|
|
1158
|
+
|
|
1159
|
+
```vue
|
|
1160
|
+
<ns-popover content="这是提示信息" placement="top">
|
|
1161
|
+
<ns-button label="点击查看" />
|
|
1162
|
+
</ns-popover>
|
|
1163
|
+
```
|
|
1164
|
+
|
|
1165
|
+
---
|
|
1166
|
+
|
|
1167
|
+
### 4. Loading 加载
|
|
1168
|
+
|
|
1169
|
+
**组件名称**: `<ns-loading>`
|
|
1170
|
+
|
|
1171
|
+
**用途**: 局部加载状态
|
|
1172
|
+
|
|
1173
|
+
**Props**:
|
|
1174
|
+
|
|
1175
|
+
| 属性名 | 类型 | 默认值 | 说明 |
|
|
1176
|
+
|--------|------|--------|------|
|
|
1177
|
+
| `visible` | `boolean` | `true` | 是否显示 |
|
|
1178
|
+
| `tip` | `string` | - | 提示文字 |
|
|
1179
|
+
| `size` | `Size` | `'md'` | 加载图标大小 |
|
|
1180
|
+
|
|
1181
|
+
**示例**:
|
|
1182
|
+
|
|
1183
|
+
```vue
|
|
1184
|
+
<ns-loading :visible="loading" tip="加载中..." />
|
|
1185
|
+
```
|
|
1186
|
+
|
|
1187
|
+
---
|
|
1188
|
+
|
|
1189
|
+
### 5. Drawer 抽屉
|
|
1190
|
+
|
|
1191
|
+
**组件名称**: `<ns-drawer>`
|
|
1192
|
+
|
|
1193
|
+
**用途**: 从侧边滑出的抽屉面板
|
|
1194
|
+
|
|
1195
|
+
**Props**:
|
|
1196
|
+
|
|
1197
|
+
| 属性名 | 类型 | 默认值 | 说明 |
|
|
1198
|
+
|--------|------|--------|------|
|
|
1199
|
+
| `modelValue` | `boolean` | - | 是否显示 |
|
|
1200
|
+
| `title` | `string` | - | 抽屉标题 |
|
|
1201
|
+
| `placement` | `'left'\|'right'\|'top'\|'bottom'` | `'right'` | 抽屉方向 |
|
|
1202
|
+
| `height` | `string` | `'60%'` | 高度(bottom/top时) |
|
|
1203
|
+
|
|
1204
|
+
**示例**:
|
|
1205
|
+
|
|
1206
|
+
```vue
|
|
1207
|
+
<ns-drawer
|
|
1208
|
+
v-model="drawerVisible"
|
|
1209
|
+
title="筛选"
|
|
1210
|
+
placement="bottom"
|
|
1211
|
+
height="70%"
|
|
1212
|
+
>
|
|
1213
|
+
<!-- 筛选内容 -->
|
|
1214
|
+
</ns-drawer>
|
|
1215
|
+
```
|
|
1216
|
+
|
|
1217
|
+
---
|
|
1218
|
+
|
|
1219
|
+
## 布局组件
|
|
1220
|
+
|
|
1221
|
+
### 1. Row / Column 弹性布局
|
|
1222
|
+
|
|
1223
|
+
**组件名称**: `<ns-row>` / `<ns-column>`
|
|
1224
|
+
|
|
1225
|
+
**用途**: Flex 布局容器
|
|
1226
|
+
|
|
1227
|
+
**Props**:
|
|
1228
|
+
|
|
1229
|
+
| 属性名 | 类型 | 默认值 | 说明 |
|
|
1230
|
+
|--------|------|--------|------|
|
|
1231
|
+
| `gap` | `Size\|number` | - | 子元素间距 |
|
|
1232
|
+
| `justify` | `'start'\|'center'\|'end'\|'between'\|'around'` | - | 主轴对齐方式 |
|
|
1233
|
+
| `align` | `'start'\|'center'\|'end'\|'stretch'` | - | 交叉轴对齐方式 |
|
|
1234
|
+
| `wrap` | `boolean` | `false` | 是否换行 |
|
|
1235
|
+
|
|
1236
|
+
**示例**:
|
|
1237
|
+
|
|
1238
|
+
```vue
|
|
1239
|
+
<!-- 水平排列 -->
|
|
1240
|
+
<ns-row gap="md" justify="between" align="center">
|
|
1241
|
+
<ns-button label="按钮1" />
|
|
1242
|
+
<ns-button label="按钮2" />
|
|
1243
|
+
<ns-button label="按钮3" />
|
|
1244
|
+
</ns-row>
|
|
1245
|
+
|
|
1246
|
+
<!-- 垂直排列 -->
|
|
1247
|
+
<ns-column gap="lg">
|
|
1248
|
+
<ns-card title="卡片1" />
|
|
1249
|
+
<ns-card title="卡片2" />
|
|
1250
|
+
<ns-card title="卡片3" />
|
|
1251
|
+
</ns-column>
|
|
1252
|
+
```
|
|
1253
|
+
|
|
1254
|
+
---
|
|
1255
|
+
|
|
1256
|
+
### 2. Grid 网格
|
|
1257
|
+
|
|
1258
|
+
**组件名称**: `<ns-grid>`
|
|
1259
|
+
|
|
1260
|
+
**用途**: Grid 布局容器
|
|
1261
|
+
|
|
1262
|
+
**Props**:
|
|
1263
|
+
|
|
1264
|
+
| 属性名 | 类型 | 默认值 | 说明 |
|
|
1265
|
+
|--------|------|--------|------|
|
|
1266
|
+
| `columns` | `number` | `4` | 列数 |
|
|
1267
|
+
| `gap` | `Size\|number` | - | 间距 |
|
|
1268
|
+
|
|
1269
|
+
**示例**:
|
|
1270
|
+
|
|
1271
|
+
```vue
|
|
1272
|
+
<ns-grid :columns="3" gap="md">
|
|
1273
|
+
<div v-for="i in 9" :key="i">
|
|
1274
|
+
<ns-button :label="`按钮${i}`" block />
|
|
1275
|
+
</div>
|
|
1276
|
+
</ns-grid>
|
|
1277
|
+
```
|
|
1278
|
+
|
|
1279
|
+
---
|
|
1280
|
+
|
|
1281
|
+
### 3. Scrollable 滚动容器
|
|
1282
|
+
|
|
1283
|
+
**组件名称**: `<ns-scrollable>`
|
|
1284
|
+
|
|
1285
|
+
**用途**: 可滚动区域(支持下拉刷新)
|
|
1286
|
+
|
|
1287
|
+
**Props**:
|
|
1288
|
+
|
|
1289
|
+
| 属性名 | 类型 | 默认值 | 说明 |
|
|
1290
|
+
|--------|------|--------|------|
|
|
1291
|
+
| `height` | `string` | - | 容器高度 |
|
|
1292
|
+
| `refreshable` | `boolean` | `false` | 是否支持下拉刷新 |
|
|
1293
|
+
|
|
1294
|
+
**Events**:
|
|
1295
|
+
|
|
1296
|
+
| 事件名 | 参数 | 说明 |
|
|
1297
|
+
|--------|------|------|
|
|
1298
|
+
| `refresh` | `()` | 下拉刷新 |
|
|
1299
|
+
| `scrollEnd` | `()` | 滚动到底部 |
|
|
1300
|
+
|
|
1301
|
+
**示例**:
|
|
1302
|
+
|
|
1303
|
+
```vue
|
|
1304
|
+
<ns-scrollable
|
|
1305
|
+
height="100vh"
|
|
1306
|
+
refreshable
|
|
1307
|
+
@refresh="handleRefresh"
|
|
1308
|
+
@scroll-end="handleScrollEnd"
|
|
1309
|
+
>
|
|
1310
|
+
<div v-for="item in items" :key="item.id">
|
|
1311
|
+
{{ item.content }}
|
|
1312
|
+
</div>
|
|
1313
|
+
</ns-scrollable>
|
|
1314
|
+
```
|
|
1315
|
+
|
|
1316
|
+
---
|
|
1317
|
+
|
|
1318
|
+
### 4. Divider 分割线
|
|
1319
|
+
|
|
1320
|
+
**组件名称**: `<ns-divider>`
|
|
1321
|
+
|
|
1322
|
+
**用途**: 分隔内容
|
|
1323
|
+
|
|
1324
|
+
**Props**:
|
|
1325
|
+
|
|
1326
|
+
| 属性名 | 类型 | 默认值 | 说明 |
|
|
1327
|
+
|--------|------|--------|------|
|
|
1328
|
+
| `dashed` | `boolean` | `false` | 是否虚线 |
|
|
1329
|
+
| `hairline` | `boolean` | `true` | 是否细线(0.5px) |
|
|
1330
|
+
|
|
1331
|
+
**示例**:
|
|
1332
|
+
|
|
1333
|
+
```vue
|
|
1334
|
+
<ns-divider />
|
|
1335
|
+
<ns-divider dashed />
|
|
1336
|
+
```
|
|
1337
|
+
|
|
1338
|
+
---
|
|
1339
|
+
|
|
1340
|
+
## 导航组件
|
|
1341
|
+
|
|
1342
|
+
### 1. Tabbar 标签栏
|
|
1343
|
+
|
|
1344
|
+
**组件名称**: `<ns-tabbar>`
|
|
1345
|
+
|
|
1346
|
+
**用途**: 底部导航栏
|
|
1347
|
+
|
|
1348
|
+
**Props**:
|
|
1349
|
+
|
|
1350
|
+
| 属性名 | 类型 | 默认值 | 说明 |
|
|
1351
|
+
|--------|------|--------|------|
|
|
1352
|
+
| `modelValue` | `string\|number` | - | 当前激活的标签 |
|
|
1353
|
+
| `items` | `TabbarItem[]` | - | 标签项数据 |
|
|
1354
|
+
| `fixed` | `boolean` | `true` | 是否固定在底部 |
|
|
1355
|
+
| `safeAreaInsetBottom` | `boolean` | `true` | 是否开启底部安全区适配 |
|
|
1356
|
+
|
|
1357
|
+
**标签项数据格式**:
|
|
1358
|
+
|
|
1359
|
+
```typescript
|
|
1360
|
+
type TabbarItem = {
|
|
1361
|
+
text: string
|
|
1362
|
+
value: string | number
|
|
1363
|
+
icon?: string
|
|
1364
|
+
badge?: string | number
|
|
1365
|
+
}
|
|
1366
|
+
```
|
|
1367
|
+
|
|
1368
|
+
**示例**:
|
|
1369
|
+
|
|
1370
|
+
```vue
|
|
1371
|
+
<template>
|
|
1372
|
+
<ns-tabbar v-model="activeTab" :items="tabbarItems" />
|
|
1373
|
+
</template>
|
|
1374
|
+
|
|
1375
|
+
<script setup>
|
|
1376
|
+
import { ref } from 'vue'
|
|
1377
|
+
|
|
1378
|
+
const activeTab = ref('home')
|
|
1379
|
+
const tabbarItems = [
|
|
1380
|
+
{ text: '首页', value: 'home', icon: 'home' },
|
|
1381
|
+
{ text: '分类', value: 'category', icon: 'category' },
|
|
1382
|
+
{ text: '购物车', value: 'cart', icon: 'cart', badge: 5 },
|
|
1383
|
+
{ text: '我的', value: 'mine', icon: 'user' }
|
|
1384
|
+
]
|
|
1385
|
+
</script>
|
|
1386
|
+
```
|
|
1387
|
+
|
|
1388
|
+
---
|
|
1389
|
+
|
|
1390
|
+
### 2. Tabs 标签页
|
|
1391
|
+
|
|
1392
|
+
**组件名称**: `<ns-tabs>`
|
|
1393
|
+
|
|
1394
|
+
**用途**: 选项卡切换
|
|
1395
|
+
|
|
1396
|
+
**Props**:
|
|
1397
|
+
|
|
1398
|
+
| 属性名 | 类型 | 默认值 | 说明 |
|
|
1399
|
+
|--------|------|--------|------|
|
|
1400
|
+
| `modelValue` | `string\|number` | - | 当前激活的标签 |
|
|
1401
|
+
| `items` | `TabsItem[]` | - | 标签项数据 |
|
|
1402
|
+
| `variant` | `'line'\|'card'\|'button'` | `'line'` | 标签样式 |
|
|
1403
|
+
| `swipeable` | `boolean` | `false` | 是否开启手势滑动切换 |
|
|
1404
|
+
| `sticky` | `boolean` | `false` | 是否吸顶 |
|
|
1405
|
+
|
|
1406
|
+
**示例**:
|
|
1407
|
+
|
|
1408
|
+
```vue
|
|
1409
|
+
<ns-tabs
|
|
1410
|
+
v-model="activeTab"
|
|
1411
|
+
:items="[
|
|
1412
|
+
{ text: '全部', value: 'all' },
|
|
1413
|
+
{ text: '待付款', value: 'unpaid' },
|
|
1414
|
+
{ text: '待发货', value: 'unshipped' },
|
|
1415
|
+
{ text: '已完成', value: 'finished' }
|
|
1416
|
+
]"
|
|
1417
|
+
swipeable
|
|
1418
|
+
sticky
|
|
1419
|
+
>
|
|
1420
|
+
<ns-tabs-item value="all">
|
|
1421
|
+
<!-- 全部订单内容 -->
|
|
1422
|
+
</ns-tabs-item>
|
|
1423
|
+
<ns-tabs-item value="unpaid">
|
|
1424
|
+
<!-- 待付款订单内容 -->
|
|
1425
|
+
</ns-tabs-item>
|
|
1426
|
+
<!-- ... -->
|
|
1427
|
+
</ns-tabs>
|
|
1428
|
+
```
|
|
1429
|
+
|
|
1430
|
+
---
|
|
1431
|
+
|
|
1432
|
+
### 3. Pagination 分页
|
|
1433
|
+
|
|
1434
|
+
**组件名称**: `<ns-pagination>`
|
|
1435
|
+
|
|
1436
|
+
**用途**: 分页导航(移动端简化版)
|
|
1437
|
+
|
|
1438
|
+
**Props**:
|
|
1439
|
+
|
|
1440
|
+
| 属性名 | 类型 | 默认值 | 说明 |
|
|
1441
|
+
|--------|------|--------|------|
|
|
1442
|
+
| `modelValue` | `number` | - | 当前页码 |
|
|
1443
|
+
| `total` | `number` | - | 总页数 |
|
|
1444
|
+
|
|
1445
|
+
**示例**:
|
|
1446
|
+
|
|
1447
|
+
```vue
|
|
1448
|
+
<ns-pagination
|
|
1449
|
+
v-model="currentPage"
|
|
1450
|
+
:total="10"
|
|
1451
|
+
@change="handlePageChange"
|
|
1452
|
+
/>
|
|
1453
|
+
```
|
|
1454
|
+
|
|
1455
|
+
---
|
|
1456
|
+
|
|
1457
|
+
## 通用属性
|
|
1458
|
+
|
|
1459
|
+
### 尺寸(Size)
|
|
1460
|
+
|
|
1461
|
+
| 值 | 说明 | 移动端常用场景 |
|
|
1462
|
+
|----|------|----------------|
|
|
1463
|
+
| `'xs'` | 超小 | 小图标、小标签 |
|
|
1464
|
+
| `'sm'` | 小 | 次要按钮、小卡片 |
|
|
1465
|
+
| `'md'` | 中等(默认) | 主按钮、标准组件 |
|
|
1466
|
+
| `'lg'` | 大 | 大按钮、大卡片 |
|
|
1467
|
+
| `'xl'` | 超大 | 重要操作按钮 |
|
|
1468
|
+
|
|
1469
|
+
---
|
|
1470
|
+
|
|
1471
|
+
### 颜色(Color)
|
|
1472
|
+
|
|
1473
|
+
| 值 | 说明 | 适用场景 |
|
|
1474
|
+
|----|------|----------|
|
|
1475
|
+
| `'primary'` | 主色 | 主要操作、强调 |
|
|
1476
|
+
| `'success'` | 成功色 | 成功提示、完成状态 |
|
|
1477
|
+
| `'warning'` | 警告色 | 警告提示、待处理 |
|
|
1478
|
+
| `'danger'` | 危险色 | 删除、错误提示 |
|
|
1479
|
+
| `'info'` | 信息色 | 一般信息提示 |
|
|
1480
|
+
|
|
1481
|
+
---
|
|
1482
|
+
|
|
1483
|
+
## 服务方法
|
|
1484
|
+
|
|
1485
|
+
### 1. Toast 轻提示
|
|
1486
|
+
|
|
1487
|
+
**方法**: `$n.toast(message, options?)`
|
|
1488
|
+
|
|
1489
|
+
**参数**:
|
|
1490
|
+
|
|
1491
|
+
```typescript
|
|
1492
|
+
type ToastOptions = {
|
|
1493
|
+
type?: 'info' | 'success' | 'error' | 'warning'
|
|
1494
|
+
duration?: number // 持续时间(秒),默认2秒
|
|
1495
|
+
position?: 'top' | 'center' | 'bottom'
|
|
1496
|
+
}
|
|
1497
|
+
```
|
|
1498
|
+
|
|
1499
|
+
**示例**:
|
|
1500
|
+
|
|
1501
|
+
```javascript
|
|
1502
|
+
// 普通提示
|
|
1503
|
+
$n.toast('操作成功')
|
|
1504
|
+
|
|
1505
|
+
// 成功提示
|
|
1506
|
+
$n.toast('保存成功', { type: 'success' })
|
|
1507
|
+
|
|
1508
|
+
// 错误提示
|
|
1509
|
+
$n.toast('操作失败', { type: 'error' })
|
|
1510
|
+
|
|
1511
|
+
// 长时间提示
|
|
1512
|
+
$n.toast('提交中,请稍候...', { duration: 5 })
|
|
1513
|
+
```
|
|
1514
|
+
|
|
1515
|
+
---
|
|
1516
|
+
|
|
1517
|
+
### 2. Loading 全局加载
|
|
1518
|
+
|
|
1519
|
+
**方法**:
|
|
1520
|
+
- `$n.loading.show(message?)` - 显示加载
|
|
1521
|
+
- `$n.loading.hide()` - 隐藏加载
|
|
1522
|
+
|
|
1523
|
+
**示例**:
|
|
1524
|
+
|
|
1525
|
+
```javascript
|
|
1526
|
+
// 显示加载
|
|
1527
|
+
$n.loading.show('加载中...')
|
|
1528
|
+
|
|
1529
|
+
// 异步操作
|
|
1530
|
+
await fetchData()
|
|
1531
|
+
|
|
1532
|
+
// 隐藏加载
|
|
1533
|
+
$n.loading.hide()
|
|
1534
|
+
```
|
|
1535
|
+
|
|
1536
|
+
---
|
|
1537
|
+
|
|
1538
|
+
### 3. Dialog 对话框
|
|
1539
|
+
|
|
1540
|
+
**方法**: `$n.dialog(options)`
|
|
1541
|
+
|
|
1542
|
+
**示例**:
|
|
1543
|
+
|
|
1544
|
+
```javascript
|
|
1545
|
+
$n.dialog({
|
|
1546
|
+
title: '提示',
|
|
1547
|
+
content: '确定要删除吗?',
|
|
1548
|
+
onOk: () => {
|
|
1549
|
+
// 确定操作
|
|
1550
|
+
}
|
|
1551
|
+
})
|
|
1552
|
+
```
|
|
1553
|
+
|
|
1554
|
+
---
|
|
1555
|
+
|
|
1556
|
+
### 4. Confirm 确认框
|
|
1557
|
+
|
|
1558
|
+
**方法**: `$n.confirm(message, onOk)`
|
|
1559
|
+
|
|
1560
|
+
**示例**:
|
|
1561
|
+
|
|
1562
|
+
```javascript
|
|
1563
|
+
$n.confirm('确定要退出登录吗?', () => {
|
|
1564
|
+
// 退出登录
|
|
1565
|
+
logout()
|
|
1566
|
+
})
|
|
1567
|
+
```
|
|
1568
|
+
|
|
1569
|
+
---
|
|
1570
|
+
|
|
1571
|
+
### 5. Sheet 底部弹出层
|
|
1572
|
+
|
|
1573
|
+
**方法**: `$n.sheet.open(options)`
|
|
1574
|
+
|
|
1575
|
+
**示例**:
|
|
1576
|
+
|
|
1577
|
+
```javascript
|
|
1578
|
+
$n.sheet.open({
|
|
1579
|
+
title: '选择操作',
|
|
1580
|
+
items: [
|
|
1581
|
+
{ text: '编辑', value: 'edit' },
|
|
1582
|
+
{ text: '删除', value: 'delete' },
|
|
1583
|
+
{ text: '取消', value: 'cancel' }
|
|
1584
|
+
],
|
|
1585
|
+
onSelect: (item) => {
|
|
1586
|
+
if (item.value === 'edit') {
|
|
1587
|
+
// 编辑操作
|
|
1588
|
+
}
|
|
1589
|
+
}
|
|
1590
|
+
})
|
|
1591
|
+
```
|
|
1592
|
+
|
|
1593
|
+
---
|
|
1594
|
+
|
|
1595
|
+
## 移动端特性
|
|
1596
|
+
|
|
1597
|
+
### 1. 安全区域适配
|
|
1598
|
+
|
|
1599
|
+
在 iPhone X 等设备上,组件会自动适配安全区域(刘海屏、底部横条)。
|
|
1600
|
+
|
|
1601
|
+
```vue
|
|
1602
|
+
<!-- Tabbar 自动适配底部安全区 -->
|
|
1603
|
+
<ns-tabbar
|
|
1604
|
+
:items="tabbarItems"
|
|
1605
|
+
safe-area-inset-bottom
|
|
1606
|
+
/>
|
|
1607
|
+
```
|
|
1608
|
+
|
|
1609
|
+
---
|
|
1610
|
+
|
|
1611
|
+
### 2. 触摸反馈
|
|
1612
|
+
|
|
1613
|
+
移动端组件支持触摸反馈效果,提供更好的交互体验。
|
|
1614
|
+
|
|
1615
|
+
```vue
|
|
1616
|
+
<!-- 按钮支持触摸高亮 -->
|
|
1617
|
+
<ns-button label="点击我" />
|
|
1618
|
+
```
|
|
1619
|
+
|
|
1620
|
+
---
|
|
1621
|
+
|
|
1622
|
+
### 3. 手势操作
|
|
1623
|
+
|
|
1624
|
+
支持常见的移动端手势:
|
|
1625
|
+
|
|
1626
|
+
- **滑动**: Tabs 可左右滑动切换
|
|
1627
|
+
- **下拉刷新**: List、Scrollable 支持下拉刷新
|
|
1628
|
+
- **上拉加载**: List 支持上拉加载更多
|
|
1629
|
+
|
|
1630
|
+
---
|
|
1631
|
+
|
|
1632
|
+
### 4. 底部弹出选择器
|
|
1633
|
+
|
|
1634
|
+
移动端的 Select、DateSelect 等组件会从底部弹出选择器,符合移动端交互习惯。
|
|
1635
|
+
|
|
1636
|
+
```vue
|
|
1637
|
+
<ns-select
|
|
1638
|
+
v-model="city"
|
|
1639
|
+
:options="cityOptions"
|
|
1640
|
+
placeholder="选择城市"
|
|
1641
|
+
/>
|
|
1642
|
+
<!-- 点击后从底部弹出选择器 -->
|
|
1643
|
+
```
|
|
1644
|
+
|
|
1645
|
+
---
|
|
1646
|
+
|
|
1647
|
+
### 5. 虚拟列表
|
|
1648
|
+
|
|
1649
|
+
对于长列表,使用虚拟滚动提升性能:
|
|
1650
|
+
|
|
1651
|
+
```vue
|
|
1652
|
+
<ns-list
|
|
1653
|
+
:data="longList"
|
|
1654
|
+
virtual
|
|
1655
|
+
:item-height="60"
|
|
1656
|
+
/>
|
|
1657
|
+
```
|
|
1658
|
+
|
|
1659
|
+
---
|
|
1660
|
+
|
|
1661
|
+
## 最佳实践
|
|
1662
|
+
|
|
1663
|
+
### 1. 移动端表单设计
|
|
1664
|
+
|
|
1665
|
+
```vue
|
|
1666
|
+
<template>
|
|
1667
|
+
<ns-page>
|
|
1668
|
+
<ns-page-header title="用户信息" />
|
|
1669
|
+
|
|
1670
|
+
<ns-page-content>
|
|
1671
|
+
<ns-form v-model="formData" ref="formRef">
|
|
1672
|
+
<ns-input
|
|
1673
|
+
name="name"
|
|
1674
|
+
label="姓名"
|
|
1675
|
+
:rules="['required']"
|
|
1676
|
+
placeholder="请输入姓名"
|
|
1677
|
+
/>
|
|
1678
|
+
|
|
1679
|
+
<ns-mobile-input
|
|
1680
|
+
name="phone"
|
|
1681
|
+
label="手机号"
|
|
1682
|
+
:rules="['required', 'mobile']"
|
|
1683
|
+
placeholder="请输入手机号"
|
|
1684
|
+
/>
|
|
1685
|
+
|
|
1686
|
+
<ns-select
|
|
1687
|
+
name="city"
|
|
1688
|
+
label="城市"
|
|
1689
|
+
:options="cityOptions"
|
|
1690
|
+
:rules="['required']"
|
|
1691
|
+
placeholder="请选择城市"
|
|
1692
|
+
/>
|
|
1693
|
+
|
|
1694
|
+
<ns-date-select
|
|
1695
|
+
name="birthDate"
|
|
1696
|
+
label="出生日期"
|
|
1697
|
+
/>
|
|
1698
|
+
|
|
1699
|
+
<ns-textarea
|
|
1700
|
+
name="remark"
|
|
1701
|
+
label="备注"
|
|
1702
|
+
:rows="4"
|
|
1703
|
+
placeholder="请输入备注"
|
|
1704
|
+
/>
|
|
1705
|
+
</ns-form>
|
|
1706
|
+
</ns-page-content>
|
|
1707
|
+
|
|
1708
|
+
<ns-page-footer>
|
|
1709
|
+
<ns-button
|
|
1710
|
+
label="提交"
|
|
1711
|
+
color="primary"
|
|
1712
|
+
block
|
|
1713
|
+
@click="handleSubmit"
|
|
1714
|
+
/>
|
|
1715
|
+
</ns-page-footer>
|
|
1716
|
+
</ns-page>
|
|
1717
|
+
</template>
|
|
1718
|
+
|
|
1719
|
+
<script setup>
|
|
1720
|
+
import { ref } from 'vue'
|
|
1721
|
+
import { useNutshell } from '@uxda/nutshell/taro'
|
|
1722
|
+
|
|
1723
|
+
const $n = useNutshell()
|
|
1724
|
+
const formRef = ref()
|
|
1725
|
+
const formData = ref({
|
|
1726
|
+
name: '',
|
|
1727
|
+
phone: '',
|
|
1728
|
+
city: '',
|
|
1729
|
+
birthDate: '',
|
|
1730
|
+
remark: ''
|
|
1731
|
+
})
|
|
1732
|
+
|
|
1733
|
+
const cityOptions = [
|
|
1734
|
+
{ text: '北京', value: 'beijing' },
|
|
1735
|
+
{ text: '上海', value: 'shanghai' },
|
|
1736
|
+
{ text: '深圳', value: 'shenzhen' }
|
|
1737
|
+
]
|
|
1738
|
+
|
|
1739
|
+
const handleSubmit = async () => {
|
|
1740
|
+
const valid = await formRef.value.validate()
|
|
1741
|
+
if (valid) {
|
|
1742
|
+
try {
|
|
1743
|
+
$n.loading.show('提交中...')
|
|
1744
|
+
await api.submitForm(formData.value)
|
|
1745
|
+
$n.toast('提交成功', { type: 'success' })
|
|
1746
|
+
// 返回上一页或跳转
|
|
1747
|
+
} catch (error) {
|
|
1748
|
+
$n.toast('提交失败', { type: 'error' })
|
|
1749
|
+
} finally {
|
|
1750
|
+
$n.loading.hide()
|
|
1751
|
+
}
|
|
1752
|
+
}
|
|
1753
|
+
}
|
|
1754
|
+
</script>
|
|
1755
|
+
```
|
|
1756
|
+
|
|
1757
|
+
---
|
|
1758
|
+
|
|
1759
|
+
### 2. 移动端列表页
|
|
1760
|
+
|
|
1761
|
+
```vue
|
|
1762
|
+
<template>
|
|
1763
|
+
<ns-page>
|
|
1764
|
+
<ns-page-header title="订单列表" />
|
|
1765
|
+
|
|
1766
|
+
<ns-tabs
|
|
1767
|
+
v-model="activeTab"
|
|
1768
|
+
:items="tabItems"
|
|
1769
|
+
sticky
|
|
1770
|
+
>
|
|
1771
|
+
<ns-tabs-item value="all">
|
|
1772
|
+
<ns-list
|
|
1773
|
+
:data="orders"
|
|
1774
|
+
:loading="loading"
|
|
1775
|
+
:finished="finished"
|
|
1776
|
+
refreshable
|
|
1777
|
+
loadmore
|
|
1778
|
+
@refresh="handleRefresh"
|
|
1779
|
+
@load="handleLoad"
|
|
1780
|
+
>
|
|
1781
|
+
<template #default="{ item }">
|
|
1782
|
+
<ns-card class="order-card">
|
|
1783
|
+
<ns-row justify="between" align="center">
|
|
1784
|
+
<h3>订单号:{{ item.orderNo }}</h3>
|
|
1785
|
+
<ns-chip
|
|
1786
|
+
:label="item.statusText"
|
|
1787
|
+
:color="getStatusColor(item.status)"
|
|
1788
|
+
/>
|
|
1789
|
+
</ns-row>
|
|
1790
|
+
|
|
1791
|
+
<ns-divider />
|
|
1792
|
+
|
|
1793
|
+
<ns-row gap="md" align="center">
|
|
1794
|
+
<ns-image
|
|
1795
|
+
:src="item.productImage"
|
|
1796
|
+
width="80"
|
|
1797
|
+
height="80"
|
|
1798
|
+
/>
|
|
1799
|
+
<ns-column flex="1">
|
|
1800
|
+
<p>{{ item.productName }}</p>
|
|
1801
|
+
<p class="price">¥{{ item.price }}</p>
|
|
1802
|
+
</ns-column>
|
|
1803
|
+
</ns-row>
|
|
1804
|
+
|
|
1805
|
+
<ns-divider />
|
|
1806
|
+
|
|
1807
|
+
<ns-row justify="end" gap="sm">
|
|
1808
|
+
<ns-button
|
|
1809
|
+
label="查看详情"
|
|
1810
|
+
size="sm"
|
|
1811
|
+
@click="viewDetail(item)"
|
|
1812
|
+
/>
|
|
1813
|
+
<ns-button
|
|
1814
|
+
v-if="item.canPay"
|
|
1815
|
+
label="去支付"
|
|
1816
|
+
size="sm"
|
|
1817
|
+
color="primary"
|
|
1818
|
+
@click="goPay(item)"
|
|
1819
|
+
/>
|
|
1820
|
+
</ns-row>
|
|
1821
|
+
</ns-card>
|
|
1822
|
+
</template>
|
|
1823
|
+
</ns-list>
|
|
1824
|
+
</ns-tabs-item>
|
|
1825
|
+
</ns-tabs>
|
|
1826
|
+
</ns-page>
|
|
1827
|
+
</template>
|
|
1828
|
+
|
|
1829
|
+
<script setup>
|
|
1830
|
+
import { ref, onMounted } from 'vue'
|
|
1831
|
+
|
|
1832
|
+
const activeTab = ref('all')
|
|
1833
|
+
const orders = ref([])
|
|
1834
|
+
const loading = ref(false)
|
|
1835
|
+
const finished = ref(false)
|
|
1836
|
+
const page = ref(1)
|
|
1837
|
+
|
|
1838
|
+
const tabItems = [
|
|
1839
|
+
{ text: '全部', value: 'all' },
|
|
1840
|
+
{ text: '待付款', value: 'unpaid' },
|
|
1841
|
+
{ text: '待发货', value: 'unshipped' },
|
|
1842
|
+
{ text: '已完成', value: 'finished' }
|
|
1843
|
+
]
|
|
1844
|
+
|
|
1845
|
+
const handleRefresh = async () => {
|
|
1846
|
+
page.value = 1
|
|
1847
|
+
finished.value = false
|
|
1848
|
+
await loadData()
|
|
1849
|
+
}
|
|
1850
|
+
|
|
1851
|
+
const handleLoad = async () => {
|
|
1852
|
+
page.value++
|
|
1853
|
+
await loadData()
|
|
1854
|
+
}
|
|
1855
|
+
|
|
1856
|
+
const loadData = async () => {
|
|
1857
|
+
loading.value = true
|
|
1858
|
+
try {
|
|
1859
|
+
const response = await api.getOrders({
|
|
1860
|
+
page: page.value,
|
|
1861
|
+
status: activeTab.value
|
|
1862
|
+
})
|
|
1863
|
+
|
|
1864
|
+
if (page.value === 1) {
|
|
1865
|
+
orders.value = response.data
|
|
1866
|
+
} else {
|
|
1867
|
+
orders.value.push(...response.data)
|
|
1868
|
+
}
|
|
1869
|
+
|
|
1870
|
+
finished.value = !response.hasMore
|
|
1871
|
+
} finally {
|
|
1872
|
+
loading.value = false
|
|
1873
|
+
}
|
|
1874
|
+
}
|
|
1875
|
+
|
|
1876
|
+
const getStatusColor = (status) => {
|
|
1877
|
+
const colorMap = {
|
|
1878
|
+
unpaid: 'warning',
|
|
1879
|
+
unshipped: 'info',
|
|
1880
|
+
shipped: 'primary',
|
|
1881
|
+
finished: 'success'
|
|
1882
|
+
}
|
|
1883
|
+
return colorMap[status] || 'info'
|
|
1884
|
+
}
|
|
1885
|
+
|
|
1886
|
+
const viewDetail = (order) => {
|
|
1887
|
+
// 跳转到详情页
|
|
1888
|
+
}
|
|
1889
|
+
|
|
1890
|
+
const goPay = (order) => {
|
|
1891
|
+
// 跳转到支付页
|
|
1892
|
+
}
|
|
1893
|
+
|
|
1894
|
+
onMounted(() => {
|
|
1895
|
+
loadData()
|
|
1896
|
+
})
|
|
1897
|
+
</script>
|
|
1898
|
+
|
|
1899
|
+
<style scoped>
|
|
1900
|
+
.order-card {
|
|
1901
|
+
margin-bottom: 12px;
|
|
1902
|
+
}
|
|
1903
|
+
|
|
1904
|
+
.price {
|
|
1905
|
+
color: #ff4d4f;
|
|
1906
|
+
font-size: 18px;
|
|
1907
|
+
font-weight: bold;
|
|
1908
|
+
}
|
|
1909
|
+
</style>
|
|
1910
|
+
```
|
|
1911
|
+
|
|
1912
|
+
---
|
|
1913
|
+
|
|
1914
|
+
### 3. 移动端详情页
|
|
1915
|
+
|
|
1916
|
+
```vue
|
|
1917
|
+
<template>
|
|
1918
|
+
<ns-page>
|
|
1919
|
+
<ns-page-header
|
|
1920
|
+
title="订单详情"
|
|
1921
|
+
back
|
|
1922
|
+
@back="goBack"
|
|
1923
|
+
/>
|
|
1924
|
+
|
|
1925
|
+
<ns-page-content>
|
|
1926
|
+
<!-- 订单状态 -->
|
|
1927
|
+
<ns-card>
|
|
1928
|
+
<ns-row align="center" gap="md">
|
|
1929
|
+
<ns-icon name="success" size="xl" fill="success" />
|
|
1930
|
+
<ns-column>
|
|
1931
|
+
<h2>订单已完成</h2>
|
|
1932
|
+
<p>感谢您的购买</p>
|
|
1933
|
+
</ns-column>
|
|
1934
|
+
</ns-row>
|
|
1935
|
+
</ns-card>
|
|
1936
|
+
|
|
1937
|
+
<!-- 物流信息 -->
|
|
1938
|
+
<ns-card title="物流信息">
|
|
1939
|
+
<ns-timeline :items="logisticsSteps" />
|
|
1940
|
+
</ns-card>
|
|
1941
|
+
|
|
1942
|
+
<!-- 商品信息 -->
|
|
1943
|
+
<ns-card title="商品信息">
|
|
1944
|
+
<ns-row gap="md" align="center">
|
|
1945
|
+
<ns-image
|
|
1946
|
+
:src="order.productImage"
|
|
1947
|
+
width="80"
|
|
1948
|
+
height="80"
|
|
1949
|
+
/>
|
|
1950
|
+
<ns-column flex="1">
|
|
1951
|
+
<p>{{ order.productName }}</p>
|
|
1952
|
+
<p class="price">¥{{ order.price }}</p>
|
|
1953
|
+
</ns-column>
|
|
1954
|
+
</ns-row>
|
|
1955
|
+
</ns-card>
|
|
1956
|
+
|
|
1957
|
+
<!-- 订单详情 -->
|
|
1958
|
+
<ns-card title="订单详情">
|
|
1959
|
+
<ns-facts>
|
|
1960
|
+
<ns-facts-item
|
|
1961
|
+
label="订单号"
|
|
1962
|
+
:value="order.orderNo"
|
|
1963
|
+
/>
|
|
1964
|
+
<ns-facts-item
|
|
1965
|
+
label="下单时间"
|
|
1966
|
+
:value="order.createdAt"
|
|
1967
|
+
/>
|
|
1968
|
+
<ns-facts-item
|
|
1969
|
+
label="支付方式"
|
|
1970
|
+
:value="order.paymentMethod"
|
|
1971
|
+
/>
|
|
1972
|
+
<ns-facts-item
|
|
1973
|
+
label="配送地址"
|
|
1974
|
+
:value="order.address"
|
|
1975
|
+
/>
|
|
1976
|
+
</ns-facts>
|
|
1977
|
+
</ns-card>
|
|
1978
|
+
</ns-page-content>
|
|
1979
|
+
|
|
1980
|
+
<ns-page-footer>
|
|
1981
|
+
<ns-row gap="sm">
|
|
1982
|
+
<ns-button
|
|
1983
|
+
label="联系客服"
|
|
1984
|
+
flex="1"
|
|
1985
|
+
@click="contactService"
|
|
1986
|
+
/>
|
|
1987
|
+
<ns-button
|
|
1988
|
+
label="再来一单"
|
|
1989
|
+
color="primary"
|
|
1990
|
+
flex="1"
|
|
1991
|
+
@click="reorder"
|
|
1992
|
+
/>
|
|
1993
|
+
</ns-row>
|
|
1994
|
+
</ns-page-footer>
|
|
1995
|
+
</ns-page>
|
|
1996
|
+
</template>
|
|
1997
|
+
|
|
1998
|
+
<script setup>
|
|
1999
|
+
import { ref, onMounted } from 'vue'
|
|
2000
|
+
import { useRouter } from 'vue-router'
|
|
2001
|
+
|
|
2002
|
+
const router = useRouter()
|
|
2003
|
+
const order = ref({})
|
|
2004
|
+
const logisticsSteps = ref([])
|
|
2005
|
+
|
|
2006
|
+
const goBack = () => {
|
|
2007
|
+
router.back()
|
|
2008
|
+
}
|
|
2009
|
+
|
|
2010
|
+
const contactService = () => {
|
|
2011
|
+
// 联系客服
|
|
2012
|
+
}
|
|
2013
|
+
|
|
2014
|
+
const reorder = () => {
|
|
2015
|
+
// 再来一单
|
|
2016
|
+
}
|
|
2017
|
+
|
|
2018
|
+
onMounted(async () => {
|
|
2019
|
+
// 加载订单详情
|
|
2020
|
+
})
|
|
2021
|
+
</script>
|
|
2022
|
+
```
|
|
2023
|
+
|
|
2024
|
+
---
|
|
2025
|
+
|
|
2026
|
+
### 4. 性能优化建议
|
|
2027
|
+
|
|
2028
|
+
**长列表优化**:
|
|
2029
|
+
|
|
2030
|
+
```vue
|
|
2031
|
+
<!-- 使用虚拟列表 -->
|
|
2032
|
+
<ns-list
|
|
2033
|
+
:data="longList"
|
|
2034
|
+
virtual
|
|
2035
|
+
:item-height="80"
|
|
2036
|
+
:buffer-size="5"
|
|
2037
|
+
/>
|
|
2038
|
+
```
|
|
2039
|
+
|
|
2040
|
+
**图片懒加载**:
|
|
2041
|
+
|
|
2042
|
+
```vue
|
|
2043
|
+
<ns-image
|
|
2044
|
+
:src="imageUrl"
|
|
2045
|
+
lazy
|
|
2046
|
+
placeholder="/loading.png"
|
|
2047
|
+
/>
|
|
2048
|
+
```
|
|
2049
|
+
|
|
2050
|
+
**防抖处理**:
|
|
2051
|
+
|
|
2052
|
+
```javascript
|
|
2053
|
+
import { debounce } from 'lodash-es'
|
|
2054
|
+
|
|
2055
|
+
const handleSearch = debounce((keyword) => {
|
|
2056
|
+
// 搜索逻辑
|
|
2057
|
+
}, 300)
|
|
2058
|
+
```
|
|
2059
|
+
|
|
2060
|
+
---
|
|
2061
|
+
|
|
2062
|
+
### 5. 响应式设计
|
|
2063
|
+
|
|
2064
|
+
```vue
|
|
2065
|
+
<script setup>
|
|
2066
|
+
import { usePlatform } from '@uxda/nutshell/taro'
|
|
2067
|
+
|
|
2068
|
+
const platform = usePlatform()
|
|
2069
|
+
|
|
2070
|
+
// 根据屏幕宽度调整布局
|
|
2071
|
+
const columns = computed(() => {
|
|
2072
|
+
if (platform.screen.width < 375) return 3
|
|
2073
|
+
if (platform.screen.width < 414) return 4
|
|
2074
|
+
return 5
|
|
2075
|
+
})
|
|
2076
|
+
</script>
|
|
2077
|
+
|
|
2078
|
+
<template>
|
|
2079
|
+
<ns-grid :columns="columns">
|
|
2080
|
+
<!-- 网格内容 -->
|
|
2081
|
+
</ns-grid>
|
|
2082
|
+
</template>
|
|
2083
|
+
```
|
|
2084
|
+
|
|
2085
|
+
---
|
|
2086
|
+
|
|
2087
|
+
### 6. 小程序特殊处理
|
|
2088
|
+
|
|
2089
|
+
**页面高度设置**:
|
|
2090
|
+
|
|
2091
|
+
```vue
|
|
2092
|
+
<style>
|
|
2093
|
+
/* 小程序页面高度100% */
|
|
2094
|
+
page {
|
|
2095
|
+
height: 100%;
|
|
2096
|
+
}
|
|
2097
|
+
</style>
|
|
2098
|
+
```
|
|
2099
|
+
|
|
2100
|
+
**授权处理**:
|
|
2101
|
+
|
|
2102
|
+
```javascript
|
|
2103
|
+
import Taro from '@tarojs/taro'
|
|
2104
|
+
|
|
2105
|
+
// 获取用户信息
|
|
2106
|
+
const getUserInfo = async () => {
|
|
2107
|
+
const { authSetting } = await Taro.getSetting()
|
|
2108
|
+
|
|
2109
|
+
if (!authSetting['scope.userInfo']) {
|
|
2110
|
+
// 请求授权
|
|
2111
|
+
await Taro.authorize({ scope: 'scope.userInfo' })
|
|
2112
|
+
}
|
|
2113
|
+
|
|
2114
|
+
const userInfo = await Taro.getUserInfo()
|
|
2115
|
+
return userInfo
|
|
2116
|
+
}
|
|
2117
|
+
```
|
|
2118
|
+
|
|
2119
|
+
---
|
|
2120
|
+
|
|
2121
|
+
## 附录
|
|
2122
|
+
|
|
2123
|
+
### 移动端尺寸规范
|
|
2124
|
+
|
|
2125
|
+
| 元素 | 推荐尺寸 |
|
|
2126
|
+
|------|----------|
|
|
2127
|
+
| 按钮高度 | 44px - 48px |
|
|
2128
|
+
| 输入框高度 | 44px - 48px |
|
|
2129
|
+
| 列表项高度 | 不小于 44px |
|
|
2130
|
+
| 图标尺寸 | 24px - 32px |
|
|
2131
|
+
| 字体大小(正文) | 14px - 16px |
|
|
2132
|
+
| 字体大小(标题) | 18px - 20px |
|
|
2133
|
+
| 安全触摸区域 | 不小于 44px × 44px |
|
|
2134
|
+
|
|
2135
|
+
---
|
|
2136
|
+
|
|
2137
|
+
### 常见问题
|
|
2138
|
+
|
|
2139
|
+
**Q: 如何处理移动端1px边框问题?**
|
|
2140
|
+
|
|
2141
|
+
A: 组件库已内置处理,使用 `hairline` 属性可以实现0.5px细线效果。
|
|
2142
|
+
|
|
2143
|
+
**Q: 如何适配刘海屏?**
|
|
2144
|
+
|
|
2145
|
+
A: 使用 `safe-area-inset-bottom` 等属性自动适配安全区域。
|
|
2146
|
+
|
|
2147
|
+
**Q: 小程序中如何使用?**
|
|
2148
|
+
|
|
2149
|
+
A: 引入 `@uxda/nutshell/taro` 版本,详见"快速开始"章节。
|
|
2150
|
+
|
|
2151
|
+
**Q: 如何实现下拉刷新?**
|
|
2152
|
+
|
|
2153
|
+
A: 使用 `<ns-list>` 或 `<ns-scrollable>` 组件的 `refreshable` 属性。
|
|
2154
|
+
|
|
2155
|
+
---
|
|
2156
|
+
|
|
2157
|
+
## 技术支持
|
|
2158
|
+
|
|
2159
|
+
- GitLab: http://gitlab.ddjf.local/fed/nutshell
|
|
2160
|
+
- 版本: 1.6.92
|
|
2161
|
+
- 支持平台: H5、微信小程序
|
|
2162
|
+
|
|
2163
|
+
---
|
|
2164
|
+
|
|
2165
|
+
**最后更新**: 2024-11-13
|
|
2166
|
+
|