1
0
mirror of https://github.com/ialley-workshop-open/uni-halo.git synced 2026-09-12 16:40:40 +08:00

refactor: 架构升级

This commit is contained in:
小莫唐尼
2026-08-31 07:58:23 +08:00
commit ba5b77568b
693 changed files with 118430 additions and 0 deletions
+7
View File
@@ -0,0 +1,7 @@
# uni-app Skills 目录
| 优先级 | Skill | 理由 |
|---|---|---|
| 1 | `uni-app` | 框架速查:条件编译、pages/manifest 配置,unibest 大量用到 `@uni-helper/vite-plugin-uni-pages` 等约定,日常开发必查 |
| 2 | `uniapp-project` | 逐组件/逐 API 示例库(220 个文件),写页面查组件、查 API 兼容性时最常用 |
| 3 | `uview-pro-vue3` | uView Pro 组件、工具、布局模板,备选没有用迁移到 bak-skills |
+54
View File
@@ -0,0 +1,54 @@
# Generation Info
- **Source:** `sources/uniapp`
- **Git SHA:** `91423a240a5b0714fc5e7e13bd3f93a79b8cc8d7`
- **Generated:** 2026-01-30
## Generated Skills
| Category | File | Description |
|----------|------|-------------|
| Core | core-framework.md | Framework basics, platform support, condition compilation |
| Core | core-view-components.md | Container components: view, scroll-view, swiper, movable-area |
| Core | core-form-components.md | Form controls: input, textarea, picker, checkbox, radio |
| Features | feature-media-components.md | Media: image, video, camera, map, live-player |
| Features | feature-navigation.md | Navigation: navigator, routing APIs |
| Features | feature-network.md | Network: request, upload, download, WebSocket |
| Features | feature-storage.md | Storage: localStorage, file system |
| Features | feature-system-info.md | System: device info, network, screen, vibration |
| Features | feature-file-operations.md | Files: image/video selection, file operations |
| Features | feature-location.md | Location: geolocation, map component |
| Features | feature-ui-feedback.md | UI: toast, modal, loading, action sheet |
| Features | feature-lifecycle.md | Lifecycle: app and page hooks |
| Config | config-pages.md | pages.json configuration |
| Config | config-manifest.md | manifest.json configuration |
## Source Documentation Structure
```
sources/uniapp/docs/
├── README.md # Framework overview
├── api/ # API documentation
│ ├── README.md # API overview
│ ├── request/ # Network APIs
│ ├── storage/ # Storage APIs
│ ├── media/ # Media APIs
│ ├── file/ # File APIs
│ ├── location/ # Location APIs
│ ├── ui/ # UI APIs
│ └── system/ # System APIs
├── component/ # Component documentation
├── collocation/ # Configuration
│ ├── pages.md # pages.json
│ ├── manifest.md # manifest.json
│ └── manifest-app.md # App-specific manifest
├── tutorial/ # Tutorials
└── quickstart.md # Getting started
```
## Notes
- Skills focus on practical usage patterns and code examples
- Platform-specific differences are highlighted where relevant
- Configuration files include common use cases for each platform
- API skills include both callback and Promise usage patterns
+113
View File
@@ -0,0 +1,113 @@
---
name: uni-app
description: Comprehensive skill reference for uni-app cross-platform development framework
metadata:
author: FlippeDround
version: "2026.1.30"
source: Generated from https://gitcode.com/dcloud/unidocs-zh, skills located at https://github.com/antfu/skills
---
> The skill is based on uni-app documentation, generated at 2026-01-30.
uni-app is a Vue.js-based cross-platform framework for developing applications that run on iOS, Android, HarmonyOS, Web (responsive), and various mini-program platforms (WeChat/Alipay/Baidu/Douyin/Feishu/QQ/Kuaishou/DingTalk/Taobao/Jingdong/Xiaohongshu).
## Core
| Topic | Description | Reference |
|-------|-------------|-----------|
| Core Framework | Project structure, platform support, condition compilation | [core-framework](references/core-framework.md) |
| View Components | view, scroll-view, swiper, movable-area, cover-view | [core-view-components](references/core-view-components.md) |
| Form Components | input, textarea, picker, checkbox, radio, switch, slider | [core-form-components](references/core-form-components.md) |
## Features
### UI Components
| Topic | Description | Reference |
|-------|-------------|-----------|
| Media Components | image, video, camera, live-player, map | [feature-media-components](references/feature-media-components.md) |
| Navigation | navigator, routing, page navigation | [feature-navigation](references/feature-navigation.md) |
| UI Feedback | toast, modal, loading, action sheet, pull refresh | [feature-ui-feedback](references/feature-ui-feedback.md) |
### APIs
| Topic | Description | Reference |
|-------|-------------|-----------|
| Network | HTTP requests, file upload/download, WebSocket | [feature-network](references/feature-network.md) |
| Storage | Local storage, file system, caching | [feature-storage](references/feature-storage.md) |
| System Info | Device info, network status, screen, vibration | [feature-system-info](references/feature-system-info.md) |
| File Operations | Image/video selection, file system operations | [feature-file-operations](references/feature-file-operations.md) |
| Location | Geolocation, map component, address selection | [feature-location](references/feature-location.md) |
| Lifecycle | App and page lifecycle hooks | [feature-lifecycle](references/feature-lifecycle.md) |
## Configuration
| Topic | Description | Reference |
|-------|-------------|-----------|
| pages.json | Page routing, tab bar, global styles, sub-packages | [config-pages](references/config-pages.md) |
| manifest.json | App config, permissions, platform settings | [config-manifest](references/config-manifest.md) |
## Platform Support
| Platform | Support Level |
|----------|---------------|
| iOS App | Full support |
| Android App | Full support |
| HarmonyOS Next | Full support |
| H5/Web | Full support |
| WeChat Mini Program | Full support |
| Alipay Mini Program | Full support |
| Baidu Smart Program | Full support |
| Douyin Mini Program | Full support |
| QQ Mini Program | Full support |
| Kuaishou Mini Program | Full support |
| Feishu Mini Program | Full support |
| JD Mini Program | Full support |
| HarmonyOS Meta Service | Full support |
## Key Concepts
### Condition Compilation
Use special comments to write platform-specific code:
```vue
<!-- #ifdef APP-PLUS -->
<view>App only</view>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN -->
<view>WeChat only</view>
<!-- #endif -->
```
### API Promise Support
Most uni-app APIs support Promise when no callback is provided:
```javascript
const res = await uni.request({ url: 'https://api.example.com' })
```
### Cross-Platform Best Practices
1. Use uni-app components and APIs instead of platform-specific ones
2. Use condition compilation for platform-specific features
3. Test on all target platforms
4. Use rpx for responsive layouts
5. Handle platform differences in manifest.json
6. must use uni-helper tools
### MCP扩展
当需要查询 uni-app 官方文档时,优先调用 `search-docs-by-Uniapp-official` MCP 工具搜索相关 API 文档和使用示例。
**使用场景:**
- 用户询问特定 API 的详细用法
- 需要官方文档中的代码示例
- 查询组件的属性和事件
- 了解 API 的平台兼容性
**工具安装:**
如果检测到该 MCP 工具不可用,引导用户访问 https://github.com/uni-helper/mcp 进行安装。
@@ -0,0 +1,370 @@
---
name: Manifest.json Configuration
description: App configuration, permissions, and platform-specific settings
---
# Manifest.json Configuration
`manifest.json` is the application configuration file, defining app name, icon, permissions, and platform-specific settings.
## Basic Configuration
```json
{
"name": "My App",
"appid": "__UNI__XXXXXXX",
"description": "App description",
"versionName": "1.0.0",
"versionCode": 100,
"locale": "auto",
"debug": false
}
```
### Basic Properties
| Property | Type | Description |
|----------|------|-------------|
| name | String | App name |
| appid | String | DCloud app ID |
| description | String | App description |
| versionName | String | Version name (1.0.0) |
| versionCode | Number | Version code (integer) |
| locale | String | Default language |
| debug | Boolean | Debug mode |
| networkTimeout | Object | Network timeout settings |
| uniStatistics | Object | Statistics configuration |
## Network Timeout
```json
{
"networkTimeout": {
"request": 60000,
"connectSocket": 60000,
"uploadFile": 60000,
"downloadFile": 60000
}
}
```
## App Configuration (app-plus)
```json
{
"app-plus": {
"splashscreen": {
"alwaysShowBeforeRender": true,
"autoclose": true,
"waiting": true
},
"screenOrientation": ["portrait-primary"],
"modules": {
"OAuth": {},
"Payment": {},
"Push": {}
},
"distribute": {
"android": {
"permissions": [
"<uses-permission android:name=\"android.permission.INTERNET\" />"
],
"minSdkVersion": 21,
"targetSdkVersion": 30
},
"ios": {
"capabilities": {
"entitlements": {
"com.apple.developer.push": true
}
}
},
"sdkConfigs": {
"payment": {
"alipay": {},
"weixin": {}
}
}
},
"optimization": {
"subPackages": true
}
}
}
```
### Splash Screen
| Property | Type | Description |
|----------|------|-------------|
| alwaysShowBeforeRender | Boolean | Show until first page renders |
| autoclose | Boolean | Auto close splash screen |
| waiting | Boolean | Show loading indicator |
## Mini-Program Configuration
### WeChat (mp-weixin)
```json
{
"mp-weixin": {
"appid": "wx1234567890",
"setting": {
"urlCheck": false,
"es6": true,
"postcss": true,
"minified": true
},
"usingComponents": true,
"permission": {
"scope.userLocation": {
"desc": "Your location is needed"
}
},
"requiredPrivateInfos": [
"getLocation"
]
}
}
```
### Alipay (mp-alipay)
```json
{
"mp-alipay": {
"appid": "2021...",
"allowsAlignRight": true,
"component2": true
}
}
```
### Baidu (mp-baidu)
```json
{
"mp-baidu": {
"appid": "12345678",
"navigationBarForceEnable": true
}
}
```
### Douyin (mp-toutiao)
```json
{
"mp-toutiao": {
"appid": "tt...",
"setting": {
"es6": true,
"minified": true
}
}
}
```
## H5 Configuration
```json
{
"h5": {
"title": "My App",
"template": "index.html",
"router": {
"mode": "hash",
"base": "./"
},
"optimization": {
"treeShaking": {
"enable": true
}
},
"publicPath": "./",
"devServer": {
"port": 8080,
"disableHostCheck": true
},
"sdkConfigs": {
"maps": {
"qqmap": {
"key": "..."
}
}
}
}
}
```
## Vue Configuration
### Vue 2
```json
{
"vueVersion": "2",
"sassImplementationName": "dart-sass"
}
```
### Vue 3
```json
{
"vueVersion": "3"
}
```
## Permission Configuration
### Android Permissions
```json
{
"app-plus": {
"distribute": {
"android": {
"permissions": [
"<uses-permission android:name=\"android.permission.INTERNET\" />",
"<uses-permission android:name=\"android.permission.CAMERA\" />",
"<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\" />",
"<uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\" />",
"<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\" />"
]
}
}
}
}
```
### iOS Privacy Descriptions
```json
{
"app-plus": {
"distribute": {
"ios": {
"privacyDescription": {
"NSCameraUsageDescription": "Camera access is needed for scanning QR codes",
"NSPhotoLibraryUsageDescription": "Photo access is needed for uploading images",
"NSLocationWhenInUseUsageDescription": "Location is needed for finding nearby stores"
}
}
}
}
}
```
## Common Module Configuration
### OAuth (Login)
```json
{
"app-plus": {
"modules": {
"OAuth": {}
},
"distribute": {
"sdkConfigs": {
"oauth": {
"weixin": {
"appid": "wx...",
"appsecret": "...",
"UniversalLinks": "https://..."
}
}
}
}
}
}
```
### Payment
```json
{
"app-plus": {
"modules": {
"Payment": {}
},
"distribute": {
"sdkConfigs": {
"payment": {
"alipay": {},
"weixin": {
"appid": "wx..."
}
}
}
}
}
}
```
### Push Notifications
```json
{
"app-plus": {
"modules": {
"Push": {}
},
"distribute": {
"sdkConfigs": {
"push": {
"unipush": {}
}
}
}
}
}
```
### Share
```json
{
"app-plus": {
"modules": {
"Share": {}
},
"distribute": {
"sdkConfigs": {
"share": {
"weixin": {
"appid": "wx..."
}
}
}
}
}
}
```
## Statistics Configuration
```json
{
"uniStatistics": {
"enable": true
},
"app-plus": {
"uniStatistics": {
"enable": true
}
},
"mp-weixin": {
"uniStatistics": {
"enable": true
}
}
}
```
<!--
Source references:
- https://gitcode.com/dcloud/unidocs-zh/blob/main/docs/collocation/manifest.md
- https://gitcode.com/dcloud/unidocs-zh/blob/main/docs/collocation/manifest-app.md
-->
@@ -0,0 +1,270 @@
---
name: Pages.json Configuration
description: Page routing, tab bar, and global style configuration
---
# Pages.json Configuration
`pages.json` is the global configuration file for uni-app, defining page routes, window styles, native navigation bar, and tab bar.
## Basic Structure
```json
{
"pages": [
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "Home"
}
}
],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarBackgroundColor": "#F8F8F8"
},
"tabBar": {
"list": [
{ "pagePath": "pages/index/index", "text": "Home" }
]
}
}
```
## Root Properties
| Property | Type | Required | Description |
|----------|------|----------|-------------|
| pages | Array | Yes | Page routes |
| globalStyle | Object | No | Default window style |
| tabBar | Object | No | Tab bar configuration |
| condition | Object | No | Launch mode (dev only) |
| subPackages | Array | No | Sub-packages |
| preloadRule | Object | No | Preload rules (MP) |
| easycom | Object | No | Auto component import |
| leftWindow/topWindow/rightWindow | Object | No | Multi-window (H5) |
## Pages Configuration
```json
{
"pages": [
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "Home",
"enablePullDownRefresh": true
}
},
{
"path": "pages/detail/detail",
"style": {
"navigationBarTitleText": "Detail",
"navigationStyle": "custom"
}
}
]
}
```
### Page Style Options
| Property | Type | Description |
|----------|------|-------------|
| navigationBarTitleText | String | Navigation title |
| navigationBarTextStyle | String | Title color: black/white |
| navigationBarBackgroundColor | HexColor | Nav background |
| navigationStyle | String | default/custom |
| enablePullDownRefresh | Boolean | Enable pull refresh |
| backgroundColor | HexColor | Background color |
| backgroundTextStyle | String | dark/light |
| onReachBottomDistance | Number | Bottom distance (px) |
| disableScroll | Boolean | Disable scroll (MP) |
| usingComponents | Object | Using custom components |
## Global Style
Applied to all pages unless overridden.
```json
{
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "My App",
"navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8",
"backgroundTextStyle": "dark",
"enablePullDownRefresh": false,
"onReachBottomDistance": 50,
"rpxCalcMaxDeviceWidth": 960,
"rpxCalcBaseDeviceWidth": 375,
"rpxCalcIncludeWidth": 750
}
}
```
## Tab Bar Configuration
```json
{
"tabBar": {
"color": "#7A7E83",
"selectedColor": "#3cc51f",
"backgroundColor": "#ffffff",
"borderStyle": "black",
"list": [
{
"pagePath": "pages/index/index",
"text": "Home",
"iconPath": "static/image/home.png",
"selectedIconPath": "static/image/home-active.png"
},
{
"pagePath": "pages/category/category",
"text": "Category",
"iconPath": "static/image/cat.png",
"selectedIconPath": "static/image/cat-active.png"
},
{
"pagePath": "pages/cart/cart",
"text": "Cart",
"iconPath": "static/image/cart.png",
"selectedIconPath": "static/image/cart-active.png"
},
{
"pagePath": "pages/user/user",
"text": "User",
"iconPath": "static/image/user.png",
"selectedIconPath": "static/image/user-active.png"
}
]
}
}
```
### Tab Bar Properties
| Property | Type | Description |
|----------|------|-------------|
| color | HexColor | Unselected text color |
| selectedColor | HexColor | Selected text color |
| backgroundColor | HexColor | Background color |
| borderStyle | String | black/white |
| list | Array | Tab items (2-5 items) |
| position | String | bottom/top |
### Tab Item Properties
| Property | Type | Required | Description |
|----------|------|----------|-------------|
| pagePath | String | Yes | Page path |
| text | String | Yes | Tab text |
| iconPath | String | No | Icon path (81x81px) |
| selectedIconPath | String | No | Selected icon |
### Custom Tab Bar (WeChat/QQ/Douyin)
```json
{
"tabBar": {
"custom": true,
"list": [
{ "pagePath": "pages/index/index", "text": "Home" }
]
}
}
```
Create `custom-tab-bar/index` component in root.
## Sub-packages
Split app into smaller chunks for faster loading.
```json
{
"subPackages": [
{
"root": "packageA",
"pages": [
{ "path": "pages/cat/cat" },
{ "path": "pages/dog/dog" }
]
},
{
"root": "packageB",
"pages": [
{ "path": "pages/apple/apple" },
{ "path": "pages/banana/banana" }
]
}
],
"preloadRule": {
"pages/index/index": {
"network": "all",
"packages": ["packageA"]
}
}
}
```
## EasyCom (Auto Component Import)
```json
{
"easycom": {
"autoscan": true,
"custom": {
"^u--(.*)": "uview-plus/components/u-$1/u-$1.vue",
"^up-(.*)": "uview-plus/components/u-$1/u-$1.vue",
"^uni-(.*)": "@dcloudio/uni-ui/lib/uni-$1/uni-$1.vue"
}
}
}
```
With this config, components are auto-imported without registration.
## Conditional Compilation in Config
```json
{
"pages": [
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "Home"
}
}
],
"globalStyle": {
"navigationBarTextStyle": "black"
},
"condition": {
"current": 0,
"list": [
{
"name": "test",
"path": "pages/test/test",
"query": "id=1"
}
]
},
"mp-weixin": {
"appid": "wx...",
"setting": {
"urlCheck": false
}
},
"app-plus": {
"splashscreen": {
"alwaysShowBeforeRender": true
}
}
}
```
<!--
Source references:
- https://gitcode.com/dcloud/unidocs-zh/blob/main/docs/collocation/pages.md
-->
@@ -0,0 +1,250 @@
---
name: Form Components
description: Input, selection, and form control components
---
# Form Components
## input
Single-line text input.
```vue
<template>
<input
v-model="inputValue"
type="text"
placeholder="Enter text"
:maxlength="100"
:focus="true"
@input="onInput"
@focus="onFocus"
@blur="onBlur"
@confirm="onConfirm"
/>
</template>
```
**Properties:**
| Property | Type | Default | Description |
|----------|------|---------|-------------|
| value | String | | Input value |
| type | String | text | Input type: text/number/idcard/digit/tel |
| password | Boolean | false | Password input |
| placeholder | String | | Placeholder text |
| placeholder-style | String | | Placeholder inline styles |
| placeholder-class | String | | Placeholder CSS class |
| maxlength | Number | 140 | Max character length |
| cursor-spacing | Number | 0 | Cursor distance from keyboard bottom (px) |
| focus | Boolean | false | Auto focus |
| confirm-type | String | done | Return key type: send/search/next/go/done |
| confirm-hold | Boolean | false | Keep keyboard open after confirm |
**Events:**
- `@input` - Input value change
- `@focus` - Input focused
- `@blur` - Input blurred
- `@confirm` - Confirm button clicked
- `@keyboardheightchange` - Keyboard height changed
## textarea
Multi-line text input.
```vue
<template>
<textarea
v-model="content"
placeholder="Enter content"
:maxlength="500"
:auto-height="true"
:show-confirm-bar="false"
@linechange="onLineChange"
/>
</template>
```
**Additional Properties:**
| Property | Type | Default | Description |
|----------|------|---------|-------------|
| auto-height | Boolean | false | Auto adjust height |
| fixed | Boolean | false | Fixed position when scrolling |
| cursor | Number | | Cursor position |
| show-confirm-bar | Boolean | true | Show recommendation bar (WeChat) |
| selection-start | Number | -1 | Selection start position |
| selection-end | Number | -1 | Selection end position |
## picker
Selection from predefined options.
```vue
<template>
<!-- Selector mode -->
<picker mode="selector" :range="options" :value="selected" @change="onChange">
<view>Selected: {{ options[selected] }}</view>
</picker>
<!-- Multi-selector -->
<picker mode="multiSelector" :range="multiOptions" @change="onMultiChange">
<view>Multi-select</view>
</picker>
<!-- Date picker -->
<picker mode="date" :value="date" :start="startDate" :end="endDate" @change="onDateChange">
<view>Date: {{ date }}</view>
</picker>
<!-- Region picker -->
<picker mode="region" :value="region" @change="onRegionChange">
<view>Region: {{ region.join('-') }}</view>
</picker>
</template>
<script>
export default {
data() {
return {
options: ['Option 1', 'Option 2', 'Option 3'],
selected: 0,
multiOptions: [['A', 'B'], ['1', '2', '3']],
date: '2024-01-01',
startDate: '2020-01-01',
endDate: '2025-12-31',
region: ['Beijing', 'Beijing', 'Dongcheng']
}
},
methods: {
onChange(e) {
this.selected = e.detail.value
},
onDateChange(e) {
this.date = e.detail.value
},
onRegionChange(e) {
this.region = e.detail.value
}
}
}
</script>
```
**Mode-specific Properties:**
| Mode | Properties |
|------|------------|
| selector | range, range-key |
| multiSelector | range, range-key |
| time | start, end |
| date | start, end, fields (year/month/day) |
| region | custom-item, disable-sub-districts |
## picker-view
Embedded picker view (inline, not popup).
```vue
<template>
<picker-view :value="value" @change="onChange">
<picker-view-column>
<view v-for="item in years" :key="item">{{ item }}</view>
</picker-view-column>
<picker-view-column>
<view v-for="item in months" :key="item">{{ item }}</view>
</picker-view-column>
</picker-view>
</template>
```
## radio / checkbox
Selection controls.
```vue
<template>
<!-- Radio group -->
<radio-group @change="onRadioChange">
<label v-for="item in items" :key="item.value">
<radio :value="item.value" :checked="item.checked" color="#007AFF" />
{{ item.name }}
</label>
</radio-group>
<!-- Checkbox group -->
<checkbox-group @change="onCheckboxChange">
<label v-for="item in items" :key="item.value">
<checkbox :value="item.value" :checked="item.checked" color="#007AFF" />
{{ item.name }}
</label>
</checkbox-group>
</template>
```
**radio/checkbox Properties:**
| Property | Type | Default | Description |
|----------|------|---------|-------------|
| value | String | | Identifier value |
| checked | Boolean | false | Selected state |
| disabled | Boolean | false | Disabled state |
| color | Color | | Selected color |
## switch
Toggle switch.
```vue
<template>
<switch
:checked="isOn"
:disabled="false"
type="switch"
color="#007AFF"
@change="onSwitchChange"
/>
</template>
```
**Properties:**
| Property | Type | Default | Description |
|----------|------|---------|-------------|
| checked | Boolean | false | Checked state |
| disabled | Boolean | false | Disabled state |
| type | String | switch | Style: switch/checkbox |
| color | Color | | Switch color when on |
## slider
Range slider input.
```vue
<template>
<slider
:value="50"
:min="0"
:max="100"
:step="1"
:show-value="true"
:disabled="false"
activeColor="#007AFF"
backgroundColor="#e9e9e9"
block-size="28"
@change="onChange"
@changing="onChanging"
/>
</template>
```
<!--
Source references:
- https://gitcode.com/dcloud/unidocs-zh/blob/main/docs/component/input.md
- https://gitcode.com/dcloud/unidocs-zh/blob/main/docs/component/textarea.md
- https://gitcode.com/dcloud/unidocs-zh/blob/main/docs/component/picker.md
- https://gitcode.com/dcloud/unidocs-zh/blob/main/docs/component/radio.md
- https://gitcode.com/dcloud/unidocs-zh/blob/main/docs/component/checkbox.md
- https://gitcode.com/dcloud/unidocs-zh/blob/main/docs/component/switch.md
- https://gitcode.com/dcloud/unidocs-zh/blob/main/docs/component/slider.md
-->
@@ -0,0 +1,133 @@
---
name: Core Framework
description: UniApp core framework concepts, project structure, and platform overview
---
# UniApp Core Framework
UniApp is a Vue.js-based cross-platform framework for developing applications that run on iOS, Android, HarmonyOS, Web, and various mini-program platforms (WeChat, Alipay, Baidu, Douyin, etc.).
## Project Structure
```
project-root/
├── pages/ # Page files
│ └── index/
│ └── index.vue # Page component
├── components/ # Reusable components
├── static/ # Static assets (images, fonts)
├── App.vue # Application root component
├── main.js # Application entry
├── manifest.json # App configuration
├── pages.json # Page routing config
└── uni.scss # Global SCSS variables
```
## Platform Support
| Platform | Value | Description |
|----------|-------|-------------|
| App | APP-PLUS | iOS/Android native apps |
| App nvue | APP-PLUS-NVUE | Native rendering pages |
| H5 | H5 / WEB | Web applications |
| WeChat Mini Program | MP-WEIXIN | WeChat MP |
| Alipay | MP-ALIPAY | Alipay MP |
| Baidu | MP-BAIDU | Baidu Smart Program |
| Douyin | MP-TOUTIAO | ByteDance MP |
| QQ | MP-QQ | QQ Mini Program |
| Kuaishou | MP-KUAISHOU | Kuaishou MP |
| HarmonyOS | APP-HARMONY | HarmonyOS Next |
## Condition Compilation
Handle platform differences using special comment syntax:
```vue
<template>
<view>
<!-- #ifdef APP-PLUS -->
<text>App only content</text>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN -->
<text>WeChat MP only</text>
<!-- #endif -->
<!-- #ifndef H5 -->
<text>All platforms except H5</text>
<!-- #endif -->
</view>
</template>
<script>
export default {
methods: {
getPlatform() {
// #ifdef APP-PLUS
return 'App'
// #endif
// #ifdef H5
return 'Web'
// #endif
}
}
}
</script>
<style>
/* #ifdef APP-PLUS */
.app-style { padding: 20px; }
/* #endif */
</style>
```
## Platform Values Reference
| Value | Description |
|-------|-------------|
| VUE3 / VUE2 | Vue version |
| UNI-APP-X | UniApp X project |
| APP-PLUS | App (JS engine) |
| APP-PLUS-NVUE / APP-NVUE | App nvue pages |
| APP-ANDROID | Android platform |
| APP-IOS | iOS platform |
| APP-HARMONY | HarmonyOS Next |
| H5 / WEB | Web platform |
| MP-WEIXIN | WeChat Mini Program |
| MP-ALIPAY | Alipay Mini Program |
| MP-BAIDU | Baidu Smart Program |
| MP-TOUTIAO | Douyin Mini Program |
| MP-LARK | Feishu Mini Program |
| MP-QQ | QQ Mini Program |
| MP-KUAISHOU | Kuaishou Mini Program |
| MP-HARMONY | HarmonyOS Meta Service |
## API Promise Support
UniApp APIs support Promise when no callback is provided:
```javascript
// Promise style
uni.request({ url: 'https://api.example.com' })
.then(res => console.log(res))
.catch(err => console.error(err))
// Async/await
async function fetchData() {
try {
const res = await uni.request({ url: 'https://api.example.com' })
return res.data
} catch (err) {
console.error(err)
}
}
```
**Note:** Synchronous APIs (ending in `Sync`), `create*` methods, and `*Manager` methods do not support Promise.
<!--
Source references:
- https://gitcode.com/dcloud/unidocs-zh/blob/main/docs/README.md
- https://gitcode.com/dcloud/unidocs-zh/blob/main/docs/tutorial/platform.md
- https://gitcode.com/dcloud/unidocs-zh/blob/main/docs/api/README.md
-->
@@ -0,0 +1,202 @@
---
name: View Components
description: Core container components for layout and structure
---
# View Components
## view
Basic container component, similar to HTML `<div>`.
```vue
<template>
<view class="container">
<view class="flex-row">
<view class="item">A</view>
<view class="item">B</view>
</view>
<view class="flex-column">
<view class="item">C</view>
<view class="item">D</view>
</view>
</view>
</template>
```
**Properties:**
| Property | Type | Default | Description |
|----------|------|---------|-------------|
| hover-class | String | none | CSS class when pressed |
| hover-stop-propagation | Boolean | false | Stop propagation to ancestor nodes |
| hover-start-time | Number | 50 | Delay before hover state (ms) |
| hover-stay-time | Number | 400 | Duration to keep hover state (ms) |
**Tips:**
- `<div>` is auto-converted to `<view>` in mini-programs
- Use `<text>` to wrap text in nvue pages
## scroll-view
Scrollable container with enhanced scroll capabilities.
```vue
<template>
<!-- Vertical scroll -->
<scroll-view
scroll-y
class="scroll-container"
@scroll="onScroll"
@scrolltolower="loadMore"
:scroll-top="scrollTop"
:scroll-into-view="targetId"
>
<view id="item1">Item 1</view>
<view id="item2">Item 2</view>
</scroll-view>
<!-- Horizontal scroll -->
<scroll-view scroll-x class="horizontal-scroll">
<view class="scroll-item">1</view>
<view class="scroll-item">2</view>
</scroll-view>
</template>
```
**Properties:**
| Property | Type | Description |
|----------|------|-------------|
| scroll-x | Boolean | Enable horizontal scroll |
| scroll-y | Boolean | Enable vertical scroll |
| upper-threshold | Number | Distance from top to trigger scrolltoupper (px) |
| lower-threshold | Number | Distance from bottom to trigger scrolltolower (px) |
| scroll-top | Number | Vertical scroll position |
| scroll-left | Number | Horizontal scroll position |
| scroll-into-view | String | Element ID to scroll into view |
| scroll-with-animation | Boolean | Enable smooth scroll animation |
| enable-back-to-top | Boolean | iOS: tap status bar to scroll top |
**Events:**
- `@scroll` - Scroll event
- `@scrolltoupper` - Reached top
- `@scrolltolower` - Reached bottom
## swiper
Carousel/slider container for switching content.
```vue
<template>
<swiper
:current="currentIndex"
:autoplay="true"
:interval="3000"
:duration="500"
:circular="true"
:indicator-dots="true"
@change="onSwiperChange"
>
<swiper-item>
<view class="slide">Slide 1</view>
</swiper-item>
<swiper-item>
<view class="slide">Slide 2</view>
</swiper-item>
</swiper>
</template>
<script>
export default {
data() {
return {
currentIndex: 0
}
},
methods: {
onSwiperChange(e) {
this.currentIndex = e.detail.current
}
}
}
</script>
```
**swiper Properties:**
| Property | Type | Default | Description |
|----------|------|---------|-------------|
| indicator-dots | Boolean | false | Show pagination dots |
| indicator-color | Color | rgba(0,0,0,.3) | Inactive dot color |
| indicator-active-color | Color | #000000 | Active dot color |
| autoplay | Boolean | false | Auto-play slides |
| current | Number | 0 | Current slide index |
| interval | Number | 5000 | Auto-play interval (ms) |
| duration | Number | 500 | Transition duration (ms) |
| circular | Boolean | false | Circular sliding |
| vertical | Boolean | false | Vertical sliding |
| previous-margin | String | 0px | Previous slide margin |
| next-margin | String | 0px | Next slide margin |
## movable-area / movable-view
Draggable and scalable container.
```vue
<template>
<movable-area class="move-area">
<movable-view
:x="x"
:y="y"
direction="all"
:scale="true"
:scale-min="0.5"
:scale-max="4"
@change="onChange"
@scale="onScale"
>
Draggable content
</movable-view>
</movable-area>
</template>
```
**movable-view Properties:**
| Property | Type | Default | Description |
|----------|------|---------|-------------|
| direction | String | none | Move direction: all/vertical/horizontal/none |
| x | Number | | Initial X position |
| y | Number | | Initial Y position |
| scale | Boolean | false | Enable scaling |
| scale-min | Number | 0.5 | Min scale |
| scale-max | Number | 10 | Max scale |
| scale-value | Number | 1 | Initial scale |
## cover-view / cover-image
Native overlay components that can cover native components (map, video, canvas).
```vue
<template>
<map class="map">
<cover-view class="overlay">Overlay text</cover-view>
<cover-image class="marker" src="/static/marker.png" />
</map>
</template>
```
**Limitations:**
- Only supported in WeChat MP, App, and H5
- Limited styling capabilities
- Cannot nest regular components inside
<!--
Source references:
- https://gitcode.com/dcloud/unidocs-zh/blob/main/docs/component/view.md
- https://gitcode.com/dcloud/unidocs-zh/blob/main/docs/component/scroll-view.md
- https://gitcode.com/dcloud/unidocs-zh/blob/main/docs/component/swiper.md
- https://gitcode.com/dcloud/unidocs-zh/blob/main/docs/component/movable-area.md
- https://gitcode.com/dcloud/unidocs-zh/blob/main/docs/component/cover-view.md
-->
@@ -0,0 +1,391 @@
---
name: File Operations
description: File system operations, image/video selection, and file management
---
# File Operations
## Image Selection
### uni.chooseImage
Select images from album or camera.
```javascript
// Select from album
uni.chooseImage({
count: 9, // Max 9
sizeType: ['original', 'compressed'],
sourceType: ['album'],
success: (res) => {
console.log('Selected:', res.tempFilePaths)
// tempFilePaths: ['blob:xxx', 'blob:xxx']
// tempFiles: [{ path, size }]
}
})
// Take photo
uni.chooseImage({
count: 1,
sourceType: ['camera'],
success: (res) => {
const tempPath = res.tempFilePaths[0]
this.uploadImage(tempPath)
}
})
// Both album and camera
uni.chooseImage({
count: 5,
sizeType: ['compressed'], // Compressed only
sourceType: ['album', 'camera'],
success: (res) => {
res.tempFilePaths.forEach(path => {
this.previewImage(path)
})
}
})
```
**Parameters:**
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| count | Number | 9 | Max number of images |
| sizeType | Array | ['original', 'compressed'] | original/compressed |
| sourceType | Array | ['album', 'camera'] | album/camera |
## Video Selection
### uni.chooseVideo
Select or record video.
```javascript
uni.chooseVideo({
sourceType: ['album', 'camera'],
compressed: true,
maxDuration: 60,
camera: 'back', // front/back
success: (res) => {
console.log('Path:', res.tempFilePath)
console.log('Duration:', res.duration) // seconds
console.log('Size:', res.size) // bytes
console.log('Height:', res.height)
console.log('Width:', res.width)
}
})
```
### uni.chooseMedia (WeChat/QQ)
Choose mixed media types.
```javascript
uni.chooseMedia({
count: 9,
mediaType: ['image', 'video'],
sourceType: ['album', 'camera'],
maxDuration: 30,
camera: 'back',
success: (res) => {
console.log(res.tempFiles)
}
})
```
## File Selection
### uni.chooseFile
Select any file type.
```javascript
uni.chooseFile({
count: 1,
type: 'all', // all/video/image/file
extension: ['.pdf', '.doc', '.docx'], // Filter by extension
success: (res) => {
console.log(res.tempFilePaths)
console.log(res.tempFiles)
}
})
```
## File System Operations (App)
### Get File System Manager
```javascript
const fs = uni.getFileSystemManager()
```
### Read File
```javascript
// Read as text
fs.readFile({
filePath: `${uni.env.USER_DATA_PATH}/data.txt`,
encoding: 'utf8',
success: (res) => {
console.log(res.data)
}
})
// Read as binary
fs.readFile({
filePath: tempFilePath,
encoding: 'binary',
success: (res) => {
console.log(res.data)
}
})
```
### Write File
```javascript
fs.writeFile({
filePath: `${uni.env.USER_DATA_PATH}/config.json`,
data: JSON.stringify({ theme: 'dark' }),
encoding: 'utf8',
success: () => {
console.log('File written')
}
})
```
### Append to File
```javascript
fs.appendFile({
filePath: `${uni.env.USER_DATA_PATH}/log.txt`,
data: '\nNew log entry',
encoding: 'utf8',
success: () => {
console.log('Appended')
}
})
```
### Delete File
```javascript
fs.unlink({
filePath: `${uni.env.USER_DATA_PATH}/temp.txt`,
success: () => {
console.log('File deleted')
}
})
```
### Check File Exists
```javascript
fs.access({
path: `${uni.env.USER_DATA_PATH}/data.json`,
success: () => {
console.log('File exists')
},
fail: () => {
console.log('File not found')
}
})
```
### Create Directory
```javascript
fs.mkdir({
dirPath: `${uni.env.USER_DATA_PATH}/downloads`,
recursive: true, // Create parent directories
success: () => {
console.log('Directory created')
}
})
```
### Read Directory
```javascript
fs.readdir({
dirPath: `${uni.env.USER_DATA_PATH}/downloads`,
success: (res) => {
console.log('Files:', res.files)
}
})
```
### Get File Info
```javascript
fs.getFileInfo({
filePath: tempFilePath,
success: (res) => {
console.log('Size:', res.size)
console.log('Create time:', res.createTime)
console.log('Last access:', res.lastAccessedTime)
}
})
```
## Save and Open Files
### Save File
```javascript
uni.saveFile({
tempFilePath: res.tempFilePath,
success: (res) => {
const savedPath = res.savedFilePath
console.log('Saved to:', savedPath)
}
})
```
### Get Saved File List
```javascript
uni.getSavedFileList({
success: (res) => {
console.log('Files:', res.fileList)
// [{ filePath, createTime, size }, ...]
}
})
```
### Get Saved File Info
```javascript
uni.getSavedFileInfo({
filePath: savedFilePath,
success: (res) => {
console.log('Size:', res.size)
console.log('Create time:', res.createTime)
}
})
```
### Remove Saved File
```javascript
uni.removeSavedFile({
filePath: savedFilePath,
success: () => {
console.log('File removed')
}
})
```
### Open Document
```javascript
uni.openDocument({
filePath: filePath,
fileType: 'pdf', // Optional hint
showMenu: true, // Show share menu (WeChat)
success: () => {
console.log('Document opened')
}
})
```
## Image Operations
### Preview Image
```javascript
uni.previewImage({
current: currentImage, // Current image URL
urls: imageList, // All image URLs
indicator: 'default',
loop: false,
longPressActions: {
itemList: ['Save Image', 'Share'],
success: (data) => {
console.log('Selected:', data.tapIndex)
}
}
})
```
### Get Image Info
```javascript
uni.getImageInfo({
src: imagePath,
success: (res) => {
console.log('Width:', res.width)
console.log('Height:', res.height)
console.log('Path:', res.path)
console.log('Orientation:', res.orientation)
console.log('Type:', res.type)
}
})
```
### Compress Image
```javascript
uni.compressImage({
src: originalPath,
quality: 80, // 0-100
success: (res) => {
console.log('Compressed:', res.tempFilePath)
}
})
```
### Save Image to Album
```javascript
uni.saveImageToPhotosAlbum({
filePath: tempFilePath,
success: () => {
uni.showToast({ title: 'Saved to album' })
}
})
```
## Video Operations
### Save Video to Album
```javascript
uni.saveVideoToPhotosAlbum({
filePath: videoPath,
success: () => {
uni.showToast({ title: 'Video saved' })
}
})
```
### Get Video Info
```javascript
uni.getVideoInfo({
src: videoPath,
success: (res) => {
console.log('Duration:', res.duration)
console.log('Size:', res.size)
console.log('Bitrate:', res.bitrate)
console.log('FPS:', res.fps)
}
})
```
## File Paths Reference
| Path Type | Example | Description |
|-----------|---------|-------------|
| tempFilePath | `blob:xxx` or `_doc/uniapp_temp/xxx` | Temporary file |
| savedFilePath | `_doc/uniapp_save/xxx` | Saved file |
| USER_DATA_PATH | `_doc/` | App data directory |
<!--
Source references:
- https://gitcode.com/dcloud/unidocs-zh/blob/main/docs/api/media/image.md
- https://gitcode.com/dcloud/unidocs-zh/blob/main/docs/api/media/file.md
- https://gitcode.com/dcloud/unidocs-zh/blob/main/docs/api/file/file.md
- https://gitcode.com/dcloud/unidocs-zh/blob/main/docs/api/file/getFileSystemManager.md
-->
@@ -0,0 +1,423 @@
---
name: Page Lifecycle
description: Page and application lifecycle hooks
---
# Page Lifecycle
## Application Lifecycle
In `App.vue`:
```javascript
export default {
globalData: {
userInfo: null,
theme: 'light'
},
onLaunch(options) {
// App launched (only once)
console.log('App launched', options)
this.checkUpdate()
},
onShow(options) {
// App shown/foreground
console.log('App shown', options)
},
onHide() {
// App hidden/background
console.log('App hidden')
},
onError(msg) {
// Global error handler
console.error('App error:', msg)
},
onUnhandledRejection(err) {
// Unhandled promise rejection
console.error('Unhandled rejection:', err)
},
onPageNotFound(res) {
// 404 page not found
console.error('Page not found:', res.path)
uni.redirectTo({
url: '/pages/404/404'
})
},
methods: {
checkUpdate() {
// Check for app updates
const updateManager = uni.getUpdateManager()
updateManager.onCheckForUpdate((res) => {
if (res.hasUpdate) {
console.log('New version available')
}
})
}
}
}
```
## Page Lifecycle
```vue
<script>
export default {
// === Page Load ===
onLoad(options) {
// Page loaded with query parameters
console.log('Page loaded', options)
// options contains URL query params
// e.g., /pages/detail?id=123 -> options = { id: '123' }
this.id = options.id
this.loadData()
},
// === Page Show ===
onShow() {
// Page shown (every time)
console.log('Page shown')
// Good for refreshing data when returning
},
// === Page Ready ===
onReady() {
// Page ready, DOM rendered
console.log('Page ready')
// Safe to access DOM elements
this.initChart()
},
// === Page Hide ===
onHide() {
// Page hidden (navigated away)
console.log('Page hidden')
// Pause videos, timers, etc.
},
// === Page Unload ===
onUnload() {
// Page destroyed
console.log('Page unloaded')
// Clean up resources, remove listeners
clearInterval(this.timer)
},
// === Pull Down Refresh ===
onPullDownRefresh() {
// User pulled down
console.log('Pull down refresh')
this.refreshData().finally(() => {
uni.stopPullDownRefresh()
})
},
// === Reach Bottom ===
onReachBottom() {
// Scrolled to bottom
console.log('Reach bottom')
this.loadMore()
},
// === Page Scroll ===
onPageScroll(e) {
// Page scrolled
// e.scrollTop: scroll position
this.scrollTop = e.scrollTop
},
// === Resize ===
onResize(e) {
// Page resized (e.g., rotation)
console.log('Page resized', e.size)
},
// === Share ===
onShareAppMessage(res) {
// Native share (MP)
if (res.from === 'button') {
// From share button
console.log(res.target)
}
return {
title: 'Share Title',
path: '/pages/index/index',
imageUrl: '/static/share.png'
}
},
// === Timeline Share ===
onShareTimeline() {
// Share to timeline (WeChat)
return {
title: 'Timeline Title',
query: 'id=123',
imageUrl: '/static/share.png'
}
},
// === Add to Favorites ===
onAddToFavorites() {
// Add to MP favorites
return {
title: 'Favorite Title',
imageUrl: '/static/fav.png',
query: 'id=123'
}
},
data() {
return {
id: null,
scrollTop: 0,
timer: null
}
},
methods: {
loadData() {
// Load page data
},
refreshData() {
// Refresh data
},
loadMore() {
// Load more data
},
initChart() {
// Initialize chart after DOM ready
}
}
}
</script>
```
## Component Lifecycle (Vue 2)
```vue
<script>
export default {
// === Creation ===
beforeCreate() {
// Instance initialized
},
created() {
// Instance created, data observed
// Good for initial data loading
},
// === Mounting ===
beforeMount() {
// Before DOM mount
},
mounted() {
// DOM mounted
// Good for DOM operations
},
// === Updating ===
beforeUpdate() {
// Before data update
},
updated() {
// After data update
},
// === Destruction ===
beforeDestroy() {
// Before instance destroyed
// Clean up here
},
destroyed() {
// Instance destroyed
},
// === Keep-alive ===
activated() {
// Component activated (kept-alive)
},
deactivated() {
// Component deactivated (kept-alive)
}
}
</script>
```
## Component Lifecycle (Vue 3)
```vue
<script setup>
import {
onBeforeMount,
onMounted,
onBeforeUpdate,
onUpdated,
onBeforeUnmount,
onUnmounted,
onActivated,
onDeactivated
} from 'vue'
// Setup runs before beforeCreate
console.log('setup')
onBeforeMount(() => {
console.log('onBeforeMount')
})
onMounted(() => {
console.log('onMounted')
})
onBeforeUpdate(() => {
console.log('onBeforeUpdate')
})
onUpdated(() => {
console.log('onUpdated')
})
onBeforeUnmount(() => {
console.log('onBeforeUnmount')
})
onUnmounted(() => {
console.log('onUnmounted')
})
onActivated(() => {
console.log('onActivated')
})
onDeactivated(() => {
console.log('onDeactivated')
})
</script>
```
## Lifecycle Comparison
| Scenario | UniApp Page | Vue Component |
|----------|-------------|---------------|
| Initial load | onLoad | created |
| DOM ready | onReady | mounted |
| Page show | onShow | - |
| Page hide | onHide | - |
| Page destroy | onUnload | destroyed/unmounted |
| Data refresh | onPullDownRefresh | - |
| Infinite scroll | onReachBottom | - |
| Scroll position | onPageScroll | - |
## App Update Manager
```javascript
// In App.vue onLaunch
onLaunch() {
const updateManager = uni.getUpdateManager()
updateManager.onCheckForUpdate((res) => {
console.log('Has update:', res.hasUpdate)
})
updateManager.onUpdateReady(() => {
uni.showModal({
title: 'Update Ready',
content: 'New version downloaded. Restart to apply?',
success: (res) => {
if (res.confirm) {
updateManager.applyUpdate()
}
}
})
})
updateManager.onUpdateFailed(() => {
console.error('Update failed')
})
}
```
## Best Practices
### Data Loading Pattern
```javascript
export default {
data() {
return {
loading: false,
error: null,
data: null
}
},
onLoad(options) {
this.fetchData(options.id)
},
onPullDownRefresh() {
this.fetchData(this.id).finally(() => {
uni.stopPullDownRefresh()
})
},
methods: {
async fetchData(id) {
this.loading = true
this.error = null
try {
this.data = await api.getDetail(id)
} catch (err) {
this.error = err.message
} finally {
this.loading = false
}
}
}
}
```
### Scroll Performance
```javascript
export default {
data() {
return {
scrollTop: 0,
showBackTop: false
}
},
// Throttle scroll events
onPageScroll: throttle(function(e) {
this.scrollTop = e.scrollTop
this.showBackTop = e.scrollTop > 500
}, 200),
methods: {
scrollToTop() {
uni.pageScrollTo({
scrollTop: 0,
duration: 300
})
}
}
}
```
<!--
Source references:
- https://gitcode.com/dcloud/unidocs-zh/blob/main/docs/collocation/App.md
- https://gitcode.com/dcloud/unidocs-zh/blob/main/docs/api/lifecycle.md
-->
@@ -0,0 +1,417 @@
---
name: Location Services
description: Geolocation, map operations, and location-based services
---
# Location Services
## Get Current Location
### uni.getLocation
Get current geographic location.
```javascript
uni.getLocation({
type: 'wgs84', // wgs84/gcj02 (gcj02 for map display)
altitude: false, // Include altitude
geocode: false, // Include address info (App)
highAccuracyExpireTime: 3000, // High accuracy timeout
success: (res) => {
console.log('Latitude:', res.latitude)
console.log('Longitude:', res.longitude)
console.log('Speed:', res.speed)
console.log('Accuracy:', res.accuracy)
// App only:
console.log('Altitude:', res.altitude)
console.log('Address:', res.address)
},
fail: (err) => {
console.error('Location failed:', err)
}
})
```
**Response Properties:**
| Property | Type | Description |
|----------|------|-------------|
| latitude | Number | Latitude |
| longitude | Number | Longitude |
| speed | Number | Speed (m/s) |
| accuracy | Number | Accuracy (meters) |
| altitude | Number | Altitude (meters) |
| verticalAccuracy | Number | Vertical accuracy |
| horizontalAccuracy | Number | Horizontal accuracy |
| address | Object | Address info (App) |
### uni.getFuzzyLocation (WeChat)
Get approximate location (better privacy, faster).
```javascript
uni.getFuzzyLocation({
type: 'wgs84',
success: (res) => {
console.log(res.latitude, res.longitude)
}
})
```
## Choose Location
### uni.chooseLocation
Open map to select location.
```javascript
uni.chooseLocation({
latitude: 39.9,
longitude: 116.4,
keyword: 'restaurant',
success: (res) => {
console.log('Name:', res.name)
console.log('Address:', res.address)
console.log('Latitude:', res.latitude)
console.log('Longitude:', res.longitude)
}
})
```
## Open Location
### uni.openLocation
Open external map app.
```javascript
uni.openLocation({
latitude: 39.9,
longitude: 116.4,
name: 'Destination Name',
address: 'Full address here',
scale: 18
})
```
## Location Change Monitoring
### uni.startLocationUpdate
Start background location updates.
```javascript
uni.startLocationUpdate({
type: 'gcj02',
success: () => {
console.log('Location updates started')
}
})
```
### uni.startLocationUpdateBackground
Start background location (requires permission).
```javascript
uni.startLocationUpdateBackground({
type: 'gcj02',
success: () => {
console.log('Background location started')
}
})
```
### Listen for Location Changes
```javascript
uni.onLocationChange((res) => {
console.log('Location updated:', res.latitude, res.longitude)
})
// Stop listening
uni.offLocationChange(callback)
```
### Stop Location Updates
```javascript
uni.stopLocationUpdate({
success: () => {
console.log('Location updates stopped')
}
})
```
## Map Component
### Basic Map
```vue
<template>
<map
id="myMap"
style="width: 100%; height: 300px;"
:latitude="latitude"
:longitude="longitude"
:scale="14"
:markers="markers"
:polyline="polyline"
:circles="circles"
:show-location="true"
@markertap="onMarkerTap"
@regionchange="onRegionChange"
/>
</template>
<script>
export default {
data() {
return {
latitude: 39.909,
longitude: 116.39742,
markers: [{
id: 1,
latitude: 39.909,
longitude: 116.39742,
title: 'Marker 1',
iconPath: '/static/marker.png',
width: 30,
height: 30,
callout: {
content: 'Hello',
color: '#000',
fontSize: 14,
borderRadius: 5,
padding: 10,
display: 'BYCLICK'
}
}],
polyline: [{
points: [
{ latitude: 39.909, longitude: 116.39742 },
{ latitude: 39.91, longitude: 116.4 }
],
color: '#FF0000',
width: 2,
dottedLine: false
}],
circles: [{
latitude: 39.909,
longitude: 116.39742,
radius: 100,
strokeWidth: 2,
fillColor: '#FF000020'
}]
}
}
}
</script>
```
### Map Context Operations
```javascript
export default {
onReady() {
this.mapContext = uni.createMapContext('myMap')
},
methods: {
// Get center location
getCenter() {
this.mapContext.getCenterLocation({
success: (res) => {
console.log('Center:', res.latitude, res.longitude)
}
})
},
// Move to location
moveToLocation() {
this.mapContext.moveToLocation({
latitude: 39.9,
longitude: 116.4
})
},
// Translate marker
translateMarker() {
this.mapContext.translateMarker({
markerId: 1,
destination: {
latitude: 39.91,
longitude: 116.41
},
autoRotate: true,
rotate: 0,
duration: 1000
})
},
// Include points in view
includePoints() {
this.mapContext.includePoints({
points: [
{ latitude: 39.9, longitude: 116.4 },
{ latitude: 39.91, longitude: 116.41 }
],
padding: [10, 10, 10, 10]
})
},
// Get region
getRegion() {
this.mapContext.getRegion({
success: (res) => {
console.log('Southwest:', res.southwest)
console.log('Northeast:', res.northeast)
}
})
},
// Add markers
addMarkers() {
this.mapContext.addMarkers({
markers: [{
id: 2,
latitude: 39.91,
longitude: 116.41,
title: 'New Marker'
}],
clear: false // Don't clear existing
})
},
// Remove markers
removeMarkers() {
this.mapContext.removeMarkers({
markerIds: [1, 2]
})
}
}
}
```
## Coordinate Systems
| System | Description | Usage |
|--------|-------------|-------|
| WGS84 | GPS coordinates | International standard |
| GCJ02 | Mars coordinates | China national standard |
| BD09 | Baidu coordinates | Baidu Map only |
**Note:** For map display in China, use `gcj02`.
## Permission Configuration
### Mini-Program
Add to `manifest.json`:
```json
{
"mp-weixin": {
"permission": {
"scope.userLocation": {
"desc": "Your location is needed to find nearby stores"
}
},
"requiredPrivateInfos": [
"getLocation",
"chooseLocation"
]
}
}
```
### App (Android)
```json
{
"app-plus": {
"distribute": {
"android": {
"permissions": [
"<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\" />",
"<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\" />"
]
}
}
}
}
```
### App (iOS)
```json
{
"app-plus": {
"distribute": {
"ios": {
"privacyDescription": {
"NSLocationWhenInUseUsageDescription": "Location is needed to find nearby stores",
"NSLocationAlwaysUsageDescription": "Background location is needed for navigation"
}
}
}
}
}
```
## Best Practices
### Permission Handling
```javascript
async function getLocationWithPermission() {
try {
// Check permission
const setting = await uni.getSetting()
if (!setting.authSetting['scope.userLocation']) {
// Request permission
await uni.authorize({ scope: 'scope.userLocation' })
}
// Get location
const res = await uni.getLocation({ type: 'gcj02' })
return res
} catch (err) {
if (err.errMsg.includes('auth deny')) {
uni.showModal({
title: 'Permission Required',
content: 'Please enable location permission in settings',
success: (res) => {
if (res.confirm) {
uni.openSetting()
}
}
})
}
throw err
}
}
```
### Distance Calculation
```javascript
function calculateDistance(lat1, lon1, lat2, lon2) {
const R = 6371 // Earth's radius in km
const dLat = (lat2 - lat1) * Math.PI / 180
const dLon = (lon2 - lon1) * Math.PI / 180
const a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) *
Math.sin(dLon/2) * Math.sin(dLon/2)
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a))
return R * c // Distance in km
}
```
<!--
Source references:
- https://gitcode.com/dcloud/unidocs-zh/blob/main/docs/api/location/location.md
- https://gitcode.com/dcloud/unidocs-zh/blob/main/docs/api/location/location-change.md
- https://gitcode.com/dcloud/unidocs-zh/blob/main/docs/api/location/open-location.md
- https://gitcode.com/dcloud/unidocs-zh/blob/main/docs/component/map.md
-->
@@ -0,0 +1,314 @@
---
name: Media Components
description: Image, video, audio, and camera components
---
# Media Components
## image
Display images with various mode options.
```vue
<template>
<!-- Basic usage -->
<image src="/static/logo.png" mode="aspectFit" />
<!-- With event handling -->
<image
:src="imageUrl"
mode="aspectFill"
:lazy-load="true"
:show-menu-by-longpress="true"
@load="onImageLoad"
@error="onImageError"
/>
</template>
```
**Properties:**
| Property | Type | Default | Description |
|----------|------|---------|-------------|
| src | String | | Image source URL |
| mode | String | scaleToFill | Display mode (see below) |
| lazy-load | Boolean | false | Lazy load image |
| show-menu-by-longpress | Boolean | false | Show menu on long press |
| webp | Boolean | false | Parse WebP format (Android) |
**Mode Values:**
| Mode | Description |
|------|-------------|
| scaleToFill | Fill container, may distort |
| aspectFit | Contain within container |
| aspectFill | Cover container, may clip |
| widthFix | Width fixed, height auto |
| heightFix | Height fixed, width auto |
| top / bottom / center / left / right | Align to position |
| top left / top right / bottom left / bottom right | Corner alignment |
**Events:**
- `@load` - Image loaded successfully
- `@error` - Image failed to load
## video
Video player component.
```vue
<template>
<video
id="myVideo"
src="https://example.com/video.mp4"
:controls="true"
:autoplay="false"
:loop="false"
:muted="false"
initial-time="30"
:duration="300"
poster="/static/poster.jpg"
object-fit="contain"
@play="onPlay"
@pause="onPause"
@ended="onEnded"
@timeupdate="onTimeUpdate"
@fullscreenchange="onFullscreenChange"
/>
</template>
<script>
export default {
onReady() {
this.videoContext = uni.createVideoContext('myVideo')
},
methods: {
play() {
this.videoContext.play()
},
pause() {
this.videoContext.pause()
},
seek(time) {
this.videoContext.seek(time)
},
sendDanmu(danmu) {
this.videoContext.sendDanmu({
text: danmu.text,
color: danmu.color
})
},
playbackRate(rate) {
this.videoContext.playbackRate(rate)
},
onFullscreenChange(e) {
console.log('Fullscreen:', e.detail.fullScreen)
}
}
}
</script>
```
**Properties:**
| Property | Type | Default | Description |
|----------|------|---------|-------------|
| src | String | | Video source URL |
| controls | Boolean | true | Show controls |
| autoplay | Boolean | false | Auto play |
| loop | Boolean | false | Loop playback |
| muted | Boolean | false | Muted |
| initial-time | Number | 0 | Start time (s) |
| duration | Number | | Total duration (s) |
| poster | String | | Poster image URL |
| object-fit | String | contain | contain/cover/fill |
| danmu-list | Array | | Danmu list |
| danmu-btn | Boolean | false | Show danmu button |
| enable-danmu | Boolean | false | Enable danmu |
| show-center-play-btn | Boolean | true | Show center play button |
| show-play-btn | Boolean | true | Show play button |
| show-fullscreen-btn | Boolean | true | Show fullscreen button |
| page-gesture | Boolean | false | Enable page gesture |
| enable-progress-gesture | Boolean | true | Enable progress gesture |
## audio
Audio player (deprecated, use `uni.getBackgroundAudioManager` instead).
```vue
<template>
<audio
:src="audioSrc"
:poster="posterUrl"
:name="audioName"
:author="author"
:controls="true"
:loop="false"
@play="onPlay"
@pause="onPause"
@ended="onEnded"
@timeupdate="onTimeUpdate"
/>
</template>
```
## camera
Camera component for capturing photos/videos.
```vue
<template>
<camera
device-position="back"
flash="auto"
resolution="high"
frame-size="large"
@stop="onCameraStop"
@error="onCameraError"
@initdone="onCameraReady"
/>
<button @click="takePhoto">Take Photo</button>
<button @click="startRecord">Start Record</button>
<button @click="stopRecord">Stop Record</button>
</template>
<script>
export default {
onReady() {
this.cameraContext = uni.createCameraContext()
},
methods: {
takePhoto() {
this.cameraContext.takePhoto({
quality: 'high',
success: (res) => {
console.log(res.tempImagePath)
}
})
},
startRecord() {
this.cameraContext.startRecord({
success: () => console.log('Recording started')
})
},
stopRecord() {
this.cameraContext.stopRecord({
success: (res) => {
console.log(res.tempVideoPath)
}
})
}
}
}
</script>
```
**Properties:**
| Property | Type | Default | Description |
|----------|------|---------|-------------|
| mode | String | normal | normal/scanCode |
| resolution | String | medium | low/medium/high |
| device-position | String | back | front/back |
| flash | String | auto | auto/on/off |
| frame-size | String | large | small/medium/large |
## live-player / live-pusher
Live streaming components (mini-program only).
```vue
<template>
<!-- Live player -->
<live-player
src="rtmp://example.com/live/stream"
mode="live"
:autoplay="true"
:muted="false"
orientation="vertical"
object-fit="contain"
@statechange="onStateChange"
@error="onError"
/>
</template>
```
## map
Map component for displaying maps and markers.
```vue
<template>
<map
id="myMap"
style="width: 100%; height: 300px;"
:latitude="latitude"
:longitude="longitude"
:scale="14"
:markers="markers"
:polyline="polyline"
:circles="circles"
:controls="controls"
:show-location="true"
@markertap="onMarkerTap"
@regionchange="onRegionChange"
@tap="onMapTap"
/>
</template>
<script>
export default {
data() {
return {
latitude: 39.909,
longitude: 116.39742,
markers: [{
id: 1,
latitude: 39.909,
longitude: 116.39742,
title: 'Marker 1',
iconPath: '/static/marker.png',
width: 30,
height: 30
}],
polyline: [{
points: [
{ latitude: 39.909, longitude: 116.39742 },
{ latitude: 39.91, longitude: 116.4 }
],
color: '#FF0000',
width: 2
}]
}
},
onReady() {
this.mapContext = uni.createMapContext('myMap')
},
methods: {
moveToLocation() {
this.mapContext.moveToLocation({
latitude: 39.91,
longitude: 116.4
})
},
getCenterLocation() {
this.mapContext.getCenterLocation({
success: (res) => {
console.log(res.latitude, res.longitude)
}
})
}
}
}
</script>
```
<!--
Source references:
- https://gitcode.com/dcloud/unidocs-zh/blob/main/docs/component/image.md
- https://gitcode.com/dcloud/unidocs-zh/blob/main/docs/component/video.md
- https://gitcode.com/dcloud/unidocs-zh/blob/main/docs/component/audio.md
- https://gitcode.com/dcloud/unidocs-zh/blob/main/docs/component/camera.md
- https://gitcode.com/dcloud/unidocs-zh/blob/main/docs/component/live-player.md
- https://gitcode.com/dcloud/unidocs-zh/blob/main/docs/component/map.md
-->
@@ -0,0 +1,257 @@
---
name: Navigation
description: Navigation, routing, and page navigation components
---
# Navigation
## navigator
Page navigation component.
```vue
<template>
<!-- Basic navigation -->
<navigator url="/pages/detail/detail" hover-class="navigator-hover">
Go to Detail
</navigator>
<!-- Open in new page -->
<navigator url="/pages/detail/detail" open-type="navigate">
Navigate (default)
</navigator>
<!-- Redirect (no back button) -->
<navigator url="/pages/login/login" open-type="redirect">
Login (redirect)
</navigator>
<!-- Switch to tab page -->
<navigator url="/pages/index/index" open-type="switchTab">
Go to Home
</navigator>
<!-- Re-launch app -->
<navigator url="/pages/start/start" open-type="reLaunch">
Restart
</navigator>
<!-- Navigate back -->
<navigator open-type="navigateBack" :delta="1">
Go Back
</navigator>
<!-- Exit app (mini-program) -->
<navigator open-type="exit" target="miniProgram">
Exit
</navigator>
</template>
```
**Properties:**
| Property | Type | Default | Description |
|----------|------|---------|-------------|
| url | String | | Target page path |
| open-type | String | navigate | navigate/redirect/switchTab/reLaunch/navigateBack/exit |
| delta | Number | 1 | Back level when open-type is navigateBack |
| hover-class | String | navigator-hover | Hover state class |
| hover-stop-propagation | Boolean | false | Stop hover propagation |
| target | String | self | self/miniProgram (mini-program only) |
## Programmatic Navigation
### uni.navigateTo
Navigate to new page.
```javascript
// Basic navigation
uni.navigateTo({
url: '/pages/detail/detail'
})
// With query parameters
uni.navigateTo({
url: '/pages/detail/detail?id=123&name=test'
})
// With events (Vue 2 only)
uni.navigateTo({
url: '/pages/detail/detail',
events: {
acceptDataFromOpenedPage(data) {
console.log(data)
}
},
success(res) {
res.eventChannel.emit('acceptDataFromOpenerPage', { data: 'test' })
}
})
```
### uni.redirectTo
Redirect to new page (closes current page).
```javascript
uni.redirectTo({
url: '/pages/login/login'
})
```
### uni.reLaunch
Re-launch application to specified page.
```javascript
uni.reLaunch({
url: '/pages/index/index'
})
```
### uni.switchTab
Switch to tab bar page.
```javascript
uni.switchTab({
url: '/pages/home/home'
})
```
### uni.navigateBack
Navigate back to previous page.
```javascript
// Go back one page
uni.navigateBack()
// Go back multiple pages
uni.navigateBack({
delta: 2
})
// With animation (App only)
uni.navigateBack({
delta: 1,
animationType: 'pop-out',
animationDuration: 300
})
```
### uni.preloadPage
Preload page for faster navigation (App only).
```javascript
uni.preloadPage({
url: '/pages/detail/detail'
})
```
## Getting Page Information
### getCurrentPages
Get current page stack.
```javascript
const pages = getCurrentPages()
const currentPage = pages[pages.length - 1]
console.log(currentPage.route) // Current page path
```
### getApp
Get app instance.
```javascript
const app = getApp()
console.log(app.globalData)
```
## Page Event Channel (Vue 2)
Communicate between pages using event channel.
```javascript
// Page A: Open page B
uni.navigateTo({
url: '/pages/pageB/pageB',
success(res) {
// Listen for events from page B
res.eventChannel.on('acceptDataFromPageB', (data) => {
console.log(data)
})
// Send data to page B
res.eventChannel.emit('acceptDataFromPageA', { data: 'hello' })
}
})
// Page B: Receive and send data
export default {
onLoad() {
const eventChannel = this.getOpenerEventChannel()
// Listen for events from page A
eventChannel.on('acceptDataFromPageA', (data) => {
console.log(data)
})
// Send data back to page A
eventChannel.emit('acceptDataFromPageB', { data: 'world' })
}
}
```
## Navigation Bar
### Custom Navigation Bar
Configure in `pages.json`:
```json
{
"pages": [{
"path": "pages/index/index",
"style": {
"navigationStyle": "custom"
}
}]
}
```
### uni.setNavigationBarTitle
```javascript
uni.setNavigationBarTitle({
title: 'New Title'
})
```
### uni.setNavigationBarColor
```javascript
uni.setNavigationBarColor({
frontColor: '#ffffff',
backgroundColor: '#000000',
animation: {
duration: 400,
timingFunc: 'easeIn'
}
})
```
### uni.showNavigationBarLoading
```javascript
uni.showNavigationBarLoading()
// ...loading operation
uni.hideNavigationBarLoading()
```
<!--
Source references:
- https://gitcode.com/dcloud/unidocs-zh/blob/main/docs/component/navigator.md
- https://gitcode.com/dcloud/unidocs-zh/blob/main/docs/api/router.md
-->
@@ -0,0 +1,345 @@
---
name: Network Requests
description: HTTP requests, file upload/download, and WebSocket
---
# Network Requests
## uni.request
Make HTTP requests to backend APIs.
```javascript
// GET request
uni.request({
url: 'https://api.example.com/data',
method: 'GET',
data: { id: 123 },
header: {
'content-type': 'application/json',
'Authorization': 'Bearer token'
},
timeout: 30000,
success: (res) => {
console.log(res.data)
},
fail: (err) => {
console.error(err)
},
complete: () => {
console.log('Request complete')
}
})
// POST request with JSON
uni.request({
url: 'https://api.example.com/submit',
method: 'POST',
data: {
name: 'John',
age: 30
},
header: {
'content-type': 'application/json'
},
success: (res) => {
if (res.statusCode === 200) {
console.log('Success:', res.data)
}
}
})
// Using Promise
uni.request({
url: 'https://api.example.com/data',
method: 'GET'
}).then(res => {
console.log(res.data)
}).catch(err => {
console.error(err)
})
// Async/await
async function fetchData() {
try {
const res = await uni.request({
url: 'https://api.example.com/data'
})
return res.data
} catch (err) {
console.error('Failed to fetch:', err)
throw err
}
}
```
**Parameters:**
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| url | String | Yes | Request URL |
| data | Object/String/Array/ArrayBuffer | No | Request data |
| header | Object | No | Request headers |
| method | String | No | HTTP method (default: GET) |
| timeout | Number | No | Timeout in ms (default: 60000) |
| dataType | String | No | Response data type (default: json) |
| responseType | String | No | Response type (default: text) |
| sslVerify | Boolean | No | Verify SSL certificate (default: true) |
**Response Object:**
```javascript
{
data: Object | String | ArrayBuffer, // Response data
statusCode: Number, // HTTP status code
header: Object, // Response headers
cookies: Array // Response cookies
}
```
## uni.uploadFile
Upload files to server.
```javascript
uni.chooseImage({
count: 1,
success: (chooseRes) => {
const tempFilePath = chooseRes.tempFilePaths[0]
const uploadTask = uni.uploadFile({
url: 'https://api.example.com/upload',
filePath: tempFilePath,
name: 'file',
formData: {
user: 'test',
description: 'Image upload'
},
header: {
'Authorization': 'Bearer token'
},
success: (res) => {
console.log('Upload success:', JSON.parse(res.data))
},
fail: (err) => {
console.error('Upload failed:', err)
}
})
// Track upload progress
uploadTask.onProgressUpdate((res) => {
console.log('Progress:', res.progress)
console.log('Uploaded bytes:', res.totalBytesSent)
console.log('Total bytes:', res.totalBytesExpectedToSend)
})
// Abort upload if needed
// uploadTask.abort()
}
})
```
**Upload Task Methods:**
- `onProgressUpdate(callback)` - Listen for progress updates
- `abort()` - Cancel the upload
- `offProgressUpdate(callback)` - Remove progress listener
## uni.downloadFile
Download files from server.
```javascript
const downloadTask = uni.downloadFile({
url: 'https://example.com/file.pdf',
success: (res) => {
if (res.statusCode === 200) {
console.log('Downloaded to:', res.tempFilePath)
// Save to local (App only)
uni.saveFile({
tempFilePath: res.tempFilePath,
success: (saveRes) => {
console.log('Saved to:', saveRes.savedFilePath)
}
})
}
}
})
// Track download progress
downloadTask.onProgressUpdate((res) => {
console.log('Progress:', res.progress)
})
```
## WebSocket
Real-time bidirectional communication.
```javascript
// Connect to WebSocket
const socketTask = uni.connectSocket({
url: 'wss://api.example.com/ws',
protocols: ['protocol1'],
header: {
'Authorization': 'Bearer token'
},
success: () => {
console.log('WebSocket connecting...')
}
})
// Listen for connection open
uni.onSocketOpen((res) => {
console.log('WebSocket connected')
// Send message
uni.sendSocketMessage({
data: JSON.stringify({
type: 'message',
content: 'Hello server'
})
})
})
// Listen for messages
uni.onSocketMessage((res) => {
console.log('Received:', res.data)
const data = JSON.parse(res.data)
// Handle message...
})
// Listen for errors
uni.onSocketError((err) => {
console.error('WebSocket error:', err)
})
// Listen for close
uni.onSocketClose((res) => {
console.log('WebSocket closed:', res)
})
// Close connection
function closeSocket() {
uni.closeSocket({
code: 1000,
reason: 'User logout',
success: () => {
console.log('Socket closed successfully')
}
})
}
```
**Socket Task Methods:**
- `close(options)` - Close connection
- `send(options)` - Send message
- `onOpen(callback)` - Connection opened
- `onMessage(callback)` - Message received
- `onClose(callback)` - Connection closed
- `onError(callback)` - Error occurred
## Request Interceptors
Use `uni.addInterceptor` to intercept requests.
```javascript
// Add request interceptor
uni.addInterceptor('request', {
invoke(args) {
// Before request
console.log('Request:', args)
// Add auth token
args.header = args.header || {}
args.header.Authorization = `Bearer ${getToken()}`
return args
},
success(res) {
// After success
console.log('Response:', res)
return res
},
fail(err) {
// After failure
console.error('Request failed:', err)
return err
},
complete(res) {
// Always executed
console.log('Request complete')
}
})
// Remove interceptor
uni.removeInterceptor('request')
```
## Domain Configuration
### Mini-Program
Configure request domains in mini-program developer console:
- `request` domain: For `uni.request`
- `uploadFile` domain: For `uni.uploadFile`
- `downloadFile` domain: For `uni.downloadFile`
- `websocket` domain: For `uni.connectSocket`
### H5
H5 uses browser's same-origin policy. Configure CORS on server or use proxy in development.
```javascript
// vite.config.js proxy configuration
export default {
server: {
proxy: {
'/api': {
target: 'https://api.example.com',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '')
}
}
}
}
```
## Best Practices
```javascript
// Create a request wrapper
const request = (options) => {
return new Promise((resolve, reject) => {
uni.request({
...options,
success: (res) => {
if (res.statusCode >= 200 && res.statusCode < 300) {
resolve(res.data)
} else if (res.statusCode === 401) {
// Handle unauthorized
uni.redirectTo({ url: '/pages/login/login' })
reject(new Error('Unauthorized'))
} else {
reject(new Error(res.data.message || 'Request failed'))
}
},
fail: reject
})
})
}
// Usage
const api = {
getUser: () => request({ url: '/user' }),
updateUser: (data) => request({ url: '/user', method: 'PUT', data })
}
```
<!--
Source references:
- https://gitcode.com/dcloud/unidocs-zh/blob/main/docs/api/request/request.md
- https://gitcode.com/dcloud/unidocs-zh/blob/main/docs/api/request/network-file.md
- https://gitcode.com/dcloud/unidocs-zh/blob/main/docs/api/request/websocket.md
- https://gitcode.com/dcloud/unidocs-zh/blob/main/docs/api/interceptor.md
-->
@@ -0,0 +1,279 @@
---
name: Storage
description: Local data storage and caching APIs
---
# Storage
## Synchronous Storage (Recommended for small data)
### uni.setStorageSync
Store data synchronously.
```javascript
// Store simple value
uni.setStorageSync('username', 'John')
// Store object
uni.setStorageSync('userInfo', {
name: 'John',
age: 30,
email: 'john@example.com'
})
// Store array
uni.setStorageSync('tags', ['vue', 'uniapp', 'javascript'])
```
### uni.getStorageSync
Retrieve data synchronously.
```javascript
// Get simple value
const username = uni.getStorageSync('username')
console.log(username) // 'John'
// Get object
const userInfo = uni.getStorageSync('userInfo')
console.log(userInfo.name) // 'John'
// Check if exists
const value = uni.getStorageSync('nonexistent')
console.log(value) // '' (empty string if not found)
```
### uni.removeStorageSync
Remove specific key.
```javascript
uni.removeStorageSync('username')
```
### uni.clearStorageSync
Clear all storage.
```javascript
uni.clearStorageSync()
```
## Asynchronous Storage (Recommended for large data)
### uni.setStorage
```javascript
uni.setStorage({
key: 'userData',
data: {
id: 123,
preferences: { theme: 'dark', language: 'zh' }
},
success: () => {
console.log('Storage saved')
},
fail: (err) => {
console.error('Save failed:', err)
}
})
// Promise style
uni.setStorage({
key: 'config',
data: { debug: true }
}).then(() => {
console.log('Config saved')
})
```
### uni.getStorage
```javascript
uni.getStorage({
key: 'userData',
success: (res) => {
console.log('Data:', res.data)
},
fail: (err) => {
console.log('Key not found')
}
})
// Promise style
uni.getStorage({ key: 'userData' })
.then(res => console.log(res.data))
.catch(() => console.log('Not found'))
```
### uni.removeStorage
```javascript
uni.removeStorage({
key: 'tempData',
success: () => {
console.log('Removed successfully')
}
})
```
### uni.getStorageInfo
Get storage information.
```javascript
uni.getStorageInfo({
success: (res) => {
console.log('Keys:', res.keys)
console.log('Current size:', res.currentSize, 'KB')
console.log('Limit size:', res.limitSize, 'KB')
}
})
```
## Storage Limits
| Platform | Limit |
|----------|-------|
| Mini Program | 10 MB (single) / 200+ MB total |
| App | No hard limit (device dependent) |
| H5 | ~5-10 MB (browser dependent) |
## Best Practices
### Data Persistence Helper
```javascript
const storage = {
// Set with expiration (days)
setWithExpiry(key, value, days) {
const item = {
value,
expiry: Date.now() + days * 24 * 60 * 60 * 1000
}
uni.setStorageSync(key, item)
},
// Get with expiration check
getWithExpiry(key) {
const item = uni.getStorageSync(key)
if (!item) return null
if (Date.now() > item.expiry) {
uni.removeStorageSync(key)
return null
}
return item.value
},
// Safe get with default
get(key, defaultValue = null) {
try {
const value = uni.getStorageSync(key)
return value !== '' ? value : defaultValue
} catch (e) {
return defaultValue
}
},
// Batch operations
setBatch(data) {
Object.entries(data).forEach(([key, value]) => {
uni.setStorageSync(key, value)
})
},
clear() {
uni.clearStorageSync()
}
}
// Usage
storage.setWithExpiry('token', 'abc123', 7) // Expires in 7 days
const token = storage.getWithExpiry('token')
```
### User Session Management
```javascript
const session = {
setToken(token) {
uni.setStorageSync('access_token', token)
},
getToken() {
return uni.getStorageSync('access_token')
},
clearToken() {
uni.removeStorageSync('access_token')
},
setUserInfo(info) {
uni.setStorageSync('user_info', info)
},
getUserInfo() {
return uni.getStorageSync('user_info')
},
isLoggedIn() {
return !!this.getToken()
},
clear() {
this.clearToken()
uni.removeStorageSync('user_info')
}
}
```
## File Storage (App only)
### Local File System
```javascript
// Get file system manager
const fs = uni.getFileSystemManager()
// Write file
fs.writeFile({
filePath: `${uni.env.USER_DATA_PATH}/data.json`,
data: JSON.stringify({ name: 'test' }),
encoding: 'utf8',
success: () => console.log('File written')
})
// Read file
fs.readFile({
filePath: `${uni.env.USER_DATA_PATH}/data.json`,
encoding: 'utf8',
success: (res) => {
const data = JSON.parse(res.data)
console.log(data)
}
})
// Check if file exists
fs.access({
path: `${uni.env.USER_DATA_PATH}/data.json`,
success: () => console.log('File exists'),
fail: () => console.log('File not found')
})
```
## Storage Comparison
| Method | Data Type | Size Limit | Async | Use Case |
|--------|-----------|------------|-------|----------|
| StorageSync | Any | ~10MB | No | Small config data |
| Storage | Any | ~10MB | Yes | Large data objects |
| File System | Binary/Text | Large | Yes | Files, images |
<!--
Source references:
- https://gitcode.com/dcloud/unidocs-zh/blob/main/docs/api/storage/storage.md
- https://gitcode.com/dcloud/unidocs-zh/blob/main/docs/api/file/file.md
- https://gitcode.com/dcloud/unidocs-zh/blob/main/docs/api/file/getFileSystemManager.md
-->
@@ -0,0 +1,300 @@
---
name: System Information
description: Device info, system info, and environment detection APIs
---
# System Information
## uni.getSystemInfo / getSystemInfoSync
Get device and system information.
```javascript
// Synchronous (faster, recommended)
const info = uni.getSystemInfoSync()
console.log(info)
// Asynchronous
uni.getSystemInfo({
success: (res) => {
console.log(res)
}
})
// Promise
uni.getSystemInfo().then(res => {
console.log(res)
})
```
### System Info Properties
| Property | Type | Description |
|----------|------|-------------|
| brand | String | Device brand |
| model | String | Device model |
| pixelRatio | Number | Device pixel ratio |
| screenWidth | Number | Screen width (px) |
| screenHeight | Number | Screen height (px) |
| windowWidth | Number | Window width (px) |
| windowHeight | Number | Window height (px) |
| statusBarHeight | Number | Status bar height (px) |
| language | String | Language |
| system | String | OS version |
| version | String | WeChat/Runtime version |
| platform | String | Platform: ios/android/windows/mac/devtools |
| SDKVersion | String | Client base library version |
| appId | String | App ID (DCloud) |
| appName | String | App name |
| appVersion | String | App version |
| appCodeName | String | App code name |
| uniPlatform | String | uni-app platform |
| uniCompileVersion | String | Compilation version |
| uniRuntimeVersion | String | Runtime version |
| deviceId | String | Device ID |
| deviceBrand | String | Device brand |
| deviceModel | String | Device model |
| deviceType | String | Device type: phone/pad |
| osName | String | OS name |
| osVersion | String | OS version |
| osLanguage | String | OS language |
| osTheme | String | OS theme: light/dark |
| batteryLevel | Number | Battery level (0-100) |
## uni.getAppBaseInfo
Get app base information.
```javascript
const info = uni.getAppBaseInfo()
// Returns: appId, appName, appVersion, appVersionCode, etc.
```
## uni.getDeviceInfo
Get device hardware information.
```javascript
const info = uni.getDeviceInfo()
// Returns: brand, model, deviceId, deviceBrand, deviceModel, deviceType
```
## uni.getWindowInfo
Get window information.
```javascript
const info = uni.getWindowInfo()
// Returns: pixelRatio, screenWidth, screenHeight, windowWidth, windowHeight,
// statusBarHeight, safeArea, screenTop
```
## Safe Area
Handle notched devices and safe areas.
```javascript
const info = uni.getSystemInfoSync()
// Safe area info
const safeArea = info.safeArea
console.log(safeArea) // { top, left, right, bottom, width, height }
// Check if device has notch (unsafe area at top)
const hasNotch = info.safeAreaInsets && info.safeAreaInsets.top > 0
```
### Safe Area CSS Variables (App/H5)
```css
.safe-area-bottom {
padding-bottom: constant(safe-area-inset-bottom); /* iOS 11.0 */
padding-bottom: env(safe-area-inset-bottom); /* iOS 11.2+ */
}
```
## Network Status
### uni.getNetworkType
```javascript
uni.getNetworkType({
success: (res) => {
// res.networkType: wifi/2g/3g/4g/5g/unknown/none
console.log('Network:', res.networkType)
}
})
```
### uni.onNetworkStatusChange
```javascript
// Listen for network changes
uni.onNetworkStatusChange((res) => {
console.log('Network type:', res.networkType)
console.log('Is connected:', res.isConnected)
})
// Remove listener
uni.offNetworkStatusChange(callback)
```
## Battery Info
### uni.getBatteryInfo
```javascript
uni.getBatteryInfo({
success: (res) => {
console.log('Level:', res.level) // 0-100
console.log('Is charging:', res.isCharging)
}
})
```
## Device Orientation
### uni.onDeviceMotionChange
```javascript
uni.startDeviceMotionListening({
interval: 'normal', // game/ui/normal
success: () => {
uni.onDeviceMotionChange((res) => {
console.log('Alpha:', res.alpha) // 0-360
console.log('Beta:', res.beta) // -180 to 180
console.log('Gamma:', res.gamma) // -90 to 90
})
}
})
// Stop listening
uni.stopDeviceMotionListening()
```
### Screen Orientation
```javascript
// Get current orientation
const info = uni.getSystemInfoSync()
const isLandscape = info.screenWidth > info.screenHeight
// Lock orientation (App only)
plus.screen.lockOrientation('portrait-primary')
// Options: portrait-primary/portrait-secondary/landscape-primary/landscape-secondary
```
## Screen Brightness
```javascript
// Set brightness (0-1)
uni.setScreenBrightness({
value: 0.8
})
// Get brightness
uni.getScreenBrightness({
success: (res) => {
console.log('Brightness:', res.value)
}
})
// Keep screen on
uni.setKeepScreenOn({
keepScreenOn: true
})
```
## Vibration
```javascript
// Short vibration (15ms)
uni.vibrateShort()
// Long vibration (400ms)
uni.vibrateLong()
// Pattern vibration (App only)
uni.vibrateLong() // or custom pattern
```
## Clipboard
```javascript
// Set clipboard
uni.setClipboardData({
data: 'Text to copy',
success: () => {
uni.showToast({ title: 'Copied' })
}
})
// Get clipboard
uni.getClipboardData({
success: (res) => {
console.log('Clipboard:', res.data)
}
})
```
## Phone Call
```javascript
uni.makePhoneCall({
phoneNumber: '13800138000'
})
```
## Scan Code
```javascript
uni.scanCode({
onlyFromCamera: false, // Allow from album
scanType: ['qrCode', 'barCode'], // Types to scan
success: (res) => {
console.log('Result:', res.result)
console.log('Type:', res.scanType)
console.log('CharSet:', res.charSet)
}
})
```
## Platform Detection
```javascript
const info = uni.getSystemInfoSync()
// Platform checks
const isIOS = info.platform === 'ios'
const isAndroid = info.platform === 'android'
const isWindows = info.platform === 'windows'
const isMac = info.platform === 'mac'
const isDevtools = info.platform === 'devtools'
// App platform checks
const isApp = info.uniPlatform === 'app'
const isH5 = info.uniPlatform === 'web'
const isWeixinMP = info.uniPlatform === 'mp-weixin'
// Safe area calculation
const safeAreaTop = info.statusBarHeight + (isApp ? 44 : 0) // 44px for nav bar
```
## Storage Info
```javascript
uni.getStorageInfo({
success: (res) => {
console.log('Keys:', res.keys)
console.log('Current size:', res.currentSize)
console.log('Limit size:', res.limitSize)
}
})
```
<!--
Source references:
- https://gitcode.com/dcloud/unidocs-zh/blob/main/docs/api/system/info.md
- https://gitcode.com/dcloud/unidocs-zh/blob/main/docs/api/system/network.md
- https://gitcode.com/dcloud/unidocs-zh/blob/main/docs/api/system/phone.md
-->
@@ -0,0 +1,382 @@
---
name: UI Feedback
description: Toast, modal, loading, and action sheet APIs
---
# UI Feedback
## Toast Messages
### uni.showToast
Display success/error messages.
```javascript
// Success toast
uni.showToast({
title: 'Success!',
icon: 'success',
duration: 2000,
mask: false
})
// Loading toast
uni.showToast({
title: 'Loading...',
icon: 'loading',
duration: 10000
})
// Text only (no icon)
uni.showToast({
title: 'Please wait',
icon: 'none',
duration: 2000
})
// Error toast
uni.showToast({
title: 'Failed!',
icon: 'error'
})
```
**Parameters:**
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| title | String | Required | Message text |
| icon | String | success | success/loading/none/error |
| duration | Number | 1500 | Duration in ms |
| mask | Boolean | false | Prevent touch during display |
| position | String | | top/center/bottom (App) |
### uni.hideToast
```javascript
uni.hideToast()
```
## Loading
### uni.showLoading
```javascript
uni.showLoading({
title: 'Loading...',
mask: true // Prevent interaction
})
// Hide after operation
setTimeout(() => {
uni.hideLoading()
}, 2000)
```
### uni.hideLoading
```javascript
uni.hideLoading()
```
## Modal Dialogs
### uni.showModal
Alert and confirm dialogs.
```javascript
// Alert (single button)
uni.showModal({
title: 'Notice',
content: 'Operation completed',
showCancel: false
})
// Confirm (two buttons)
uni.showModal({
title: 'Confirm',
content: 'Are you sure?',
cancelText: 'Cancel',
cancelColor: '#999',
confirmText: 'Confirm',
confirmColor: '#007AFF',
success: (res) => {
if (res.confirm) {
console.log('User confirmed')
} else if (res.cancel) {
console.log('User cancelled')
}
}
})
// Editable modal
uni.showModal({
title: 'Input',
content: 'Enter your name',
editable: true,
placeholderText: 'Name',
success: (res) => {
if (res.confirm) {
console.log('Input:', res.content)
}
}
})
```
## Action Sheet
### uni.showActionSheet
Bottom action menu.
```javascript
uni.showActionSheet({
itemList: ['Take Photo', 'Choose from Album', 'Cancel'],
itemColor: '#000000',
success: (res) => {
// res.tapIndex: 0, 1, 2...
console.log('Selected:', res.tapIndex)
switch (res.tapIndex) {
case 0:
this.takePhoto()
break
case 1:
this.chooseFromAlbum()
break
}
},
fail: (err) => {
console.log('Cancelled')
}
})
```
## Pull to Refresh
### Enable in pages.json
```json
{
"pages": [{
"path": "pages/index/index",
"style": {
"enablePullDownRefresh": true,
"backgroundTextStyle": "dark"
}
}]
}
```
### Handle in Page
```javascript
export default {
onPullDownRefresh() {
console.log('Pull down triggered')
this.refreshData().finally(() => {
uni.stopPullDownRefresh()
})
}
}
```
### Programmatic Control
```javascript
// Start pull refresh
uni.startPullDownRefresh()
// Stop pull refresh
uni.stopPullDownRefresh()
```
## Navigation Bar Loading
```javascript
// Show loading in nav bar
uni.showNavigationBarLoading()
// Hide loading
uni.hideNavigationBarLoading()
```
## Tab Bar Operations
### Show/Hide Tab Bar
```javascript
// Hide tab bar
uni.hideTabBar({
animation: true
})
// Show tab bar
uni.showTabBar({
animation: true
})
```
### Set Tab Bar Style
```javascript
uni.setTabBarStyle({
color: '#999',
selectedColor: '#007AFF',
backgroundColor: '#fff',
borderStyle: 'black'
})
```
### Set Tab Bar Item
```javascript
uni.setTabBarItem({
index: 0,
text: 'Home',
iconPath: '/static/home.png',
selectedIconPath: '/static/home-active.png'
})
```
### Add/Remove Tab Bar Badge
```javascript
// Show badge
uni.showTabBarRedDot({
index: 2 // Tab index
})
// Hide badge
uni.hideTabBarRedDot({
index: 2
})
// Set badge text
uni.setTabBarBadge({
index: 2,
text: '5'
})
// Remove badge text
uni.removeTabBarBadge({
index: 2
})
```
## Preview Image
```javascript
uni.previewImage({
current: 'https://example.com/1.jpg', // Current image
urls: [
'https://example.com/1.jpg',
'https://example.com/2.jpg',
'https://example.com/3.jpg'
],
indicator: 'default', // default/number/none
loop: false,
longPressActions: {
itemList: ['Save Image', 'Share'],
success: (data) => {
console.log('Long press:', data.tapIndex)
}
}
})
```
## Save Image to Photos
```javascript
uni.saveImageToPhotosAlbum({
filePath: 'temp://path/to/image.jpg',
success: () => {
uni.showToast({ title: 'Saved' })
}
})
```
## Best Practices
### Toast Helper
```javascript
const toast = {
success(message, duration = 2000) {
uni.showToast({ title: message, icon: 'success', duration })
},
error(message, duration = 2000) {
uni.showToast({ title: message, icon: 'error', duration })
},
loading(message = 'Loading...') {
uni.showLoading({ title: message, mask: true })
},
hide() {
uni.hideLoading()
uni.hideToast()
},
text(message, duration = 2000) {
uni.showToast({ title: message, icon: 'none', duration })
}
}
// Usage
toast.loading()
fetchData()
.then(() => toast.success('Loaded'))
.catch(() => toast.error('Failed'))
.finally(() => toast.hide())
```
### Modal Helper
```javascript
const modal = {
confirm(title, content) {
return new Promise((resolve) => {
uni.showModal({
title,
content,
success: (res) => resolve(res.confirm)
})
})
},
alert(title, content) {
return new Promise((resolve) => {
uni.showModal({
title,
content,
showCancel: false,
success: () => resolve()
})
})
},
action(items) {
return new Promise((resolve, reject) => {
uni.showActionSheet({
itemList: items,
success: (res) => resolve(res.tapIndex),
fail: reject
})
})
}
}
// Usage
async function deleteItem(id) {
const confirmed = await modal.confirm('Delete', 'Are you sure?')
if (confirmed) {
await api.delete(id)
toast.success('Deleted')
}
}
```
<!--
Source references:
- https://gitcode.com/dcloud/unidocs-zh/blob/main/docs/api/ui/prompt.md
- https://gitcode.com/dcloud/unidocs-zh/blob/main/docs/api/ui/navigationbar.md
- https://gitcode.com/dcloud/unidocs-zh/blob/main/docs/api/ui/tabbar.md
-->
+317
View File
@@ -0,0 +1,317 @@
# uni-app 技能与官方文档对应核对清单
## 核对目标
确保所有 uni-app 相关技能与官方文档一一对应,每个组件和 API 都有独立的示例文件,包含原文档地址和官网全部示例。
## 官方文档参考
- **组件文档**: https://uniapp.dcloud.net.cn/component/
- **API 文档**: https://uniapp.dcloud.net.cn/api/
- **uni-app-x 组件**: https://doc.dcloud.net.cn/uni-app-x/component/
- **uni-app-x API**: https://doc.dcloud.net.cn/uni-app-x/api/
## 核对任务清单
### 1. uni-app 内置组件核对
#### 视图容器组件
- [x] view - ✅ 已有文档 + ✅ 已创建示例文件 `examples/components/built-in/view.md`
- [x] scroll-view - ✅ 已有文档 + ✅ 已创建示例文件 `examples/components/built-in/scroll-view.md`
- [x] swiper - ✅ 已有文档 + ✅ 已创建示例文件 `examples/components/built-in/swiper.md`
- [x] match-media - ✅ 已有文档
- [x] movable-area - ✅ 已有文档
- [x] movable-view - ✅ 已有文档
- [x] cover-view - ✅ 已有文档
- [x] cover-image - ✅ 已有文档
#### 基础内容组件
- [x] icon - ✅ 已有文档 + ✅ 已创建示例文件 `examples/components/built-in/icon.md`
- [x] text - ✅ 已有文档 + ✅ 已创建示例文件 `examples/components/built-in/text.md`
- [x] rich-text - ✅ 已有文档 + ✅ 已创建示例文件 `examples/components/built-in/rich-text.md`
- [x] progress - ✅ 已有文档 + ✅ 已创建示例文件 `examples/components/built-in/progress.md`
#### 表单组件
- [x] button - ✅ 已有文档 + ✅ 已创建示例文件 `examples/components/built-in/button.md`
- [x] checkbox - ✅ 已有文档 + ✅ 已创建示例文件 `examples/components/built-in/checkbox.md`
- [x] editor - ✅ 已有文档
- [x] form - ✅ 已有文档 + ✅ 已创建示例文件 `examples/components/built-in/form.md`
- [x] input - ✅ 已有文档 + ✅ 已创建示例文件 `examples/components/built-in/input.md`
- [x] label - ✅ 已有文档 + ✅ 已创建示例文件 `examples/components/built-in/label.md`
- [x] picker - ✅ 已有文档 + ✅ 已创建示例文件 `examples/components/built-in/picker.md`
- [x] picker-view - ✅ 已有文档
- [x] radio - ✅ 已有文档 + ✅ 已创建示例文件 `examples/components/built-in/radio.md`
- [x] slider - ✅ 已有文档 + ✅ 已创建示例文件 `examples/components/built-in/slider.md`
- [x] switch - ✅ 已有文档 + ✅ 已创建示例文件 `examples/components/built-in/switch.md`
- [x] textarea - ✅ 已有文档 + ✅ 已创建示例文件 `examples/components/built-in/textarea.md`
#### 导航组件
- [x] navigator - ✅ 已有文档 + ✅ 已创建示例文件 `examples/components/built-in/navigator.md`
#### 媒体组件
- [x] audio - ✅ 已有文档 + ✅ 已创建示例文件 `examples/components/built-in/audio.md`
- [x] camera - ✅ 已有文档 + ✅ 已创建示例文件 `examples/components/built-in/camera.md`
- [x] image - ✅ 已有文档 + ✅ 已创建示例文件 `examples/components/built-in/image.md`
- [x] video - ✅ 已有文档 + ✅ 已创建示例文件 `examples/components/built-in/video.md`
- [x] live-player - ✅ 已有文档
- [x] live-pusher - ✅ 已有文档
#### 其他组件
- [x] map - ✅ 已有文档 + ✅ 已创建示例文件 `examples/components/built-in/map.md`
- [x] canvas - ✅ 已有文档 + ✅ 已创建示例文件 `examples/components/built-in/canvas.md`
- [x] web-view - ✅ 已有文档 + ✅ 已创建示例文件 `examples/components/built-in/web-view.md`
- [x] ad - ✅ 已有文档
- [x] ad-draw - ✅ 已有文档
- [x] custom-tab-bar - ✅ 已有文档
- [x] navigation-bar - ✅ 已有文档
- [x] page-meta - ✅ 已有文档
- [x] unicloud-db - ✅ 已有文档
**状态**: ✅ 所有内置组件(40个)已有文档
### 2. uni-ui 扩展组件核对
**状态**: ✅ 所有 uni-ui 组件(44个)已有文档
### 3. uni-app API 核对
#### 网络请求 API
- [x] uni.request - ✅ 已创建示例文件 `examples/api/network/request.md`
- [x] uni.uploadFile - ✅ 已创建示例文件 `examples/api/network/upload-file.md`
- [x] uni.downloadFile - ✅ 已创建示例文件 `examples/api/network/download-file.md`
- [ ] uni.connectSocket
- [ ] uni.onSocketOpen
- [ ] uni.onSocketError
- [ ] uni.sendSocketMessage
- [ ] uni.onSocketMessage
- [ ] uni.closeSocket
- [ ] uni.onSocketClose
#### 数据存储 API
- [x] uni.setStorage - ✅ 已创建示例文件 `examples/api/storage/set-storage.md`
- [x] uni.setStorageSync - ✅ 已创建示例文件 `examples/api/storage/set-storage-sync.md`
- [x] uni.getStorage - ✅ 已创建示例文件 `examples/api/storage/get-storage.md`
- [x] uni.getStorageSync - ✅ 已创建示例文件 `examples/api/storage/get-storage-sync.md`
- [x] uni.getStorageInfo - ✅ 已创建示例文件 `examples/api/storage/get-storage-info.md`
- [ ] uni.getStorageInfoSync
- [x] uni.removeStorage - ✅ 已创建示例文件 `examples/api/storage/remove-storage.md`
- [ ] uni.removeStorageSync
- [x] uni.clearStorage - ✅ 已创建示例文件 `examples/api/storage/clear-storage.md`
- [ ] uni.clearStorageSync
#### 设备信息 API
- [x] uni.getSystemInfo - ✅ 已创建示例文件 `examples/api/device/get-system-info.md`
- [ ] uni.getSystemInfoSync
- [x] uni.getNetworkType - ✅ 已创建示例文件 `examples/api/device/get-network-type.md`
- [ ] uni.onNetworkStatusChange
- [x] uni.getBatteryInfo - ✅ 已创建示例文件 `examples/api/device/get-battery-info.md`
- [ ] uni.getBatteryInfoSync
- [x] uni.setScreenBrightness - ✅ 已创建示例文件 `examples/api/device/set-screen-brightness.md`
- [x] uni.getScreenBrightness - ✅ 已创建示例文件 `examples/api/device/get-screen-brightness.md`
- [ ] uni.setKeepScreenOn
#### 界面交互 API
- [x] uni.showToast - ✅ 已创建示例文件 `examples/api/ui/show-toast.md`
- [x] uni.showLoading - ✅ 已创建示例文件 `examples/api/ui/show-loading.md`
- [x] uni.hideToast - ✅ 已创建示例文件 `examples/api/ui/hide-toast.md`
- [x] uni.hideLoading - ✅ 已创建示例文件 `examples/api/ui/hide-loading.md`
- [x] uni.showModal - ✅ 已创建示例文件 `examples/api/ui/show-modal.md`
- [x] uni.showActionSheet - ✅ 已创建示例文件 `examples/api/ui/show-action-sheet.md`
- [x] uni.setNavigationBarTitle - ✅ 已创建示例文件 `examples/api/ui/set-navigation-bar-title.md`
- [x] uni.setNavigationBarColor - ✅ 已创建示例文件 `examples/api/ui/set-navigation-bar-color.md`
- [x] uni.showNavigationBarLoading - ✅ 已创建示例文件 `examples/api/ui/show-navigation-bar-loading.md`
- [x] uni.hideNavigationBarLoading - ✅ 已创建示例文件 `examples/api/ui/hide-navigation-bar-loading.md`
- [x] uni.setTabBarBadge - ✅ 已创建示例文件 `examples/api/ui/set-tab-bar-badge.md`
- [x] uni.removeTabBarBadge - ✅ 已创建示例文件 `examples/api/ui/remove-tab-bar-badge.md`
- [x] uni.showTabBarRedDot - ✅ 已创建示例文件 `examples/api/ui/show-tab-bar-red-dot.md`
- [x] uni.hideTabBarRedDot - ✅ 已创建示例文件 `examples/api/ui/hide-tab-bar-red-dot.md`
- [x] uni.setTabBarStyle - ✅ 已创建示例文件 `examples/api/ui/set-tab-bar-style.md`
- [ ] uni.setTabBarItem
#### 位置服务 API
- [x] uni.getLocation - ✅ 已创建示例文件 `examples/api/location/get-location.md`
- [x] uni.openLocation - ✅ 已创建示例文件 `examples/api/location/open-location.md`
- [x] uni.chooseLocation - ✅ 已创建示例文件 `examples/api/location/choose-location.md`
#### 媒体处理 API
- [x] uni.chooseImage - ✅ 已创建示例文件 `examples/api/media/choose-image.md`
- [x] uni.previewImage - ✅ 已创建示例文件 `examples/api/media/preview-image.md`
- [x] uni.getImageInfo - ✅ 已创建示例文件 `examples/api/media/get-image-info.md`
- [x] uni.saveImageToPhotosAlbum - ✅ 已创建示例文件 `examples/api/media/save-image-to-photos-album.md`
- [x] uni.chooseVideo - ✅ 已创建示例文件 `examples/api/media/choose-video.md`
- [ ] uni.saveVideoToPhotosAlbum
- [x] uni.chooseMedia - ✅ 已创建示例文件 `examples/api/media/choose-media.md`
- [ ] uni.chooseFile
#### 页面路由 API
- [x] uni.navigateTo - ✅ 已创建示例文件 `examples/api/navigation/navigate-to.md`
- [x] uni.redirectTo - ✅ 已创建示例文件 `examples/api/navigation/redirect-to.md`
- [x] uni.reLaunch - ✅ 已创建示例文件 `examples/api/navigation/re-launch.md`
- [x] uni.switchTab - ✅ 已创建示例文件 `examples/api/navigation/switch-tab.md`
- [x] uni.navigateBack - ✅ 已创建示例文件 `examples/api/navigation/navigate-back.md`
#### 文件操作 API
- [x] uni.saveFile - ✅ 已创建示例文件 `examples/api/file/save-file.md`
- [x] uni.getFileInfo - ✅ 已创建示例文件 `examples/api/file/get-file-info.md`
- [x] uni.getSavedFileList - ✅ 已创建示例文件 `examples/api/file/get-saved-file-list.md`
- [ ] uni.getSavedFileInfo
- [ ] uni.removeSavedFile
#### 支付 API
- [ ] uni.requestPayment
#### 分享 API
- [ ] uni.share
#### 其他 API
- [ ] uni.canIUse
- [ ] uni.getProvider
- [ ] uni.login
- [ ] uni.getUserInfo
- [ ] uni.checkSession
- [ ] uni.authorize
- [ ] uni.openSetting
- [ ] uni.getSetting
**状态**: 🔄 进行中 - 已创建部分 API 独立示例文件(request.md, set-storage.md, get-storage.md, show-toast.md, show-modal.md, show-loading.md, navigate-to.md, navigate-back.md, choose-image.md, preview-image.md, get-location.md, get-system-info.md),需要继续创建其他 API 示例文件
### 4. uni-app-x 组件和 API 核对
**状态**: ❌ 需要创建完整的 uni-app-x 组件和 API 文档
### 5. 文档完整性检查
#### 每个组件文档应包含
- [ ] 组件概述
- [ ] 所有属性说明(类型、默认值、说明)
- [ ] 所有事件说明
- [ ] 插槽说明(如果有)
- [ ] 平台兼容性表格
- [ ] 使用示例(基础用法)
- [ ] 更多示例(官网全部示例)
- [ ] 官方文档链接
#### 每个 API 文档应包含
- [ ] API 概述
- [ ] 参数说明
- [ ] 返回值说明
- [ ] 平台兼容性
- [ ] 使用示例
- [ ] 官方文档链接
## 更新任务
### 优先级 1: 为每个 API 创建独立示例文件
**任务**: 在 `examples/api/` 目录下为每个 API 创建独立的示例文件
**进度**:
- ✅ 已创建: `examples/api/network/request.md`
- ✅ 已创建: `examples/api/storage/set-storage.md`
- ✅ 已创建: `examples/api/ui/show-toast.md`
- ✅ 已创建: `examples/api/navigation/navigate-to.md`
- ✅ 已创建: `examples/api/navigation/navigate-back.md`
- ✅ 已创建: `examples/api/media/choose-image.md`
- ✅ 已创建: `examples/api/media/preview-image.md`
- ✅ 已创建: `examples/api/location/get-location.md`
- ✅ 已创建: `examples/api/device/get-system-info.md`
- ✅ 已创建: `examples/api/storage/get-storage.md`
- ✅ 已创建: `examples/api/ui/show-modal.md`
- ✅ 已创建: `examples/api/ui/show-loading.md`
- ⏳ 待创建: 其他所有 API 示例文件(约40+个)
**需要创建的目录结构**:
```
examples/
├── api/
│ ├── network/
│ │ ├── request.md ✅
│ │ ├── upload-file.md ⏳
│ │ ├── download-file.md ⏳
│ │ └── websocket.md ⏳
│ ├── storage/
│ │ ├── set-storage.md ✅
│ │ ├── get-storage.md ⏳
│ │ └── ... ⏳
│ ├── device/ ⏳
│ ├── ui/
│ │ ├── show-toast.md ✅
│ │ └── ... ⏳
│ ├── location/ ⏳
│ ├── media/ ⏳
│ ├── navigation/ ⏳
│ ├── file/ ⏳
│ ├── payment/ ⏳
│ ├── share/ ⏳
│ └── other/ ⏳
```
### 优先级 2: 为每个内置组件创建独立示例文件
**任务**: 在 `examples/components/built-in/` 目录下为每个内置组件创建独立的示例文件
**进度**:
- ✅ 已创建: `examples/components/built-in/view.md`
- ✅ 已创建: `examples/components/built-in/scroll-view.md`
- ✅ 已创建: `examples/components/built-in/swiper.md`
- ✅ 已创建: `examples/components/built-in/text.md`
- ✅ 已创建: `examples/components/built-in/button.md`
- ✅ 已创建: `examples/components/built-in/input.md`
- ✅ 已创建: `examples/components/built-in/image.md`
- ⏳ 待创建: 其他33个内置组件示例文件
**当前进度统计**:
- API 示例文件: 47/50+ (约94%)
- 组件示例文件: 25/40 (62.5%)
**需要创建的目录结构**:
```
examples/
├── components/
│ ├── built-in/
│ │ ├── view.md ✅
│ │ ├── scroll-view.md ⏳
│ │ ├── swiper.md ⏳
│ │ └── ... (其他37个组件) ⏳
```
### 优先级 3: 创建 uni-app-x 完整文档
**任务**: 为 uniappx-project 创建完整的组件和 API 文档
**需要创建的目录结构**:
```
uniappx-project/
├── examples/
│ ├── components/
│ │ └── ... (所有 uni-app-x 组件)
│ └── api/
│ └── ... (所有 uni-app-x API)
├── api/
│ └── ... (API 参考文档)
└── templates/
```
### 优先级 4: 验证所有文档链接
**任务**: 检查所有组件和 API 文档中的官方文档链接是否正确
### 优先级 5: 补充缺失的 API
**任务**: 检查官方文档,找出所有 API,确保没有遗漏
## 核对进度
- [x] 内置组件文档完整性检查
- [x] uni-ui 组件文档完整性检查
- [ ] API 文档完整性检查
- [ ] 每个 API 独立示例文件检查
- [ ] 每个组件独立示例文件检查
- [ ] uni-app-x 文档完整性检查
- [ ] 官方文档链接验证
## 下一步行动
1. 先完成 API 独立示例文件的创建
2. 再完成内置组件独立示例文件的创建
3. 最后完成 uni-app-x 完整文档的创建
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2024 partme-ai
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+234
View File
@@ -0,0 +1,234 @@
---
name: uniapp-project
description: Provides comprehensive uni-app component and API integration guidance. Use when the user needs official uni-app components or APIs, wants per-component or per-API examples, or needs cross-platform compatibility details.
license: Complete terms in LICENSE.txt
---
## When to use this skill
Use this skill whenever the user wants to:
- Use any uni-app built-in component or uni-ui component
- Use any uni-app API (network, storage, device, UI, navigation, media, etc.)
- Access per-component or per-API examples with official doc links
- Check platform compatibility for components and APIs
- Build cross-platform uni-app applications with official patterns
## How to use this skill
This skill is organized to match the official uni-app components and API documentation:
1. **Choose component or API category**:
- Components → `examples/components/built-in/` and `examples/uni-ui/`
- APIs → `examples/api/` (categorized by domain)
2. **Open the matching example file**:
- Each component or API has its own example file
- Each example includes the official documentation URL
- Examples mirror the official documentation examples
3. **Use references when you need full specs**:
- `references/components/built-in/` for built-in components
- `references/components/uni-ui/` for uni-ui components
- `references/api/` for API parameter/return/compatibility details
## Examples and References
### Components (Built-in)
- Examples: `examples/components/built-in/*.md`
- References: `references/components/built-in/*.md`
- Official docs: https://uniapp.dcloud.net.cn/component/
### Components (uni-ui)
- Examples: `examples/uni-ui/*.vue` and `examples/uni-ui/README.md`
- References: `references/components/uni-ui/*.md`
- Official docs: https://uniapp.dcloud.net.cn/component/uniui/uni-ui.html
- Plugin: https://ext.dcloud.net.cn/plugin?id=55
### APIs
- Examples: `examples/api/{category}/*.md`
- References: `references/api/*.md`
- Official docs: https://uniapp.dcloud.net.cn/api/
## Best Practices
1. **One file per component/API**: Each component and API has an independent example file with official doc link.
2. **Follow platform compatibility**: Check the compatibility section in each example/reference.
3. **Use conditional compilation**: Use `#ifdef`/`#endif` for platform-specific logic.
4. **Keep examples aligned**: Use the official documentation examples as the source of truth.
5. **Prefer references for specs**: Use `references/` for full parameter tables and compatibility.
## Resources
- **Components**: https://uniapp.dcloud.net.cn/component/
- **APIs**: https://uniapp.dcloud.net.cn/api/
- **uni-ui**: https://uniapp.dcloud.net.cn/component/uniui/uni-ui.html
- **Plugin Market**: https://ext.dcloud.net.cn/
## Keywords
uniapp, uni-app, components, api, built-in components, uni-ui, examples, references, pages.json, manifest.json, H5, App, mini program, 跨平台, 组件, API, 官方文档
- `examples/api/network/` - 网络请求 API 示例
- `examples/api/storage/` - 数据存储 API 示例
- `examples/api/device/` - 设备信息 API 示例
- `examples/api/ui/` - 界面交互 API 示例
- `examples/api/location/` - 位置服务 API 示例
- `examples/api/media/` - 媒体处理 API 示例
- `examples/api/navigation/` - 页面路由 API 示例
- `examples/api/file/` - 文件操作 API 示例
- `examples/api/payment/` - 支付 API 示例
- `examples/api/share/` - 分享 API 示例
- `examples/api/other/` - 其他 API 示例
- `examples/uni-ui/` - uni-ui 组件的完整示例代码(每个组件一个独立的 .vue 文件)
**使用场景**:当需要查看组件或 API 的完整使用示例时,参考此目录下的示例文件。每个示例文件包含官网展示的所有示例场景,可直接复制使用。
**注意**
- references/ 和 examples/ 职责不同,不应合并。references/ 提供文档说明,examples/ 提供可运行代码。
- 每个组件和 API 都有独立的示例文件,包含原文档地址和官网全部示例
- 内置组件的示例代码在 `examples/components/built-in/` 目录
- API 的示例代码在 `examples/api/` 目录,按分类组织
- uni-ui 组件的完整示例代码在 `examples/uni-ui/` 目录
## 平台支持
uni-app 支持以下平台:
- **H5**Web 浏览器
- **微信小程序**WeChat Mini Program
- **支付宝小程序**Alipay Mini Program
- **百度小程序**Baidu Smart Program
- **字节跳动小程序**ByteDance Mini Program
- **QQ 小程序**QQ Mini Program
- **快手小程序**Kuaishou Mini Program
- **App**iOS、Androidnvue、vue
- **快应用**Quick App
每个组件和 API 的详细平台支持情况见对应文档。
## 参考资源
- **官方文档**https://uniapp.dcloud.net.cn/
- **组件文档**https://uniapp.dcloud.net.cn/component/
- **API 文档**https://uniapp.dcloud.net.cn/api/
- **插件市场**https://ext.dcloud.net.cn/
- **社区问答**https://ask.dcloud.net.cn/
## 使用示例
### 组件使用示例
基础组件使用示例:
```vue
<template>
<view class="container">
<text>{{ message }}</text>
<button @click="handleClick">点击按钮</button>
<image :src="imageUrl" mode="aspectFit"></image>
</view>
</template>
<script>
export default {
data() {
return {
message: 'Hello UniApp',
imageUrl: '/static/logo.png'
}
},
methods: {
handleClick() {
uni.showToast({
title: '按钮被点击',
icon: 'success'
})
}
}
}
</script>
```
**更多组件示例**
- **内置组件示例**:请参考[官方文档](https://uniapp.dcloud.net.cn/component/)或 `references/components/built-in/` 目录下的组件文档
- **uni-ui 组件完整示例**:见 `examples/uni-ui/` 目录(每个组件都有独立的 .vue 示例文件)
- **组件详细文档**:见 `references/components/built-in/``references/components/uni-ui/` 目录(每个组件都有独立的文档文件,包含属性、事件、平台兼容性、使用示例)
### API 使用示例
```javascript
// 网络请求
uni.request({
url: 'https://api.example.com/data',
method: 'GET',
success: (res) => {
console.log(res.data)
},
fail: (err) => {
console.error(err)
}
})
// 数据存储
uni.setStorage({
key: 'userInfo',
data: { name: 'John', age: 30 },
success: () => {
console.log('存储成功')
}
})
// 页面跳转
uni.navigateTo({
url: '/pages/detail/detail?id=123'
})
```
**更多 API 示例**:见 `references/api/` 目录中的详细文档
## 注意事项
1. **组件层级**:原生组件(如 video、map)层级高于普通组件,需要使用 cover-view 覆盖
2. **条件编译**:使用 `#ifdef``#endif` 处理平台差异
3. **生命周期**:注意 uni-app 的页面生命周期和组件生命周期
4. **样式单位**:推荐使用 rpx 作为响应式单位
5. **性能优化**:合理使用组件,避免过度嵌套,注意长列表优化
## 能力边界
### ✅ 适用场景
- 当你需要使用此技能对应的技术栈时
- 当项目需要遵循最佳实践时
- 当需要快速上手或深入理解核心概念时
### ⚠️ 需要注意
- 复杂业务逻辑需要结合具体场景调整
- 性能优化需要根据实际数据量评估
### ❌ 不适用场景
- 不相关的技术栈或框架
- 需要完全自定义的特殊场景
## 常见陷阱 (Gotchas)
1. **版本兼容性**:注意框架版本与依赖库的兼容性,不同版本 API 可能有差异
2. **配置文件格式**:配置文件格式错误是最常见的问题,建议使用编辑器的语法检查
3. **环境变量**:确保所有必要的环境变量已正确设置,敏感信息不要硬编码
4. **依赖冲突**:多版本共存时注意依赖冲突,使用 lock 文件锁定版本
5. **性能陷阱**:大数据量场景下注意性能优化,避免 N+1 查询等常见问题
## 使用流程
### Step 1: 环境准备
确保开发环境已安装必要的依赖和工具。
### Step 2: 配置初始化
根据项目需求进行基础配置。
### Step 3: 核心功能使用
按照示例代码实现核心功能。
### Step 4: 测试验证
运行测试确保功能正常。
### Step 5: 部署上线
完成开发后进行部署和监控。
@@ -0,0 +1,175 @@
# uni-app 技能更新计划
## 更新目标
确保所有 uni-app 相关技能与官方文档一一对应,每个组件和 API 都有独立的示例文件,包含原文档地址和官网全部示例。
## 当前进度
### ✅ 已完成
1. **核对清单创建**: 已创建 `CHECKLIST.md`,列出所有需要核对的内容
2. **目录结构创建**: 已创建 `examples/api/``examples/components/built-in/` 目录结构
3. **示例文件创建**:
-`examples/api/network/request.md` - uni.request 完整示例
-`examples/api/storage/set-storage.md` - uni.setStorage 完整示例
-`examples/api/ui/show-toast.md` - uni.showToast 完整示例
-`examples/components/built-in/view.md` - view 组件完整示例
4. **SKILL.md 更新**: 已更新 `SKILL.md`,添加对示例文件的引用说明
### 🔄 进行中
1. **API 示例文件创建**: 已创建3个,剩余约50+个待创建
2. **组件示例文件创建**: 已创建1个,剩余39个待创建
### ⏳ 待完成
1. **完成所有 API 示例文件** (约50+个文件)
2. **完成所有内置组件示例文件** (39个文件)
3. **创建 uni-app-x 完整文档** (组件 + API)
4. **验证所有文档链接**
5. **补充缺失的 API**
## 下一步行动
### 立即执行
1. **批量创建 API 示例文件**
- 优先创建常用 API: navigation, media, location, device
- 每个文件包含:官方文档链接、概述、基础用法、完整示例(官网全部示例)、平台差异、注意事项
2. **批量创建组件示例文件**
- 优先创建常用组件: button, input, image, scroll-view, swiper
- 每个文件包含:官方文档链接、概述、基础用法、完整示例(官网全部示例)、属性说明、平台兼容性
3. **创建示例文件模板**
- 为 API 和组件分别创建模板文件,便于批量生成
### 后续计划
1. **uni-app-x 文档创建**
- 创建 `uniappx-project` 的完整组件和 API 文档
- 参考 uni-app 的结构,但针对 uni-app-x 的特性
2. **文档链接验证**
- 检查所有文档中的官方链接是否正确
- 确保所有链接可访问
3. **完整性检查**
- 对照官方文档,确保没有遗漏任何组件或 API
- 检查每个示例文件是否包含官网全部示例
## 文件创建优先级
### 高优先级(立即创建)
**API 示例**:
- navigation: navigateTo, redirectTo, switchTab, navigateBack
- media: chooseImage, previewImage, chooseVideo
- location: getLocation, openLocation, chooseLocation
- device: getSystemInfo, getNetworkType
**组件示例**:
- button, input, image, scroll-view, swiper, text, icon
### 中优先级(后续创建)
**API 示例**:
- 其他网络 API: uploadFile, downloadFile, WebSocket
- 其他存储 API: getStorage, removeStorage, clearStorage
- 其他 UI API: showModal, showActionSheet, showLoading
- 文件 API: saveFile, getFileInfo
- 支付和分享 API
**组件示例**:
- 表单组件: checkbox, radio, picker, switch, textarea
- 媒体组件: video, audio, camera
- 其他组件: map, canvas, web-view
### 低优先级(最后创建)
- 不常用的 API 和组件
- 平台特定的 API 和组件
## 示例文件格式标准
每个示例文件应包含:
1. **标题和官方文档链接**
```markdown
# [组件/API名称] - [描述]
## 官方文档
参考官方文档:[链接]
```
2. **概述**
```markdown
## 概述
[简要说明组件/API的用途]
```
3. **基础用法**
```markdown
## 基础用法
[最简单的使用示例]
```
4. **完整示例**
```markdown
## 完整示例
### 示例 1: [场景描述]
[代码示例]
### 示例 2: [场景描述]
[代码示例]
...
```
5. **属性/参数说明**(如适用)
```markdown
## 属性说明
| 属性名 | 类型 | 默认值 | 说明 |
...
```
6. **平台兼容性**
```markdown
## 平台兼容性
| 平台 | 支持情况 |
...
```
7. **注意事项**
```markdown
## 注意事项
1. ...
2. ...
```
8. **参考资源**
```markdown
## 参考资源
- **官方文档**: [链接]
- **相关文档**: [链接]
```
## 质量检查清单
每个示例文件创建后,需要检查:
- [ ] 是否包含官方文档链接
- [ ] 是否包含基础用法示例
- [ ] 是否包含官网全部示例场景
- [ ] 代码示例是否可以直接运行
- [ ] 是否包含平台兼容性说明
- [ ] 是否包含注意事项
- [ ] 格式是否统一规范
## 预计工作量
- **API 示例文件**: 约50+个文件,每个文件约200-500行
- **组件示例文件**: 39个文件,每个文件约200-500行
- **uni-app-x 文档**: 组件 + API,约100+个文件
总计约200+个文件需要创建或更新。
@@ -0,0 +1,178 @@
# uni.getBatteryInfo - 获取电池信息示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/api/system/battery.html#getbatteryinfo
## 概述
`uni.getBatteryInfo` 用于获取设备电池信息。
## 基础用法
```javascript
uni.getBatteryInfo({
success: (res) => {
console.log('电池信息', res)
}
})
```
## 完整示例
### 示例 1: 获取电池信息
```javascript
uni.getBatteryInfo({
success: (res) => {
console.log('电池电量', res.level, '%')
console.log('是否正在充电', res.isCharging)
},
fail: (err) => {
console.error('获取失败', err)
}
})
```
### 示例 2: 在页面中使用
```vue
<template>
<view class="container">
<button @click="getBatteryInfo">获取电池信息</button>
<view v-if="batteryInfo" class="battery-info">
<text>电量{{ batteryInfo.level }}%</text>
<text>充电状态{{ batteryInfo.isCharging ? '充电中' : '未充电' }}</text>
</view>
</view>
</template>
<script>
export default {
data() {
return {
batteryInfo: null
}
},
methods: {
getBatteryInfo() {
uni.getBatteryInfo({
success: (res) => {
this.batteryInfo = res
},
fail: (err) => {
uni.showToast({
title: '获取失败',
icon: 'none'
})
}
})
}
}
}
</script>
```
### 示例 3: 低电量提醒
```javascript
function checkBatteryLevel() {
uni.getBatteryInfo({
success: (res) => {
if (res.level < 20 && !res.isCharging) {
uni.showModal({
title: '低电量提醒',
content: `当前电量仅剩${res.level}%,建议连接充电器`,
showCancel: false
})
}
}
})
}
// 定时检查
setInterval(checkBatteryLevel, 60000) // 每分钟检查一次
```
### 示例 4: 同步版本
```javascript
try {
const batteryInfo = uni.getBatteryInfoSync()
console.log('电池电量', batteryInfo.level, '%')
console.log('是否正在充电', batteryInfo.isCharging)
} catch (err) {
console.error('获取失败', err)
}
```
### 示例 5: 根据电量调整策略
```javascript
function getBatteryInfo() {
return new Promise((resolve, reject) => {
uni.getBatteryInfo({
success: (res) => {
resolve(res)
},
fail: (err) => {
reject(err)
}
})
})
}
// 根据电量决定是否执行耗电操作
async function performHeavyTask() {
const batteryInfo = await getBatteryInfo()
if (batteryInfo.level < 20 && !batteryInfo.isCharging) {
uni.showModal({
title: '提示',
content: '电量较低,建议连接充电器后再执行',
success: (res) => {
if (res.confirm) {
// 执行任务
console.log('执行任务')
}
}
})
} else {
// 直接执行
console.log('执行任务')
}
}
```
## 返回值
| 参数名 | 类型 | 说明 |
|--------|------|------|
| level | Number | 设备电量,范围 1 - 100 |
| isCharging | Boolean | 是否正在充电 |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ❌ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. H5 平台不支持此 API
2. `level` 范围是 1-100,表示电量百分比
3. `isCharging` 表示设备是否正在充电
4. 同步版本 `getBatteryInfoSync` 性能更好
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/api/system/battery.html#getbatteryinfo
- **同步版本**: https://uniapp.dcloud.net.cn/api/system/battery.html#getbatteryinfosync
@@ -0,0 +1,195 @@
# uni.getNetworkType - 获取网络类型示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/api/system/network.html#getnetworktype
## 概述
`uni.getNetworkType` 用于获取设备当前网络类型。
## 基础用法
```javascript
uni.getNetworkType({
success: (res) => {
console.log('网络类型', res.networkType)
}
})
```
## 完整示例
### 示例 1: 获取网络类型
```javascript
uni.getNetworkType({
success: (res) => {
console.log('网络类型', res.networkType)
// 可能的值:wifi、2g、3g、4g、5g、unknown、none
},
fail: (err) => {
console.error('获取失败', err)
}
})
```
### 示例 2: 检查网络状态
```javascript
function checkNetwork() {
uni.getNetworkType({
success: (res) => {
if (res.networkType === 'none') {
uni.showToast({
title: '网络不可用',
icon: 'none'
})
} else if (res.networkType === '2g' || res.networkType === '3g') {
uni.showModal({
title: '提示',
content: '当前网络较慢,建议使用WiFi',
showCancel: false
})
} else {
console.log('网络正常', res.networkType)
}
}
})
}
```
### 示例 3: 在页面中使用
```vue
<template>
<view class="container">
<button @click="checkNetwork">检查网络</button>
<view v-if="networkType" class="network-info">
<text>当前网络类型{{ networkType }}</text>
<text>网络状态{{ networkStatus }}</text>
</view>
</view>
</template>
<script>
export default {
data() {
return {
networkType: '',
networkStatus: ''
}
},
onLoad() {
this.checkNetwork()
},
methods: {
checkNetwork() {
uni.getNetworkType({
success: (res) => {
this.networkType = res.networkType
if (res.networkType === 'none') {
this.networkStatus = '无网络'
} else if (res.networkType === 'wifi') {
this.networkStatus = 'WiFi网络'
} else {
this.networkStatus = '移动网络'
}
}
})
}
}
}
</script>
```
### 示例 4: 监听网络状态变化
```javascript
// 监听网络状态变化
uni.onNetworkStatusChange((res) => {
console.log('网络类型', res.networkType)
console.log('是否联网', res.isConnected)
if (!res.isConnected) {
uni.showToast({
title: '网络已断开',
icon: 'none'
})
} else {
uni.showToast({
title: '网络已连接',
icon: 'success'
})
}
})
// 获取当前网络状态
uni.getNetworkType({
success: (res) => {
console.log('当前网络类型', res.networkType)
}
})
```
### 示例 5: 根据网络类型调整策略
```javascript
function getNetworkType() {
return new Promise((resolve, reject) => {
uni.getNetworkType({
success: (res) => {
resolve(res.networkType)
},
fail: (err) => {
reject(err)
}
})
})
}
// 根据网络类型决定是否加载高清图片
async function loadImage() {
const networkType = await getNetworkType()
if (networkType === 'wifi' || networkType === '4g' || networkType === '5g') {
// 加载高清图片
return 'https://example.com/hd-image.jpg'
} else {
// 加载压缩图片
return 'https://example.com/compressed-image.jpg'
}
}
```
## 返回值
| 参数名 | 类型 | 说明 |
|--------|------|------|
| networkType | String | 网络类型,可能的值:wifi、2g、3g、4g、5g、unknown、none |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. `networkType` 可能的值:wifi、2g、3g、4g、5g、unknown、none
2. `none` 表示无网络连接
3. 建议配合 `onNetworkStatusChange` 监听网络变化
4. 可以根据网络类型调整加载策略
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/api/system/network.html#getnetworktype
- **监听网络变化**: https://uniapp.dcloud.net.cn/api/system/network.html#onnetworkstatuschange
@@ -0,0 +1,192 @@
# uni.getScreenBrightness - 获取屏幕亮度示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/api/device/screen.html#getscreenbrightness
## 概述
`uni.getScreenBrightness` 用于获取屏幕亮度。
## 基础用法
```javascript
uni.getScreenBrightness({
success: (res) => {
console.log('屏幕亮度', res.value)
}
})
```
## 完整示例
### 示例 1: 获取屏幕亮度
```javascript
uni.getScreenBrightness({
success: (res) => {
console.log('屏幕亮度', res.value) // 范围 0 - 1
console.log('亮度百分比', (res.value * 100).toFixed(0) + '%')
},
fail: (err) => {
console.error('获取失败', err)
}
})
```
### 示例 2: 在页面中使用
```vue
<template>
<view class="container">
<button @click="getBrightness">获取屏幕亮度</button>
<view v-if="brightness !== null" class="brightness-info">
<text>当前亮度{{ (brightness * 100).toFixed(0) }}%</text>
</view>
</view>
</template>
<script>
export default {
data() {
return {
brightness: null
}
},
methods: {
getBrightness() {
uni.getScreenBrightness({
success: (res) => {
this.brightness = res.value
},
fail: (err) => {
uni.showToast({
title: '获取失败',
icon: 'none'
})
}
})
}
}
}
</script>
```
### 示例 3: 保存和恢复亮度
```vue
<template>
<view class="container">
<slider
:value="brightness * 100"
min="0"
max="100"
@change="handleBrightnessChange"
/>
<button @click="saveBrightness">保存亮度</button>
<button @click="restoreBrightness">恢复亮度</button>
</view>
</template>
<script>
export default {
data() {
return {
brightness: 0.5,
savedBrightness: 0.5
}
},
onLoad() {
this.getBrightness()
// 加载保存的亮度
const saved = uni.getStorageSync('screenBrightness')
if (saved) {
this.savedBrightness = saved
}
},
methods: {
getBrightness() {
uni.getScreenBrightness({
success: (res) => {
this.brightness = res.value
}
})
},
handleBrightnessChange(e) {
this.brightness = e.detail.value / 100
uni.setScreenBrightness({
value: this.brightness
})
},
saveBrightness() {
this.savedBrightness = this.brightness
uni.setStorageSync('screenBrightness', this.brightness)
uni.showToast({
title: '已保存',
icon: 'success'
})
},
restoreBrightness() {
this.brightness = this.savedBrightness
uni.setScreenBrightness({
value: this.brightness
})
uni.showToast({
title: '已恢复',
icon: 'success'
})
}
}
}
</script>
```
### 示例 4: 检查亮度设置
```javascript
function checkBrightness() {
uni.getScreenBrightness({
success: (res) => {
if (res.value < 0.3) {
console.log('屏幕较暗')
} else if (res.value > 0.8) {
console.log('屏幕较亮')
} else {
console.log('屏幕亮度适中')
}
}
})
}
```
## 返回值
| 参数名 | 类型 | 说明 |
|--------|------|------|
| value | Number | 屏幕亮度值,范围 0 - 1 |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ❌ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. H5 平台不支持此 API
2. `value` 范围是 0-1,0 表示最暗,1 表示最亮
3. 可以配合 `setScreenBrightness` 使用
4. 建议在设置亮度前先获取当前亮度
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/api/device/screen.html#getscreenbrightness
- **设置亮度**: https://uniapp.dcloud.net.cn/api/device/screen.html#setscreenbrightness
@@ -0,0 +1,209 @@
# uni.getSystemInfo - 获取系统信息示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/api/system/info.html#getsysteminfo
## 概述
`uni.getSystemInfo` 用于获取系统信息,包括设备信息、屏幕信息等。
## 基础用法
```javascript
uni.getSystemInfo({
success: (res) => {
console.log('系统信息', res)
}
})
```
## 完整示例
### 示例 1: 获取系统信息
```javascript
uni.getSystemInfo({
success: (res) => {
console.log('手机品牌', res.brand)
console.log('手机型号', res.model)
console.log('系统版本', res.system)
console.log('平台', res.platform)
console.log('屏幕宽度', res.windowWidth)
console.log('屏幕高度', res.windowHeight)
}
})
```
### 示例 2: 同步获取系统信息
```javascript
try {
const systemInfo = uni.getSystemInfoSync()
console.log('系统信息', systemInfo)
} catch (err) {
console.error('获取失败', err)
}
```
### 示例 3: 在页面中使用
```vue
<template>
<view class="container">
<button @click="getSystemInfo">获取系统信息</button>
<view v-if="systemInfo" class="info-list">
<view class="info-item">
<text class="label">手机品牌</text>
<text>{{ systemInfo.brand }}</text>
</view>
<view class="info-item">
<text class="label">手机型号</text>
<text>{{ systemInfo.model }}</text>
</view>
<view class="info-item">
<text class="label">系统版本</text>
<text>{{ systemInfo.system }}</text>
</view>
<view class="info-item">
<text class="label">平台</text>
<text>{{ systemInfo.platform }}</text>
</view>
<view class="info-item">
<text class="label">屏幕宽度</text>
<text>{{ systemInfo.windowWidth }}px</text>
</view>
<view class="info-item">
<text class="label">屏幕高度</text>
<text>{{ systemInfo.windowHeight }}px</text>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
systemInfo: null
}
},
onLoad() {
this.getSystemInfo()
},
methods: {
getSystemInfo() {
uni.getSystemInfo({
success: (res) => {
this.systemInfo = res
}
})
}
}
}
</script>
<style>
.info-list {
margin-top: 20px;
padding: 20px;
background-color: #f5f5f5;
border-radius: 8px;
}
.info-item {
padding: 10px 0;
border-bottom: 1px solid #eee;
}
.label {
font-weight: bold;
color: #333;
}
</style>
```
### 示例 4: 适配不同屏幕
```vue
<template>
<view class="container" :style="containerStyle">
<text>自适应内容</text>
</view>
</template>
<script>
export default {
data() {
return {
containerStyle: {}
}
},
onLoad() {
const systemInfo = uni.getSystemInfoSync()
this.containerStyle = {
width: systemInfo.windowWidth + 'px',
height: systemInfo.windowHeight + 'px'
}
}
}
</script>
```
### 示例 5: 判断平台
```javascript
const systemInfo = uni.getSystemInfoSync()
// 判断平台
if (systemInfo.platform === 'ios') {
console.log('iOS 平台')
} else if (systemInfo.platform === 'android') {
console.log('Android 平台')
}
// 判断是否为 App
if (systemInfo.platform !== 'devtools') {
console.log('非开发工具环境')
}
```
## 返回值说明
| 参数名 | 类型 | 说明 |
|--------|------|------|
| brand | String | 手机品牌 |
| model | String | 手机型号 |
| system | String | 操作系统版本 |
| platform | String | 客户端平台 |
| windowWidth | Number | 窗口宽度 |
| windowHeight | Number | 窗口高度 |
| pixelRatio | Number | 设备像素比 |
| screenWidth | Number | 屏幕宽度 |
| screenHeight | Number | 屏幕高度 |
| statusBarHeight | Number | 状态栏高度 |
| safeArea | Object | 安全区域 |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. 建议在 `onLoad` 中获取系统信息
2. 同步版本 `getSystemInfoSync` 性能更好
3. 不同平台返回的信息可能不同
4. 使用 `windowWidth``windowHeight` 进行屏幕适配
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/api/system/info.html#getsysteminfo
- **同步版本**: https://uniapp.dcloud.net.cn/api/system/info.html#getsysteminfosync
@@ -0,0 +1,195 @@
# uni.setScreenBrightness - 设置屏幕亮度示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/api/device/screen.html#setscreenbrightness
## 概述
`uni.setScreenBrightness` 用于设置屏幕亮度。
## 基础用法
```javascript
uni.setScreenBrightness({
value: 0.5
})
```
## 完整示例
### 示例 1: 设置屏幕亮度
```javascript
uni.setScreenBrightness({
value: 0.5, // 亮度值,范围 0 - 1
success: () => {
console.log('设置成功')
},
fail: (err) => {
console.error('设置失败', err)
}
})
```
### 示例 2: 在页面中使用
```vue
<template>
<view class="container">
<slider
:value="brightness * 100"
min="0"
max="100"
@change="handleBrightnessChange"
/>
<text>亮度{{ (brightness * 100).toFixed(0) }}%</text>
</view>
</template>
<script>
export default {
data() {
return {
brightness: 0.5
}
},
onLoad() {
this.getBrightness()
},
methods: {
getBrightness() {
uni.getScreenBrightness({
success: (res) => {
this.brightness = res.value
}
})
},
handleBrightnessChange(e) {
this.brightness = e.detail.value / 100
uni.setScreenBrightness({
value: this.brightness,
success: () => {
console.log('亮度已设置')
}
})
}
}
}
</script>
```
### 示例 3: 自动调节亮度
```javascript
function autoAdjustBrightness() {
// 获取当前时间
const hour = new Date().getHours()
// 晚上(18:00-6:00)降低亮度
if (hour >= 18 || hour < 6) {
uni.setScreenBrightness({
value: 0.3 // 较暗
})
} else {
uni.setScreenBrightness({
value: 0.8 // 较亮
})
}
}
```
### 示例 4: 护眼模式
```vue
<template>
<view class="container">
<switch :checked="eyeProtectionMode" @change="toggleEyeProtection" />
<text>护眼模式</text>
</view>
</template>
<script>
export default {
data() {
return {
eyeProtectionMode: false,
originalBrightness: 0.5
}
},
methods: {
toggleEyeProtection(e) {
this.eyeProtectionMode = e.detail.value
if (this.eyeProtectionMode) {
// 保存当前亮度
uni.getScreenBrightness({
success: (res) => {
this.originalBrightness = res.value
}
})
// 降低亮度
uni.setScreenBrightness({
value: 0.3
})
} else {
// 恢复原亮度
uni.setScreenBrightness({
value: this.originalBrightness
})
}
}
}
}
</script>
```
### 示例 5: 根据环境光调节
```javascript
// 注意:此功能需要配合其他API实现
function adjustBrightnessByAmbient() {
// 获取环境光强度(需要其他API支持)
// 这里只是示例逻辑
const ambientLight = 0.5 // 假设获取到的环境光强度
// 根据环境光设置屏幕亮度
const screenBrightness = Math.max(0.2, Math.min(1.0, ambientLight))
uni.setScreenBrightness({
value: screenBrightness
})
}
```
## 参数说明
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| value | Number | 是 | 屏幕亮度值,范围 0 - 1,0 最暗,1 最亮 |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ❌ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. H5 平台不支持此 API
2. `value` 范围是 0-1,0 表示最暗,1 表示最亮
3. 设置后立即生效
4. 建议在用户退出应用时恢复系统默认亮度
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/api/device/screen.html#setscreenbrightness
- **获取亮度**: https://uniapp.dcloud.net.cn/api/device/screen.html#getscreenbrightness
@@ -0,0 +1,232 @@
# uni.getFileInfo - 获取文件信息示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/api/file/file.html#getfileinfo
## 概述
`uni.getFileInfo` 用于获取文件信息。
## 基础用法
```javascript
uni.getFileInfo({
filePath: 'file_path',
success: (res) => {
console.log('文件大小', res.size)
}
})
```
## 完整示例
### 示例 1: 获取文件信息
```javascript
uni.getFileInfo({
filePath: 'file_path',
success: (res) => {
console.log('文件大小', res.size, '字节')
console.log('文件大小(KB', (res.size / 1024).toFixed(2), 'KB')
console.log('文件大小(MB', (res.size / 1024 / 1024).toFixed(2), 'MB')
},
fail: (err) => {
console.error('获取失败', err)
}
})
```
### 示例 2: 检查文件大小
```javascript
function checkFileSize(filePath) {
return new Promise((resolve, reject) => {
uni.getFileInfo({
filePath: filePath,
success: (res) => {
const sizeInMB = res.size / 1024 / 1024
if (sizeInMB > 10) {
uni.showModal({
title: '提示',
content: `文件大小 ${sizeInMB.toFixed(2)}MB,超过10MB,建议压缩后上传`,
showCancel: false
})
}
resolve(res)
},
fail: (err) => {
reject(err)
}
})
})
}
// 使用
checkFileSize('file_path').then(res => {
console.log('文件信息', res)
})
```
### 示例 3: 在页面中使用
```vue
<template>
<view class="container">
<button @click="chooseAndCheckFile">选择文件并检查</button>
<view v-if="fileInfo" class="file-info">
<text>文件大小{{ formatFileSize(fileInfo.size) }}</text>
</view>
</view>
</template>
<script>
export default {
data() {
return {
fileInfo: null
}
},
methods: {
chooseAndCheckFile() {
uni.chooseFile({
count: 1,
success: (res) => {
const filePath = res.tempFiles[0].path
this.getFileInfo(filePath)
}
})
},
getFileInfo(filePath) {
uni.getFileInfo({
filePath: filePath,
success: (res) => {
this.fileInfo = res
},
fail: (err) => {
uni.showToast({
title: '获取失败',
icon: 'none'
})
}
})
},
formatFileSize(size) {
if (size < 1024) {
return size + ' B'
} else if (size < 1024 * 1024) {
return (size / 1024).toFixed(2) + ' KB'
} else {
return (size / 1024 / 1024).toFixed(2) + ' MB'
}
}
}
}
</script>
```
### 示例 4: 上传前检查文件大小
```javascript
function uploadFileWithSizeCheck(filePath) {
uni.getFileInfo({
filePath: filePath,
success: (res) => {
const maxSize = 10 * 1024 * 1024 // 10MB
if (res.size > maxSize) {
uni.showModal({
title: '提示',
content: `文件大小 ${(res.size / 1024 / 1024).toFixed(2)}MB,超过限制`,
showCancel: false
})
return
}
// 上传文件
uni.uploadFile({
url: 'https://api.example.com/upload',
filePath: filePath,
name: 'file',
success: (uploadRes) => {
console.log('上传成功', uploadRes)
}
})
}
})
}
```
### 示例 5: 获取多个文件信息
```javascript
function getMultipleFileInfo(filePaths) {
const fileInfoList = []
let completedCount = 0
filePaths.forEach((filePath, index) => {
uni.getFileInfo({
filePath: filePath,
success: (res) => {
fileInfoList[index] = {
path: filePath,
size: res.size
}
completedCount++
if (completedCount === filePaths.length) {
console.log('所有文件信息', fileInfoList)
const totalSize = fileInfoList.reduce((sum, info) => sum + info.size, 0)
console.log('总大小', (totalSize / 1024 / 1024).toFixed(2), 'MB')
}
}
})
})
}
// 使用
uni.chooseFile({
count: 5,
success: (res) => {
const filePaths = res.tempFiles.map(file => file.path)
getMultipleFileInfo(filePaths)
}
})
```
## 参数说明
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| filePath | String | 是 | 文件路径 |
## 返回值
| 参数名 | 类型 | 说明 |
|--------|------|------|
| size | Number | 文件大小,单位:字节 |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ❌ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. H5 平台不支持此 API
2. `size` 单位是字节(bytes
3. 可以通过 `size` 判断文件大小,进行上传限制
4. 建议在上传前检查文件大小
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/api/file/file.html#getfileinfo
@@ -0,0 +1,347 @@
# uni.getSavedFileList - 获取已保存的文件列表示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/api/file/file.html#getsavedfilelist
## 概述
`uni.getSavedFileList` 用于获取本地已保存的文件列表。
## 基础用法
```javascript
uni.getSavedFileList({
success: (res) => {
console.log('文件列表', res.fileList)
}
})
```
## 完整示例
### 示例 1: 获取文件列表
```javascript
uni.getSavedFileList({
success: (res) => {
console.log('文件数量', res.fileList.length)
res.fileList.forEach((file, index) => {
console.log(`文件${index + 1}:`, file.filePath)
console.log(`大小:`, file.size, '字节')
console.log(`创建时间:`, new Date(file.createTime))
})
},
fail: (err) => {
console.error('获取失败', err)
}
})
```
### 示例 2: 在页面中使用
```vue
<template>
<view class="container">
<button @click="getFileList">获取文件列表</button>
<view v-if="fileList.length > 0" class="file-list">
<view
v-for="(file, index) in fileList"
:key="index"
class="file-item"
>
<text class="file-path">{{ file.filePath }}</text>
<text class="file-size">大小{{ formatFileSize(file.size) }}</text>
<text class="file-time">创建时间{{ formatTime(file.createTime) }}</text>
<button @click="removeFile(file.filePath)">删除</button>
</view>
</view>
<view v-else class="empty">
<text>暂无保存的文件</text>
</view>
</view>
</template>
<script>
export default {
data() {
return {
fileList: []
}
},
onLoad() {
this.getFileList()
},
methods: {
getFileList() {
uni.getSavedFileList({
success: (res) => {
this.fileList = res.fileList
},
fail: (err) => {
uni.showToast({
title: '获取失败',
icon: 'none'
})
}
})
},
removeFile(filePath) {
uni.removeSavedFile({
filePath: filePath,
success: () => {
uni.showToast({
title: '删除成功',
icon: 'success'
})
this.getFileList()
}
})
},
formatFileSize(size) {
if (size < 1024) {
return size + ' B'
} else if (size < 1024 * 1024) {
return (size / 1024).toFixed(2) + ' KB'
} else {
return (size / 1024 / 1024).toFixed(2) + ' MB'
}
},
formatTime(timestamp) {
const date = new Date(timestamp)
return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')} ${String(date.getHours()).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')}`
}
}
}
</script>
<style>
.file-list {
margin-top: 20px;
}
.file-item {
padding: 20px;
border-bottom: 1px solid #eee;
}
.file-path {
display: block;
font-size: 28rpx;
color: #333;
margin-bottom: 10px;
}
.file-size, .file-time {
display: block;
font-size: 24rpx;
color: #666;
margin-bottom: 5px;
}
</style>
```
### 示例 3: 计算总文件大小
```javascript
function getTotalFileSize() {
return new Promise((resolve, reject) => {
uni.getSavedFileList({
success: (res) => {
const totalSize = res.fileList.reduce((sum, file) => sum + file.size, 0)
const totalSizeMB = (totalSize / 1024 / 1024).toFixed(2)
console.log('总文件大小', totalSizeMB, 'MB')
resolve({
fileList: res.fileList,
totalSize: totalSize,
totalSizeMB: totalSizeMB
})
},
fail: (err) => {
reject(err)
}
})
})
}
// 使用
getTotalFileSize().then(result => {
console.log('文件统计', result)
})
```
### 示例 4: 清理旧文件
```javascript
function cleanOldFiles(maxAge = 7 * 24 * 60 * 60 * 1000) {
// maxAge: 最大保留时间(毫秒),默认7天
uni.getSavedFileList({
success: (res) => {
const now = Date.now()
let deletedCount = 0
res.fileList.forEach(file => {
if (now - file.createTime > maxAge) {
uni.removeSavedFile({
filePath: file.filePath,
success: () => {
deletedCount++
console.log('已删除旧文件', file.filePath)
}
})
}
})
setTimeout(() => {
uni.showToast({
title: `已清理${deletedCount}个文件`,
icon: 'success'
})
}, 1000)
}
})
}
// 使用:清理7天前的文件
cleanOldFiles()
```
### 示例 5: 文件管理
```vue
<template>
<view class="container">
<view class="header">
<text>文件管理</text>
<text class="total-size">总大小{{ totalSizeMB }}MB</text>
</view>
<view class="file-list">
<view
v-for="(file, index) in fileList"
:key="index"
class="file-item"
>
<view class="file-info">
<text class="file-name">{{ getFileName(file.filePath) }}</text>
<text class="file-detail">{{ formatFileSize(file.size) }} · {{ formatTime(file.createTime) }}</text>
</view>
<view class="file-actions">
<button size="mini" @click="previewFile(file)">预览</button>
<button size="mini" @click="removeFile(file.filePath)">删除</button>
</view>
</view>
</view>
<button @click="clearAllFiles" class="clear-btn">清空所有文件</button>
</view>
</template>
<script>
export default {
data() {
return {
fileList: [],
totalSizeMB: '0.00'
}
},
onLoad() {
this.getFileList()
},
methods: {
getFileList() {
uni.getSavedFileList({
success: (res) => {
this.fileList = res.fileList
const totalSize = res.fileList.reduce((sum, file) => sum + file.size, 0)
this.totalSizeMB = (totalSize / 1024 / 1024).toFixed(2)
}
})
},
getFileName(filePath) {
return filePath.split('/').pop()
},
removeFile(filePath) {
uni.removeSavedFile({
filePath: filePath,
success: () => {
this.getFileList()
}
})
},
clearAllFiles() {
uni.showModal({
title: '确认',
content: '确定要清空所有文件吗?',
success: (res) => {
if (res.confirm) {
this.fileList.forEach(file => {
uni.removeSavedFile({
filePath: file.filePath
})
})
setTimeout(() => {
this.getFileList()
}, 500)
}
}
})
},
previewFile(file) {
// 根据文件类型预览
if (file.filePath.endsWith('.jpg') || file.filePath.endsWith('.png')) {
uni.previewImage({
urls: [file.filePath]
})
} else {
uni.showToast({
title: '暂不支持预览此类型文件',
icon: 'none'
})
}
},
formatFileSize(size) {
if (size < 1024) {
return size + ' B'
} else if (size < 1024 * 1024) {
return (size / 1024).toFixed(2) + ' KB'
} else {
return (size / 1024 / 1024).toFixed(2) + ' MB'
}
},
formatTime(timestamp) {
const date = new Date(timestamp)
return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`
}
}
}
</script>
```
## 返回值
| 参数名 | 类型 | 说明 |
|--------|------|------|
| fileList | Array | 文件列表,每个文件包含 filePath、size、createTime |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ❌ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. H5 平台不支持此 API
2. 返回的文件列表包含通过 `uni.saveFile` 保存的文件
3. 可以通过 `createTime` 判断文件创建时间
4. 建议定期清理不需要的文件
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/api/file/file.html#getsavedfilelist
- **保存文件**: https://uniapp.dcloud.net.cn/api/file/file.html#savefile
- **删除文件**: https://uniapp.dcloud.net.cn/api/file/file.html#removesavedfile
@@ -0,0 +1,223 @@
# uni.saveFile - 保存文件示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/api/file/file.html#savefile
## 概述
`uni.saveFile` 用于保存文件到本地。
## 基础用法
```javascript
uni.saveFile({
tempFilePath: 'temp_file_path',
success: (res) => {
console.log('保存成功', res.savedFilePath)
}
})
```
## 完整示例
### 示例 1: 保存临时文件
```javascript
uni.saveFile({
tempFilePath: 'temp_file_path',
success: (res) => {
console.log('保存成功', res.savedFilePath)
uni.showToast({
title: '保存成功',
icon: 'success'
})
},
fail: (err) => {
console.error('保存失败', err)
}
})
```
### 示例 2: 保存下载的文件
```javascript
uni.downloadFile({
url: 'https://example.com/file.pdf',
success: (res) => {
if (res.statusCode === 200) {
// 保存下载的文件
uni.saveFile({
tempFilePath: res.tempFilePath,
success: (saveRes) => {
console.log('文件已保存', saveRes.savedFilePath)
}
})
}
}
})
```
### 示例 3: 保存图片到本地
```javascript
uni.chooseImage({
count: 1,
success: (res) => {
const tempFilePath = res.tempFilePaths[0]
// 保存图片
uni.saveFile({
tempFilePath: tempFilePath,
success: (saveRes) => {
console.log('图片已保存', saveRes.savedFilePath)
uni.showToast({
title: '保存成功',
icon: 'success'
})
}
})
}
})
```
### 示例 4: 在页面中使用
```vue
<template>
<view class="container">
<button @click="downloadAndSave">下载并保存文件</button>
<view v-if="savedFilePath" class="file-info">
<text>文件已保存{{ savedFilePath }}</text>
</view>
</view>
</template>
<script>
export default {
data() {
return {
savedFilePath: ''
}
},
methods: {
downloadAndSave() {
uni.showLoading({
title: '下载中...'
})
uni.downloadFile({
url: 'https://example.com/file.pdf',
success: (res) => {
if (res.statusCode === 200) {
uni.saveFile({
tempFilePath: res.tempFilePath,
success: (saveRes) => {
this.savedFilePath = saveRes.savedFilePath
uni.hideLoading()
uni.showToast({
title: '保存成功',
icon: 'success'
})
},
fail: (err) => {
uni.hideLoading()
uni.showToast({
title: '保存失败',
icon: 'none'
})
}
})
}
},
fail: (err) => {
uni.hideLoading()
uni.showToast({
title: '下载失败',
icon: 'none'
})
}
})
}
}
}
</script>
```
### 示例 5: 保存多个文件
```javascript
function saveMultipleFiles(tempFilePaths) {
const savedFilePaths = []
let completedCount = 0
tempFilePaths.forEach((tempFilePath, index) => {
uni.saveFile({
tempFilePath: tempFilePath,
success: (res) => {
savedFilePaths[index] = res.savedFilePath
completedCount++
if (completedCount === tempFilePaths.length) {
console.log('所有文件已保存', savedFilePaths)
uni.showToast({
title: '全部保存成功',
icon: 'success'
})
}
},
fail: (err) => {
console.error(`文件${index + 1}保存失败`, err)
completedCount++
}
})
})
}
// 使用
uni.chooseImage({
count: 3,
success: (res) => {
saveMultipleFiles(res.tempFilePaths)
}
})
```
## 参数说明
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| tempFilePath | String | 是 | 需要保存的文件的临时路径 |
## 返回值
| 参数名 | 类型 | 说明 |
|--------|------|------|
| savedFilePath | String | 文件的保存路径 |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ❌ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. H5 平台不支持此 API
2. 保存的文件可以通过 `uni.getSavedFileList` 获取列表
3. 保存的文件可以通过 `uni.removeSavedFile` 删除
4. 建议在保存前检查文件大小
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/api/file/file.html#savefile
- **获取文件列表**: https://uniapp.dcloud.net.cn/api/file/file.html#getsavedfilelist
- **删除文件**: https://uniapp.dcloud.net.cn/api/file/file.html#removesavedfile
@@ -0,0 +1,299 @@
# uni.chooseLocation - 选择位置示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/api/location/choose-location.html#chooselocation
## 概述
`uni.chooseLocation` 用于打开地图选择位置。
## 基础用法
```javascript
uni.chooseLocation({
success: (res) => {
console.log('选择的位置', res.name, res.address)
}
})
```
## 完整示例
### 示例 1: 基本选择位置
```javascript
uni.chooseLocation({
success: (res) => {
console.log('位置名称', res.name)
console.log('详细地址', res.address)
console.log('纬度', res.latitude)
console.log('经度', res.longitude)
},
fail: (err) => {
console.error('选择失败', err)
}
})
```
### 示例 2: 在页面中使用
```vue
<template>
<view class="container">
<button @click="chooseLocation">选择位置</button>
<view v-if="location" class="location-info">
<text>位置{{ location.name }}</text>
<text>地址{{ location.address }}</text>
<text>坐标{{ location.latitude }}, {{ location.longitude }}</text>
</view>
</view>
</template>
<script>
export default {
data() {
return {
location: null
}
},
methods: {
chooseLocation() {
uni.chooseLocation({
success: (res) => {
this.location = res
uni.showToast({
title: '选择成功',
icon: 'success'
})
},
fail: (err) => {
if (err.errMsg.includes('auth deny')) {
uni.showModal({
title: '提示',
content: '需要位置权限才能选择位置',
success: (modalRes) => {
if (modalRes.confirm) {
uni.openSetting()
}
}
})
} else {
uni.showToast({
title: '选择失败',
icon: 'none'
})
}
}
})
}
}
}
</script>
```
### 示例 3: 选择收货地址
```vue
<template>
<view class="container">
<view class="address-item" @click="chooseAddress">
<view v-if="address">
<text class="address-name">{{ address.name }}</text>
<text class="address-detail">{{ address.address }}</text>
</view>
<view v-else>
<text>请选择收货地址</text>
</view>
<text class="arrow">></text>
</view>
</view>
</template>
<script>
export default {
data() {
return {
address: null
}
},
methods: {
chooseAddress() {
uni.chooseLocation({
success: (res) => {
this.address = {
name: res.name,
address: res.address,
latitude: res.latitude,
longitude: res.longitude
}
// 保存地址
uni.setStorageSync('deliveryAddress', this.address)
}
})
}
},
onLoad() {
// 加载保存的地址
const savedAddress = uni.getStorageSync('deliveryAddress')
if (savedAddress) {
this.address = savedAddress
}
}
}
</script>
<style>
.address-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 20px;
border-bottom: 1px solid #eee;
}
.address-name {
display: block;
font-size: 32rpx;
font-weight: bold;
margin-bottom: 10rpx;
}
.address-detail {
display: block;
font-size: 28rpx;
color: #999;
}
.arrow {
color: #999;
}
</style>
```
### 示例 4: 检查权限
```javascript
function chooseLocationWithPermission() {
// 先检查权限
uni.getSetting({
success: (res) => {
if (res.authSetting['scope.userLocation']) {
// 已授权,直接选择
chooseLocation()
} else {
// 请求授权
uni.authorize({
scope: 'scope.userLocation',
success: () => {
chooseLocation()
},
fail: () => {
uni.showModal({
title: '提示',
content: '需要位置权限才能选择位置',
success: (modalRes) => {
if (modalRes.confirm) {
uni.openSetting()
}
}
})
}
})
}
}
})
}
function chooseLocation() {
uni.chooseLocation({
success: (res) => {
console.log('选择的位置', res)
}
})
}
```
### 示例 5: 在地图上显示选择的位置
```vue
<template>
<view class="container">
<button @click="chooseLocation">选择位置</button>
<map
v-if="location"
:latitude="location.latitude"
:longitude="location.longitude"
:markers="markers"
class="map"
></map>
</view>
</template>
<script>
export default {
data() {
return {
location: null,
markers: []
}
},
methods: {
chooseLocation() {
uni.chooseLocation({
success: (res) => {
this.location = res
this.markers = [{
id: 1,
latitude: res.latitude,
longitude: res.longitude,
title: res.name
}]
}
})
}
}
}
</script>
<style>
.map {
width: 100%;
height: 500px;
margin-top: 20px;
}
</style>
```
## 返回值
| 参数名 | 类型 | 说明 |
|--------|------|------|
| name | String | 位置名称 |
| address | String | 详细地址 |
| latitude | Number | 纬度 |
| longitude | Number | 经度 |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ❌ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. 需要用户授权位置权限
2. H5 平台不支持此 API
3. 选择的位置包含名称、地址和坐标信息
4. 建议在需要时再请求权限
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/api/location/choose-location.html#chooselocation
- **获取位置**: https://uniapp.dcloud.net.cn/api/location/location.html#getlocation
- **打开地图**: https://uniapp.dcloud.net.cn/api/location/open-location.html#openlocation
@@ -0,0 +1,243 @@
# uni.getLocation - 获取位置示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/api/location/location.html#getlocation
## 概述
`uni.getLocation` 用于获取当前地理位置。
## 基础用法
```javascript
uni.getLocation({
type: 'wgs84',
success: (res) => {
console.log('当前位置', res.latitude, res.longitude)
}
})
```
## 完整示例
### 示例 1: 获取当前位置
```javascript
uni.getLocation({
type: 'wgs84',
success: (res) => {
console.log('纬度', res.latitude)
console.log('经度', res.longitude)
console.log('速度', res.speed)
console.log('精度', res.accuracy)
},
fail: (err) => {
console.error('获取位置失败', err)
}
})
```
### 示例 2: 高精度定位
```javascript
uni.getLocation({
type: 'gcj02',
altitude: true,
geocode: true,
success: (res) => {
console.log('位置信息', res)
// res.address 包含地址信息(需要 geocode: true
}
})
```
### 示例 3: 在页面中使用
```vue
<template>
<view class="container">
<button @click="getCurrentLocation">获取当前位置</button>
<view v-if="location" class="location-info">
<text>纬度{{ location.latitude }}</text>
<text>经度{{ location.longitude }}</text>
<text>地址{{ location.address || '未获取' }}</text>
</view>
</view>
</template>
<script>
export default {
data() {
return {
location: null
}
},
methods: {
getCurrentLocation() {
uni.showLoading({
title: '定位中...'
})
uni.getLocation({
type: 'gcj02',
geocode: true,
success: (res) => {
this.location = res
uni.hideLoading()
uni.showToast({
title: '定位成功',
icon: 'success'
})
},
fail: (err) => {
uni.hideLoading()
uni.showToast({
title: '定位失败',
icon: 'none'
})
console.error('定位失败', err)
}
})
}
}
}
</script>
```
### 示例 4: 检查定位权限
```javascript
// 先检查定位权限
uni.getSetting({
success: (res) => {
if (res.authSetting['scope.userLocation']) {
// 已授权,直接获取位置
uni.getLocation({
type: 'gcj02',
success: (res) => {
console.log('位置', res)
}
})
} else {
// 未授权,请求授权
uni.authorize({
scope: 'scope.userLocation',
success: () => {
uni.getLocation({
type: 'gcj02',
success: (res) => {
console.log('位置', res)
}
})
},
fail: () => {
uni.showModal({
title: '提示',
content: '需要定位权限才能使用此功能',
showCancel: false
})
}
})
}
}
})
```
### 示例 5: 在地图上显示位置
```vue
<template>
<view class="container">
<button @click="getLocationAndShow">获取位置并显示</button>
<map
v-if="location"
:latitude="location.latitude"
:longitude="location.longitude"
:markers="markers"
class="map"
></map>
</view>
</template>
<script>
export default {
data() {
return {
location: null,
markers: []
}
},
methods: {
getLocationAndShow() {
uni.getLocation({
type: 'gcj02',
success: (res) => {
this.location = res
this.markers = [{
id: 1,
latitude: res.latitude,
longitude: res.longitude,
title: '我的位置'
}]
}
})
}
}
}
</script>
<style>
.map {
width: 100%;
height: 500px;
margin-top: 20px;
}
</style>
```
## 参数说明
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| type | String | 否 | 坐标类型,可选值:wgs84、gcj02 |
| altitude | Boolean | 否 | 是否返回高度信息 |
| geocode | Boolean | 否 | 是否解析地址信息 |
## 返回值
| 参数名 | 类型 | 说明 |
|--------|------|------|
| latitude | Number | 纬度 |
| longitude | Number | 经度 |
| speed | Number | 速度 |
| accuracy | Number | 位置的精确度 |
| altitude | Number | 高度(需要 altitude: true |
| address | Object | 地址信息(需要 geocode: true |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅(需要 HTTPS |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. 需要用户授权定位权限
2. H5 平台需要 HTTPS 协议
3. `type``gcj02` 时返回的坐标可用于地图显示
4. `geocode` 为 true 时才能获取地址信息
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/api/location/location.html#getlocation
- **打开地图**: https://uniapp.dcloud.net.cn/api/location/location.html#openlocation
- **选择位置**: https://uniapp.dcloud.net.cn/api/location/location.html#chooselocation
@@ -0,0 +1,188 @@
# uni.openLocation - 打开地图查看位置示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/api/location/open-location.html#openlocation
## 概述
`uni.openLocation` 用于使用地图查看位置,可以打开系统地图应用显示指定位置。
## 基础用法
```javascript
uni.openLocation({
latitude: 39.908823,
longitude: 116.397470,
name: '天安门',
address: '北京市东城区'
})
```
## 完整示例
### 示例 1: 打开地图查看位置
```javascript
uni.openLocation({
latitude: 39.908823,
longitude: 116.397470,
name: '天安门',
address: '北京市东城区天安门广场',
scale: 18,
success: () => {
console.log('打开地图成功')
},
fail: (err) => {
console.error('打开地图失败', err)
}
})
```
### 示例 2: 先获取位置再打开地图
```javascript
// 先获取当前位置
uni.getLocation({
type: 'gcj02',
success: (locationRes) => {
// 打开地图显示当前位置
uni.openLocation({
latitude: locationRes.latitude,
longitude: locationRes.longitude,
name: '我的位置',
address: locationRes.address || '当前位置'
})
}
})
```
### 示例 3: 在页面中使用
```vue
<template>
<view class="container">
<button @click="openCurrentLocation">查看当前位置</button>
<button @click="openTargetLocation">查看目标位置</button>
</view>
</template>
<script>
export default {
data() {
return {
targetLocation: {
latitude: 39.908823,
longitude: 116.397470,
name: '天安门',
address: '北京市东城区天安门广场'
}
}
},
methods: {
openCurrentLocation() {
uni.getLocation({
type: 'gcj02',
success: (res) => {
uni.openLocation({
latitude: res.latitude,
longitude: res.longitude,
name: '我的位置',
address: res.address || '当前位置'
})
},
fail: () => {
uni.showToast({
title: '获取位置失败',
icon: 'none'
})
}
})
},
openTargetLocation() {
uni.openLocation({
latitude: this.targetLocation.latitude,
longitude: this.targetLocation.longitude,
name: this.targetLocation.name,
address: this.targetLocation.address
})
}
}
}
</script>
```
### 示例 4: 查看商家位置
```javascript
function openStoreLocation(store) {
uni.openLocation({
latitude: store.latitude,
longitude: store.longitude,
name: store.name,
address: store.address,
scale: 18,
success: () => {
console.log('打开商家位置成功')
}
})
}
// 使用
const store = {
name: '星巴克咖啡',
address: '北京市朝阳区xxx路xxx号',
latitude: 39.908823,
longitude: 116.397470
}
openStoreLocation(store)
```
### 示例 5: 导航到位置
```javascript
// 在某些平台上,openLocation 可以用于导航
uni.openLocation({
latitude: 39.908823,
longitude: 116.397470,
name: '目的地',
address: '北京市东城区',
scale: 18
})
```
## 参数说明
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| latitude | Number | 是 | 纬度,范围为 -90~90,负数表示南纬 |
| longitude | Number | 是 | 经度,范围为 -180~180,负数表示西经 |
| scale | Number | 否 | 缩放比例,范围 5~18,默认为 18 |
| name | String | 否 | 位置名称 |
| address | String | 否 | 地址的详细说明 |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. 需要使用 `gcj02` 类型的坐标(通过 `uni.getLocation` 获取)
2. `scale` 值越大,地图显示越详细
3. `name``address` 用于在地图上显示位置信息
4. 不同平台打开的地图应用可能不同
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/api/location/open-location.html#openlocation
- **获取位置**: https://uniapp.dcloud.net.cn/api/location/location.html#getlocation
@@ -0,0 +1,222 @@
# uni.chooseImage - 选择图片示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/api/media/image.html#chooseimage
## 概述
`uni.chooseImage` 用于从本地相册选择图片或使用相机拍照。
## 基础用法
```javascript
uni.chooseImage({
count: 1,
success: (res) => {
console.log('选择的图片', res.tempFilePaths)
}
})
```
## 完整示例
### 示例 1: 选择单张图片
```javascript
uni.chooseImage({
count: 1,
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
success: (res) => {
console.log('选择的图片路径', res.tempFilePaths)
console.log('图片文件信息', res.tempFiles)
}
})
```
### 示例 2: 选择多张图片
```javascript
uni.chooseImage({
count: 9, // 最多选择9张
sizeType: ['compressed'], // 只选择压缩图
sourceType: ['album'], // 只从相册选择
success: (res) => {
console.log('选择了', res.tempFilePaths.length, '张图片')
res.tempFilePaths.forEach((path, index) => {
console.log(`图片${index + 1}:`, path)
})
}
})
```
### 示例 3: 在页面中使用
```vue
<template>
<view class="container">
<button @click="chooseImage">选择图片</button>
<view class="image-list">
<image
v-for="(item, index) in imageList"
:key="index"
:src="item"
mode="aspectFill"
class="image-item"
@click="previewImage(index)"
></image>
</view>
</view>
</template>
<script>
export default {
data() {
return {
imageList: []
}
},
methods: {
chooseImage() {
uni.chooseImage({
count: 9,
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
success: (res) => {
this.imageList = res.tempFilePaths
uni.showToast({
title: `选择了${res.tempFilePaths.length}张图片`,
icon: 'success'
})
},
fail: (err) => {
uni.showToast({
title: '选择图片失败',
icon: 'none'
})
}
})
},
previewImage(index) {
uni.previewImage({
current: index,
urls: this.imageList
})
}
}
}
</script>
<style>
.image-list {
display: flex;
flex-wrap: wrap;
margin-top: 20px;
}
.image-item {
width: 200rpx;
height: 200rpx;
margin: 10rpx;
border-radius: 8rpx;
}
</style>
```
### 示例 4: 上传图片
```javascript
uni.chooseImage({
count: 1,
sizeType: ['compressed'],
sourceType: ['album', 'camera'],
success: (res) => {
const tempFilePath = res.tempFilePaths[0]
// 上传图片
uni.uploadFile({
url: 'https://api.example.com/upload',
filePath: tempFilePath,
name: 'file',
success: (uploadRes) => {
const data = JSON.parse(uploadRes.data)
console.log('上传成功', data.url)
uni.showToast({
title: '上传成功',
icon: 'success'
})
},
fail: (err) => {
console.error('上传失败', err)
uni.showToast({
title: '上传失败',
icon: 'none'
})
}
})
}
})
```
### 示例 5: 获取图片信息
```javascript
uni.chooseImage({
count: 1,
success: (res) => {
const tempFilePath = res.tempFilePaths[0]
// 获取图片信息
uni.getImageInfo({
src: tempFilePath,
success: (imageInfo) => {
console.log('图片宽度', imageInfo.width)
console.log('图片高度', imageInfo.height)
console.log('图片路径', imageInfo.path)
}
})
}
})
```
## 参数说明
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| count | Number | 否 | 最多可以选择的图片张数,默认 9 |
| sizeType | Array | 否 | 所选的图片的尺寸,可选值:original(原图)、compressed(压缩图) |
| sourceType | Array | 否 | 选择图片的来源,可选值:album(相册)、camera(相机) |
## 返回值
| 参数名 | 类型 | 说明 |
|--------|------|------|
| tempFilePaths | Array | 图片的本地文件路径列表 |
| tempFiles | Array | 图片的本地文件列表,每个文件包含 path 和 size |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. 选择的图片是临时文件,需要上传到服务器才能永久保存
2. 临时文件路径在不同平台格式可能不同
3. 选择图片需要用户授权,首次使用会弹出授权提示
4. 建议使用压缩图以节省存储空间
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/api/media/image.html#chooseimage
- **预览图片**: https://uniapp.dcloud.net.cn/api/media/image.html#previewimage
- **上传文件**: https://uniapp.dcloud.net.cn/api/request/network-file.html#uploadfile
@@ -0,0 +1,232 @@
# uni.chooseMedia - 选择媒体文件示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/api/media/video.html#choosemedia
## 概述
`uni.chooseMedia` 用于从本地相册选择图片或视频,或者使用相机拍摄图片或视频。
## 基础用法
```javascript
uni.chooseMedia({
count: 9,
success: (res) => {
console.log('选择的文件', res.tempFiles)
}
})
```
## 完整示例
### 示例 1: 选择图片和视频
```javascript
uni.chooseMedia({
count: 9,
mediaType: ['image', 'video'],
sourceType: ['album', 'camera'],
success: (res) => {
console.log('选择的文件', res.tempFiles)
res.tempFiles.forEach((file, index) => {
console.log(`文件${index + 1}:`, file.tempFilePath)
if (file.fileType === 'image') {
console.log('图片大小', file.size)
} else if (file.fileType === 'video') {
console.log('视频时长', file.duration)
}
})
}
})
```
### 示例 2: 只选择图片
```javascript
uni.chooseMedia({
count: 9,
mediaType: ['image'],
sourceType: ['album', 'camera'],
sizeType: ['original', 'compressed'],
success: (res) => {
console.log('选择的图片', res.tempFiles)
}
})
```
### 示例 3: 只选择视频
```javascript
uni.chooseMedia({
count: 1,
mediaType: ['video'],
sourceType: ['album', 'camera'],
maxDuration: 60,
camera: 'back',
success: (res) => {
console.log('选择的视频', res.tempFiles)
}
})
```
### 示例 4: 在页面中使用
```vue
<template>
<view class="container">
<button @click="chooseMedia">选择媒体文件</button>
<view class="media-list">
<view
v-for="(item, index) in mediaList"
:key="index"
class="media-item"
>
<image
v-if="item.fileType === 'image'"
:src="item.tempFilePath"
mode="aspectFill"
class="media-preview"
></image>
<video
v-else-if="item.fileType === 'video'"
:src="item.tempFilePath"
controls
class="media-preview"
></video>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
mediaList: []
}
},
methods: {
chooseMedia() {
uni.chooseMedia({
count: 9,
mediaType: ['image', 'video'],
sourceType: ['album', 'camera'],
success: (res) => {
this.mediaList = res.tempFiles
uni.showToast({
title: `选择了${res.tempFiles.length}个文件`,
icon: 'success'
})
},
fail: (err) => {
console.error('选择失败', err)
}
})
}
}
}
</script>
<style>
.media-list {
display: flex;
flex-wrap: wrap;
margin-top: 20px;
}
.media-item {
width: 200rpx;
height: 200rpx;
margin: 10rpx;
border-radius: 8rpx;
overflow: hidden;
}
.media-preview {
width: 100%;
height: 100%;
}
</style>
```
### 示例 5: 上传媒体文件
```javascript
uni.chooseMedia({
count: 9,
mediaType: ['image', 'video'],
success: (res) => {
const files = res.tempFiles
let uploadCount = 0
files.forEach((file, index) => {
uni.uploadFile({
url: 'https://api.example.com/upload',
filePath: file.tempFilePath,
name: 'file',
formData: {
fileType: file.fileType,
size: file.size
},
success: (uploadRes) => {
uploadCount++
console.log(`文件${index + 1}上传成功`)
if (uploadCount === files.length) {
uni.showToast({
title: '全部上传成功',
icon: 'success'
})
}
},
fail: (err) => {
console.error(`文件${index + 1}上传失败`, err)
}
})
})
}
})
```
## 参数说明
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| count | Number | 否 | 最多可以选择的文件个数,默认 9 |
| mediaType | Array | 否 | 文件类型,可选值:image、video |
| sourceType | Array | 否 | 选择文件来源,可选值:album、camera |
| maxDuration | Number | 否 | 拍摄视频最长拍摄时间,单位秒 |
| camera | String | 否 | 使用前置或后置摄像头,可选值:back、front |
## 返回值
| 参数名 | 类型 | 说明 |
|--------|------|------|
| tempFiles | Array | 选中的文件列表,每个文件包含 tempFilePath、size、fileType 等 |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. `mediaType` 可以同时选择图片和视频
2. `count` 表示最多可以选择的文件个数
3. 返回的文件包含 `fileType` 字段,用于区分图片和视频
4. 建议根据实际需求设置 `maxDuration` 限制视频时长
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/api/media/video.html#choosemedia
- **选择图片**: https://uniapp.dcloud.net.cn/api/media/image.html#chooseimage
- **选择视频**: https://uniapp.dcloud.net.cn/api/media/video.html#choosevideo
@@ -0,0 +1,233 @@
# uni.chooseVideo - 选择视频示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/api/media/video.html#choosevideo
## 概述
`uni.chooseVideo` 用于从本地相册选择视频或使用相机拍摄视频。
## 基础用法
```javascript
uni.chooseVideo({
success: (res) => {
console.log('选择的视频', res.tempFilePath)
}
})
```
## 完整示例
### 示例 1: 选择视频
```javascript
uni.chooseVideo({
sourceType: ['album', 'camera'],
maxDuration: 60,
camera: 'back',
success: (res) => {
console.log('视频路径', res.tempFilePath)
console.log('视频时长', res.duration, '秒')
console.log('视频大小', res.size, '字节')
console.log('视频高度', res.height)
console.log('视频宽度', res.width)
}
})
```
### 示例 2: 拍摄视频
```javascript
uni.chooseVideo({
sourceType: ['camera'],
maxDuration: 30,
camera: 'back',
success: (res) => {
console.log('拍摄的视频', res.tempFilePath)
// 可以预览或上传视频
}
})
```
### 示例 3: 在页面中使用
```vue
<template>
<view class="container">
<button @click="chooseVideo">选择视频</button>
<button @click="recordVideo">拍摄视频</button>
<video
v-if="videoSrc"
:src="videoSrc"
controls
class="video-player"
></video>
</view>
</template>
<script>
export default {
data() {
return {
videoSrc: ''
}
},
methods: {
chooseVideo() {
uni.chooseVideo({
sourceType: ['album'],
maxDuration: 60,
success: (res) => {
this.videoSrc = res.tempFilePath
uni.showToast({
title: '选择成功',
icon: 'success'
})
},
fail: (err) => {
uni.showToast({
title: '选择失败',
icon: 'none'
})
}
})
},
recordVideo() {
uni.chooseVideo({
sourceType: ['camera'],
maxDuration: 30,
camera: 'back',
success: (res) => {
this.videoSrc = res.tempFilePath
uni.showToast({
title: '拍摄成功',
icon: 'success'
})
}
})
}
}
}
</script>
<style>
.video-player {
width: 100%;
height: 400px;
margin-top: 20px;
}
</style>
```
### 示例 4: 上传视频
```javascript
uni.chooseVideo({
sourceType: ['album', 'camera'],
maxDuration: 60,
success: (res) => {
const tempFilePath = res.tempFilePath
// 上传视频
uni.uploadFile({
url: 'https://api.example.com/upload-video',
filePath: tempFilePath,
name: 'video',
formData: {
duration: res.duration,
size: res.size
},
success: (uploadRes) => {
const data = JSON.parse(uploadRes.data)
console.log('上传成功', data.url)
uni.showToast({
title: '上传成功',
icon: 'success'
})
},
fail: (err) => {
console.error('上传失败', err)
}
})
}
})
```
### 示例 5: 限制视频时长和大小
```javascript
uni.chooseVideo({
sourceType: ['album', 'camera'],
maxDuration: 30, // 最长30秒
success: (res) => {
// 检查视频大小(例如限制为50MB)
const maxSize = 50 * 1024 * 1024 // 50MB
if (res.size > maxSize) {
uni.showModal({
title: '提示',
content: '视频文件过大,请选择小于50MB的视频',
showCancel: false
})
return
}
// 检查视频时长
if (res.duration > 30) {
uni.showModal({
title: '提示',
content: '视频时长不能超过30秒',
showCancel: false
})
return
}
console.log('视频符合要求', res)
}
})
```
## 参数说明
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| sourceType | Array | 否 | 选择视频的来源,可选值:album(相册)、camera(相机) |
| maxDuration | Number | 否 | 拍摄视频最长拍摄时间,单位秒 |
| camera | String | 否 | 使用前置或后置摄像头,可选值:back、front |
## 返回值
| 参数名 | 类型 | 说明 |
|--------|------|------|
| tempFilePath | String | 选定视频的临时文件路径 |
| duration | Number | 选定视频的时间长度,单位秒 |
| size | Number | 选定视频的数据量大小,单位字节 |
| width | Number | 选定视频的宽度,单位 px |
| height | Number | 选定视频的高度,单位 px |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. 选择的视频是临时文件,需要上传到服务器才能永久保存
2. `maxDuration` 用于限制拍摄时长
3. 可以通过 `size` 检查视频文件大小
4. 建议在拍摄前提示用户视频时长限制
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/api/media/video.html#choosevideo
- **上传文件**: https://uniapp.dcloud.net.cn/api/request/network-file.html#uploadfile
@@ -0,0 +1,209 @@
# uni.getImageInfo - 获取图片信息示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/api/media/image.html#getimageinfo
## 概述
`uni.getImageInfo` 用于获取图片信息,包括宽度、高度、路径等。
## 基础用法
```javascript
uni.getImageInfo({
src: 'https://example.com/image.jpg',
success: (res) => {
console.log('图片宽度', res.width)
console.log('图片高度', res.height)
}
})
```
## 完整示例
### 示例 1: 获取网络图片信息
```javascript
uni.getImageInfo({
src: 'https://example.com/image.jpg',
success: (res) => {
console.log('图片宽度', res.width)
console.log('图片高度', res.height)
console.log('图片路径', res.path)
},
fail: (err) => {
console.error('获取失败', err)
}
})
```
### 示例 2: 获取本地图片信息
```javascript
// 先选择图片
uni.chooseImage({
count: 1,
success: (res) => {
const tempFilePath = res.tempFilePaths[0]
// 获取图片信息
uni.getImageInfo({
src: tempFilePath,
success: (imageInfo) => {
console.log('图片信息', imageInfo)
// { width: 800, height: 600, path: '...' }
}
})
}
})
```
### 示例 3: 在页面中使用
```vue
<template>
<view class="container">
<button @click="selectAndGetInfo">选择图片并获取信息</button>
<view v-if="imageInfo" class="info">
<text>宽度{{ imageInfo.width }}px</text>
<text>高度{{ imageInfo.height }}px</text>
<image :src="imageInfo.path" mode="aspectFit" class="preview"></image>
</view>
</view>
</template>
<script>
export default {
data() {
return {
imageInfo: null
}
},
methods: {
selectAndGetInfo() {
uni.chooseImage({
count: 1,
success: (res) => {
const tempFilePath = res.tempFilePaths[0]
uni.getImageInfo({
src: tempFilePath,
success: (imageInfo) => {
this.imageInfo = imageInfo
},
fail: (err) => {
uni.showToast({
title: '获取图片信息失败',
icon: 'none'
})
}
})
}
})
}
}
}
</script>
<style>
.info {
margin-top: 20px;
padding: 20px;
}
.preview {
width: 100%;
max-height: 400px;
margin-top: 20px;
}
</style>
```
### 示例 4: 计算图片宽高比
```javascript
uni.getImageInfo({
src: 'https://example.com/image.jpg',
success: (res) => {
const aspectRatio = res.width / res.height
console.log('宽高比', aspectRatio)
// 根据宽高比调整显示
if (aspectRatio > 1) {
console.log('横向图片')
} else {
console.log('纵向图片')
}
}
})
```
### 示例 5: 验证图片尺寸
```javascript
function validateImageSize(imagePath, minWidth, minHeight) {
return new Promise((resolve, reject) => {
uni.getImageInfo({
src: imagePath,
success: (res) => {
if (res.width >= minWidth && res.height >= minHeight) {
resolve(res)
} else {
reject(new Error(`图片尺寸不符合要求,需要至少 ${minWidth}x${minHeight}`))
}
},
fail: (err) => {
reject(err)
}
})
})
}
// 使用
validateImageSize('https://example.com/image.jpg', 800, 600)
.then(info => {
console.log('图片符合要求', info)
})
.catch(err => {
console.error('验证失败', err)
})
```
## 参数说明
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| src | String | 是 | 图片的路径,可以是相对路径、临时文件路径或网络图片路径 |
## 返回值
| 参数名 | 类型 | 说明 |
|--------|------|------|
| width | Number | 图片宽度,单位 px |
| height | Number | 图片高度,单位 px |
| path | String | 返回图片的本地路径 |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. 网络图片需要配置合法域名
2. 本地图片路径需要使用 `/static/` 开头或临时文件路径
3. 获取图片信息是异步操作
4. 可以用于验证图片尺寸、计算宽高比等
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/api/media/image.html#getimageinfo
- **选择图片**: https://uniapp.dcloud.net.cn/api/media/image.html#chooseimage
@@ -0,0 +1,234 @@
# uni.previewImage - 预览图片示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/api/media/image.html#previewimage
## 概述
`uni.previewImage` 用于预览图片,支持缩放、滑动查看多张图片。
## 基础用法
```javascript
uni.previewImage({
urls: ['https://example.com/image1.jpg'],
current: 0
})
```
## 完整示例
### 示例 1: 预览单张图片
```javascript
uni.previewImage({
urls: ['https://example.com/image1.jpg'],
current: 'https://example.com/image1.jpg'
})
```
### 示例 2: 预览多张图片
```javascript
const imageList = [
'https://example.com/image1.jpg',
'https://example.com/image2.jpg',
'https://example.com/image3.jpg'
]
uni.previewImage({
urls: imageList,
current: 0 // 从第一张开始
})
```
### 示例 3: 在页面中使用
```vue
<template>
<view class="container">
<view class="image-list">
<image
v-for="(item, index) in imageList"
:key="index"
:src="item"
mode="aspectFill"
class="image-item"
@click="previewImage(index)"
></image>
</view>
</view>
</template>
<script>
export default {
data() {
return {
imageList: [
'https://example.com/image1.jpg',
'https://example.com/image2.jpg',
'https://example.com/image3.jpg'
]
}
},
methods: {
previewImage(index) {
uni.previewImage({
urls: this.imageList,
current: index
})
}
}
}
</script>
<style>
.image-list {
display: flex;
flex-wrap: wrap;
}
.image-item {
width: 200rpx;
height: 200rpx;
margin: 10rpx;
border-radius: 8rpx;
}
</style>
```
### 示例 4: 从选择图片到预览
```vue
<template>
<view class="container">
<button @click="chooseAndPreview">选择并预览图片</button>
<view class="image-list">
<image
v-for="(item, index) in selectedImages"
:key="index"
:src="item"
mode="aspectFill"
class="image-item"
@click="previewSelected(index)"
></image>
</view>
</view>
</template>
<script>
export default {
data() {
return {
selectedImages: []
}
},
methods: {
chooseAndPreview() {
uni.chooseImage({
count: 9,
success: (res) => {
this.selectedImages = res.tempFilePaths
// 预览第一张
if (res.tempFilePaths.length > 0) {
uni.previewImage({
urls: res.tempFilePaths,
current: 0
})
}
}
})
},
previewSelected(index) {
uni.previewImage({
urls: this.selectedImages,
current: index
})
}
}
}
</script>
```
### 示例 5: 长按保存图片
```vue
<template>
<view class="container">
<image
:src="imageUrl"
mode="aspectFit"
@longpress="saveImage"
class="preview-image"
></image>
</view>
</template>
<script>
export default {
data() {
return {
imageUrl: 'https://example.com/image.jpg'
}
},
methods: {
saveImage() {
uni.showActionSheet({
itemList: ['保存图片'],
success: (res) => {
if (res.tapIndex === 0) {
uni.downloadFile({
url: this.imageUrl,
success: (downloadRes) => {
uni.saveImageToPhotosAlbum({
filePath: downloadRes.tempFilePath,
success: () => {
uni.showToast({
title: '保存成功',
icon: 'success'
})
}
})
}
})
}
}
})
}
}
}
</script>
```
## 参数说明
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| urls | Array | 是 | 需要预览的图片 http 链接列表 |
| current | String/Number | 否 | 当前显示图片的索引或链接 |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. `urls` 必须是网络图片或已下载的本地路径
2. `current` 可以是索引(Number)或图片链接(String
3. 预览时支持手势缩放和滑动切换
4. 建议使用网络图片时确保图片可访问
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/api/media/image.html#previewimage
- **选择图片**: https://uniapp.dcloud.net.cn/api/media/image.html#chooseimage
@@ -0,0 +1,274 @@
# uni.saveImageToPhotosAlbum - 保存图片到相册示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/api/media/image.html#saveimagetophotosalbum
## 概述
`uni.saveImageToPhotosAlbum` 用于保存图片到系统相册。
## 基础用法
```javascript
uni.saveImageToPhotosAlbum({
filePath: '/tmp/image.jpg',
success: () => {
console.log('保存成功')
}
})
```
## 完整示例
### 示例 1: 保存网络图片
```javascript
// 先下载图片
uni.downloadFile({
url: 'https://example.com/image.jpg',
success: (res) => {
if (res.statusCode === 200) {
// 保存到相册
uni.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success: () => {
uni.showToast({
title: '保存成功',
icon: 'success'
})
},
fail: (err) => {
console.error('保存失败', err)
if (err.errMsg.includes('auth deny')) {
uni.showModal({
title: '提示',
content: '需要相册权限才能保存图片',
showCancel: false
})
}
}
})
}
}
})
```
### 示例 2: 保存选择的图片
```javascript
uni.chooseImage({
count: 1,
success: (res) => {
const tempFilePath = res.tempFilePaths[0]
uni.saveImageToPhotosAlbum({
filePath: tempFilePath,
success: () => {
uni.showToast({
title: '保存成功',
icon: 'success'
})
},
fail: (err) => {
console.error('保存失败', err)
}
})
}
})
```
### 示例 3: 在页面中使用
```vue
<template>
<view class="container">
<image :src="imageUrl" mode="aspectFit" class="preview-image"></image>
<button @click="saveImage">保存图片</button>
</view>
</template>
<script>
export default {
data() {
return {
imageUrl: 'https://example.com/image.jpg'
}
},
methods: {
saveImage() {
// 先下载图片
uni.downloadFile({
url: this.imageUrl,
success: (res) => {
if (res.statusCode === 200) {
uni.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success: () => {
uni.showToast({
title: '保存成功',
icon: 'success'
})
},
fail: (err) => {
if (err.errMsg.includes('auth deny')) {
uni.showModal({
title: '提示',
content: '需要相册权限,请在设置中开启',
success: (modalRes) => {
if (modalRes.confirm) {
uni.openSetting()
}
}
})
} else {
uni.showToast({
title: '保存失败',
icon: 'none'
})
}
}
})
}
}
})
}
}
}
</script>
```
### 示例 4: 检查权限
```javascript
function saveImageWithPermission(filePath) {
// 先检查权限
uni.getSetting({
success: (res) => {
if (res.authSetting['scope.writePhotosAlbum']) {
// 已授权,直接保存
saveImage(filePath)
} else {
// 请求授权
uni.authorize({
scope: 'scope.writePhotosAlbum',
success: () => {
saveImage(filePath)
},
fail: () => {
uni.showModal({
title: '提示',
content: '需要相册权限才能保存图片',
success: (modalRes) => {
if (modalRes.confirm) {
uni.openSetting()
}
}
})
}
})
}
}
})
}
function saveImage(filePath) {
uni.saveImageToPhotosAlbum({
filePath: filePath,
success: () => {
uni.showToast({
title: '保存成功',
icon: 'success'
})
}
})
}
```
### 示例 5: 长按保存图片
```vue
<template>
<view class="container">
<image
:src="imageUrl"
mode="aspectFit"
@longpress="handleLongPress"
class="preview-image"
></image>
</view>
</template>
<script>
export default {
data() {
return {
imageUrl: 'https://example.com/image.jpg'
}
},
methods: {
handleLongPress() {
uni.showActionSheet({
itemList: ['保存图片'],
success: (res) => {
if (res.tapIndex === 0) {
this.saveImage()
}
}
})
},
saveImage() {
uni.downloadFile({
url: this.imageUrl,
success: (res) => {
if (res.statusCode === 200) {
uni.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success: () => {
uni.showToast({
title: '保存成功',
icon: 'success'
})
}
})
}
}
})
}
}
}
</script>
```
## 参数说明
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| filePath | String | 是 | 图片文件路径,可以是临时文件路径或永久文件路径 |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. 需要用户授权相册权限
2. 网络图片需要先下载到本地
3. 如果权限被拒绝,可以引导用户到设置中开启
4. 建议在保存前检查权限状态
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/api/media/image.html#saveimagetophotosalbum
- **下载文件**: https://uniapp.dcloud.net.cn/api/request/network-file.html#downloadfile
- **授权**: https://uniapp.dcloud.net.cn/api/other/authorize.html#authorize
@@ -0,0 +1,177 @@
# uni.navigateBack - 返回上一页示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/api/router.html#navigateback
## 概述
`uni.navigateBack` 用于关闭当前页面,返回上一页面或多级页面。
## 基础用法
```javascript
uni.navigateBack()
```
## 完整示例
### 示例 1: 基本返回
```javascript
uni.navigateBack({
success: () => {
console.log('返回成功')
},
fail: (err) => {
console.error('返回失败', err)
}
})
```
### 示例 2: 返回多级页面
```javascript
// 返回上一页
uni.navigateBack({
delta: 1
})
// 返回上两页
uni.navigateBack({
delta: 2
})
```
### 示例 3: 在页面中使用
```vue
<template>
<view class="container">
<button @click="goBack">返回</button>
<button @click="goBackTwoPages">返回上两页</button>
</view>
</template>
<script>
export default {
methods: {
goBack() {
uni.navigateBack()
},
goBackTwoPages() {
uni.navigateBack({
delta: 2
})
}
}
}
</script>
```
### 示例 4: 带数据返回
```vue
<!-- 当前页面 -->
<template>
<view class="container">
<button @click="saveAndBack">保存并返回</button>
</view>
</template>
<script>
export default {
data() {
return {
formData: {
name: 'test',
value: '123'
}
}
},
methods: {
saveAndBack() {
// 保存数据到上一页
const pages = getCurrentPages()
const prevPage = pages[pages.length - 2]
if (prevPage) {
prevPage.setData({
savedData: this.formData
})
}
uni.navigateBack()
}
}
}
</script>
```
### 示例 5: 返回前确认
```vue
<template>
<view class="container">
<button @click="handleBack">返回</button>
</view>
</template>
<script>
export default {
data() {
return {
hasChanges: false
}
},
methods: {
handleBack() {
if (this.hasChanges) {
uni.showModal({
title: '提示',
content: '有未保存的更改,确定要返回吗?',
success: (res) => {
if (res.confirm) {
uni.navigateBack()
}
}
})
} else {
uni.navigateBack()
}
}
}
}
</script>
```
## 参数说明
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| delta | Number | 否 | 返回的页面数,如果 delta 大于现有页面数,则返回到首页 |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. `delta` 默认为 1,表示返回上一页
2. 如果 `delta` 大于现有页面数,会返回到首页
3. 可以通过 `getCurrentPages()` 获取页面栈信息
4. 返回时可以传递数据给上一页
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/api/router.html#navigateback
- **页面跳转**: https://uniapp.dcloud.net.cn/api/router.html#navigateto
@@ -0,0 +1,151 @@
# uni.navigateTo - 页面跳转示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/api/router.html#navigateto
## 概述
`uni.navigateTo` 用于保留当前页面,跳转到应用内的某个页面。
## 基础用法
```javascript
uni.navigateTo({
url: '/pages/detail/detail'
})
```
## 完整示例
### 示例 1: 基本跳转
```javascript
uni.navigateTo({
url: '/pages/detail/detail',
success: () => {
console.log('跳转成功')
},
fail: (err) => {
console.error('跳转失败', err)
}
})
```
### 示例 2: 带参数跳转
```javascript
// 跳转并传递参数
uni.navigateTo({
url: '/pages/detail/detail?id=123&name=test'
})
// 在目标页面接收参数
// pages/detail/detail.vue
export default {
onLoad(options) {
console.log('接收到的参数', options)
// { id: '123', name: 'test' }
}
}
```
### 示例 3: 传递对象参数
```javascript
// 传递对象
const params = {
id: 123,
name: 'test',
data: { key: 'value' }
}
// 需要序列化
uni.navigateTo({
url: `/pages/detail/detail?data=${encodeURIComponent(JSON.stringify(params))}`
})
// 在目标页面解析
export default {
onLoad(options) {
const data = JSON.parse(decodeURIComponent(options.data))
console.log('解析后的数据', data)
}
}
```
### 示例 4: 在组件中使用
```vue
<template>
<view class="container">
<button @click="goToDetail">查看详情</button>
<button @click="goToDetailWithParams">带参数跳转</button>
</view>
</template>
<script>
export default {
methods: {
goToDetail() {
uni.navigateTo({
url: '/pages/detail/detail'
})
},
goToDetailWithParams() {
uni.navigateTo({
url: '/pages/detail/detail?id=123&name=test'
})
}
}
}
</script>
```
### 示例 5: 封装跳转函数
```javascript
// utils/navigation.js
const navigation = {
// 跳转到详情页
toDetail(id) {
uni.navigateTo({
url: `/pages/detail/detail?id=${id}`
})
},
// 跳转到用户页
toUser(userId) {
uni.navigateTo({
url: `/pages/user/user?id=${userId}`
})
},
// 通用跳转
navigate(url, params = {}) {
const query = Object.keys(params)
.map(key => `${key}=${encodeURIComponent(params[key])}`)
.join('&')
const fullUrl = query ? `${url}?${query}` : url
uni.navigateTo({
url: fullUrl
})
}
}
// 使用
navigation.toDetail(123)
navigation.navigate('/pages/detail/detail', { id: 123, name: 'test' })
```
## 注意事项
1. 不能跳转到 tabBar 页面,需要使用 `uni.switchTab`
2. 路径前需要加 `/`,表示从根目录开始
3. 参数会拼接在 URL 后面,长度有限制
4. 复杂对象需要序列化后传递
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/api/router.html#navigateto
- **其他路由 API**: https://uniapp.dcloud.net.cn/api/router.html
@@ -0,0 +1,152 @@
# uni.reLaunch - 重新启动应用示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/api/router.html#relaunch
## 概述
`uni.reLaunch` 用于关闭所有页面,打开到应用内的某个页面。
## 基础用法
```javascript
uni.reLaunch({
url: '/pages/index/index'
})
```
## 完整示例
### 示例 1: 基本重新启动
```javascript
uni.reLaunch({
url: '/pages/index/index',
success: () => {
console.log('重新启动成功')
},
fail: (err) => {
console.error('重新启动失败', err)
}
})
```
### 示例 2: 退出登录后重新启动
```javascript
function logout() {
// 清除所有数据
uni.clearStorageSync()
// 重新启动到登录页
uni.reLaunch({
url: '/pages/login/login'
})
}
```
### 示例 3: 在页面中使用
```vue
<template>
<view class="container">
<button @click="restartApp">重新启动应用</button>
</view>
</template>
<script>
export default {
methods: {
restartApp() {
uni.showModal({
title: '提示',
content: '确定要重新启动应用吗?',
success: (res) => {
if (res.confirm) {
uni.reLaunch({
url: '/pages/index/index'
})
}
}
})
}
}
}
</script>
```
### 示例 4: 与 navigateTo 和 redirectTo 的区别
```javascript
// navigateTo: 保留当前页面,可以返回
uni.navigateTo({
url: '/pages/detail/detail'
})
// 页面栈: [首页, 详情页]
// redirectTo: 关闭当前页面,不能返回
uni.redirectTo({
url: '/pages/detail/detail'
})
// 页面栈: [详情页] (首页被关闭)
// reLaunch: 关闭所有页面,重新启动
uni.reLaunch({
url: '/pages/detail/detail'
})
// 页面栈: [详情页] (所有页面都被关闭)
```
### 示例 5: 登录后重新启动
```javascript
function login() {
uni.request({
url: 'https://api.example.com/login',
method: 'POST',
data: { username: 'test', password: '123456' },
success: (res) => {
if (res.data.success) {
uni.setStorageSync('token', res.data.token)
// 重新启动到首页
uni.reLaunch({
url: '/pages/index/index'
})
}
}
})
}
```
## 参数说明
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| url | String | 是 | 需要跳转的应用内非 tabBar 的页面的路径 |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. 不能跳转到 tabBar 页面,需要使用 `uni.switchTab`
2. 会关闭所有页面,无法返回
3. 路径前需要加 `/`,表示从根目录开始
4. 适合退出登录、重新启动等场景
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/api/router.html#relaunch
- **页面跳转**: https://uniapp.dcloud.net.cn/api/router.html#navigateto
@@ -0,0 +1,146 @@
# uni.redirectTo - 重定向跳转示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/api/router.html#redirectto
## 概述
`uni.redirectTo` 用于关闭当前页面,跳转到应用内的某个页面。
## 基础用法
```javascript
uni.redirectTo({
url: '/pages/detail/detail'
})
```
## 完整示例
### 示例 1: 基本重定向
```javascript
uni.redirectTo({
url: '/pages/detail/detail',
success: () => {
console.log('跳转成功')
},
fail: (err) => {
console.error('跳转失败', err)
}
})
```
### 示例 2: 带参数重定向
```javascript
uni.redirectTo({
url: '/pages/detail/detail?id=123&name=test'
})
// 在目标页面接收参数
// pages/detail/detail.vue
export default {
onLoad(options) {
console.log('接收到的参数', options)
// { id: '123', name: 'test' }
}
}
```
### 示例 3: 登录后重定向
```javascript
function login() {
// 登录逻辑
uni.request({
url: 'https://api.example.com/login',
method: 'POST',
data: { username: 'test', password: '123456' },
success: (res) => {
if (res.data.success) {
// 保存 token
uni.setStorageSync('token', res.data.token)
// 重定向到首页(关闭登录页)
uni.redirectTo({
url: '/pages/index/index'
})
}
}
})
}
```
### 示例 4: 在页面中使用
```vue
<template>
<view class="container">
<button @click="goToDetail">跳转到详情页</button>
</view>
</template>
<script>
export default {
methods: {
goToDetail() {
uni.redirectTo({
url: '/pages/detail/detail?id=123'
})
}
}
}
</script>
```
### 示例 5: 与 navigateTo 的区别
```javascript
// navigateTo: 保留当前页面,可以返回
uni.navigateTo({
url: '/pages/detail/detail'
})
// 页面栈: [首页, 详情页]
// redirectTo: 关闭当前页面,不能返回
uni.redirectTo({
url: '/pages/detail/detail'
})
// 页面栈: [详情页] (首页被关闭)
```
## 参数说明
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| url | String | 是 | 需要跳转的应用内非 tabBar 的页面的路径 |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. 不能跳转到 tabBar 页面,需要使用 `uni.switchTab`
2. 会关闭当前页面,无法返回
3. 路径前需要加 `/`,表示从根目录开始
4. 适合登录后跳转等不需要返回的场景
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/api/router.html#redirectto
- **保留页面跳转**: https://uniapp.dcloud.net.cn/api/router.html#navigateto
- **重新启动**: https://uniapp.dcloud.net.cn/api/router.html#relaunch
@@ -0,0 +1,149 @@
# uni.switchTab - 切换 TabBar 页面示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/api/router.html#switchtab
## 概述
`uni.switchTab` 用于跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面。
## 基础用法
```javascript
uni.switchTab({
url: '/pages/index/index'
})
```
## 完整示例
### 示例 1: 基本切换
```javascript
uni.switchTab({
url: '/pages/index/index',
success: () => {
console.log('切换成功')
},
fail: (err) => {
console.error('切换失败', err)
}
})
```
### 示例 2: 在页面中使用
```vue
<template>
<view class="container">
<button @click="goToHome">回到首页</button>
<button @click="goToCategory">分类</button>
<button @click="goToCart">购物车</button>
<button @click="goToProfile">我的</button>
</view>
</template>
<script>
export default {
methods: {
goToHome() {
uni.switchTab({
url: '/pages/index/index'
})
},
goToCategory() {
uni.switchTab({
url: '/pages/category/category'
})
},
goToCart() {
uni.switchTab({
url: '/pages/cart/cart'
})
},
goToProfile() {
uni.switchTab({
url: '/pages/profile/profile'
})
}
}
}
</script>
```
### 示例 3: 登录后跳转到首页
```javascript
function login() {
uni.request({
url: 'https://api.example.com/login',
method: 'POST',
data: { username: 'test', password: '123456' },
success: (res) => {
if (res.data.success) {
uni.setStorageSync('token', res.data.token)
// 跳转到 tabBar 首页
uni.switchTab({
url: '/pages/index/index'
})
}
}
})
}
```
### 示例 4: 封装切换函数
```javascript
// utils/navigation.js
const navigation = {
switchToTab(url) {
uni.switchTab({
url: url,
fail: (err) => {
console.error('切换失败', err)
// 如果不是 tabBar 页面,使用 navigateTo
uni.navigateTo({
url: url
})
}
})
}
}
// 使用
navigation.switchToTab('/pages/index/index')
```
## 参数说明
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| url | String | 是 | 需要跳转的 tabBar 页面的路径 |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. 只能跳转到 `pages.json` 中配置的 tabBar 页面
2. 不能传递参数(URL 参数会被忽略)
3. 会关闭所有非 tabBar 页面
4. 如果目标页面不是 tabBar 页面,会触发 fail 回调
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/api/router.html#switchtab
- **页面跳转**: https://uniapp.dcloud.net.cn/api/router.html#navigateto
@@ -0,0 +1,234 @@
# uni.downloadFile - 下载文件示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/api/request/network-file.html#downloadfile
## 概述
`uni.downloadFile` 用于下载文件资源到本地。
## 基础用法
```javascript
uni.downloadFile({
url: 'https://example.com/file.pdf',
success: (res) => {
console.log('下载成功', res.tempFilePath)
}
})
```
## 完整示例
### 示例 1: 下载图片
```javascript
uni.downloadFile({
url: 'https://example.com/image.jpg',
success: (res) => {
if (res.statusCode === 200) {
console.log('下载成功', res.tempFilePath)
// 可以预览或保存图片
uni.previewImage({
urls: [res.tempFilePath]
})
}
},
fail: (err) => {
console.error('下载失败', err)
}
})
```
### 示例 2: 下载并保存到相册
```javascript
uni.downloadFile({
url: 'https://example.com/image.jpg',
success: (res) => {
if (res.statusCode === 200) {
// 保存到相册
uni.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success: () => {
uni.showToast({
title: '保存成功',
icon: 'success'
})
},
fail: (err) => {
console.error('保存失败', err)
}
})
}
}
})
```
### 示例 3: 显示下载进度
```javascript
uni.downloadFile({
url: 'https://example.com/large-file.pdf',
success: (res) => {
console.log('下载完成', res.tempFilePath)
},
fail: (err) => {
console.error('下载失败', err)
}
})
```
### 示例 4: 在页面中使用
```vue
<template>
<view class="container">
<button @click="downloadFile">下载文件</button>
<view v-if="downloading" class="download-status">
<text>下载中...</text>
</view>
<view v-if="filePath" class="file-info">
<text>文件路径{{ filePath }}</text>
<button @click="openFile">打开文件</button>
</view>
</view>
</template>
<script>
export default {
data() {
return {
downloading: false,
filePath: ''
}
},
methods: {
downloadFile() {
this.downloading = true
uni.downloadFile({
url: 'https://example.com/file.pdf',
success: (res) => {
if (res.statusCode === 200) {
this.filePath = res.tempFilePath
this.downloading = false
uni.showToast({
title: '下载成功',
icon: 'success'
})
}
},
fail: (err) => {
this.downloading = false
uni.showToast({
title: '下载失败',
icon: 'none'
})
}
})
},
openFile() {
// 打开文件
uni.openDocument({
filePath: this.filePath,
success: () => {
console.log('打开成功')
}
})
}
}
}
</script>
```
### 示例 5: 封装下载函数
```javascript
// utils/download.js
const download = {
downloadFile(url, options = {}) {
return new Promise((resolve, reject) => {
uni.downloadFile({
url: url,
header: options.header || {},
success: (res) => {
if (res.statusCode === 200) {
resolve(res.tempFilePath)
} else {
reject(new Error(`下载失败,状态码:${res.statusCode}`))
}
},
fail: (err) => {
reject(err)
}
})
})
},
async downloadAndSave(url) {
try {
const filePath = await this.downloadFile(url)
// 根据文件类型保存
if (filePath.endsWith('.jpg') || filePath.endsWith('.png')) {
await uni.saveImageToPhotosAlbum({ filePath })
} else {
await uni.saveFile({ tempFilePath: filePath })
}
return filePath
} catch (err) {
throw err
}
}
}
// 使用
download.downloadFile('https://example.com/file.pdf')
.then(filePath => {
console.log('下载成功', filePath)
})
.catch(err => {
console.error('下载失败', err)
})
```
## 参数说明
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| url | String | 是 | 下载资源的 url |
| header | Object | 否 | HTTP 请求 Header |
## 返回值
| 参数名 | 类型 | 说明 |
|--------|------|------|
| tempFilePath | String | 临时文件路径,下载后的文件会存储到一个临时文件 |
| statusCode | Number | HTTP 状态码 |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. 下载的文件是临时文件,需要保存才能永久使用
2. 可以通过 `statusCode` 判断下载是否成功
3. 下载的文件路径是临时路径,应用关闭后可能失效
4. 建议下载后立即保存或使用
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/api/request/network-file.html#downloadfile
- **保存文件**: https://uniapp.dcloud.net.cn/api/file/file.html#savefile
- **打开文档**: https://uniapp.dcloud.net.cn/api/file/file.html#opendocument
@@ -0,0 +1,287 @@
# uni.request - 网络请求示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/api/request/request.html
## 概述
`uni.request` 用于发起网络请求,支持 GET、POST、PUT、DELETE 等方法。
## 基础用法
### GET 请求
```javascript
uni.request({
url: 'https://api.example.com/data',
method: 'GET',
success: (res) => {
console.log('请求成功', res.data)
},
fail: (err) => {
console.error('请求失败', err)
}
})
```
### POST 请求
```javascript
uni.request({
url: 'https://api.example.com/user',
method: 'POST',
data: {
name: 'John',
age: 30
},
header: {
'Content-Type': 'application/json'
},
success: (res) => {
console.log('请求成功', res.data)
}
})
```
## 完整示例
### 示例 1: 带参数的 GET 请求
```javascript
uni.request({
url: 'https://api.example.com/users',
method: 'GET',
data: {
page: 1,
limit: 10
},
success: (res) => {
if (res.statusCode === 200) {
console.log('用户列表', res.data)
}
},
fail: (err) => {
uni.showToast({
title: '请求失败',
icon: 'none'
})
}
})
```
### 示例 2: POST 请求上传数据
```javascript
uni.request({
url: 'https://api.example.com/users',
method: 'POST',
data: {
name: 'John Doe',
email: 'john@example.com',
age: 30
},
header: {
'Content-Type': 'application/json',
'Authorization': 'Bearer token123'
},
success: (res) => {
if (res.statusCode === 200 || res.statusCode === 201) {
uni.showToast({
title: '创建成功',
icon: 'success'
})
}
}
})
```
### 示例 3: 使用 Promise
```javascript
// Promise 方式(部分平台支持)
uni.request({
url: 'https://api.example.com/data'
}).then(res => {
console.log('请求成功', res.data)
}).catch(err => {
console.error('请求失败', err)
})
```
### 示例 4: 封装请求函数
```javascript
// utils/request.js
const request = (options) => {
return new Promise((resolve, reject) => {
uni.request({
url: options.url,
method: options.method || 'GET',
data: options.data || {},
header: {
'Content-Type': 'application/json',
...options.header
},
success: (res) => {
if (res.statusCode === 200) {
resolve(res.data)
} else {
reject(new Error(`请求失败: ${res.statusCode}`))
}
},
fail: (err) => {
reject(err)
}
})
})
}
// 使用
request({
url: 'https://api.example.com/data',
method: 'GET'
}).then(data => {
console.log('数据', data)
}).catch(err => {
console.error('错误', err)
})
```
### 示例 5: 请求拦截和响应拦截
```javascript
// utils/http.js
const baseURL = 'https://api.example.com'
// 请求拦截
const requestInterceptor = (config) => {
// 添加 token
const token = uni.getStorageSync('token')
if (token) {
config.header = {
...config.header,
'Authorization': `Bearer ${token}`
}
}
return config
}
// 响应拦截
const responseInterceptor = (res) => {
if (res.statusCode === 401) {
// token 过期,跳转登录
uni.navigateTo({
url: '/pages/login/login'
})
return Promise.reject(new Error('未授权'))
}
return res.data
}
const http = {
request(options) {
const config = requestInterceptor({
url: baseURL + options.url,
method: options.method || 'GET',
data: options.data || {},
header: options.header || {}
})
return new Promise((resolve, reject) => {
uni.request({
...config,
success: (res) => {
try {
const data = responseInterceptor(res)
resolve(data)
} catch (err) {
reject(err)
}
},
fail: (err) => {
reject(err)
}
})
})
}
}
export default http
```
### 示例 6: 超时处理
```javascript
uni.request({
url: 'https://api.example.com/data',
method: 'GET',
timeout: 5000, // 5秒超时
success: (res) => {
console.log('请求成功', res.data)
},
fail: (err) => {
if (err.errMsg && err.errMsg.includes('timeout')) {
uni.showToast({
title: '请求超时',
icon: 'none'
})
} else {
uni.showToast({
title: '请求失败',
icon: 'none'
})
}
}
})
```
### 示例 7: 处理不同数据类型
```javascript
// JSON 数据
uni.request({
url: 'https://api.example.com/data',
dataType: 'json',
success: (res) => {
console.log('JSON 数据', res.data)
}
})
// 文本数据
uni.request({
url: 'https://api.example.com/text',
dataType: 'text',
success: (res) => {
console.log('文本数据', res.data)
}
})
// ArrayBuffer 数据
uni.request({
url: 'https://api.example.com/binary',
responseType: 'arraybuffer',
success: (res) => {
console.log('二进制数据', res.data)
}
})
```
## 平台差异
- **H5**: 支持 `withCredentials` 参数,用于跨域请求携带凭证
- **App**: 支持 `sslVerify` 参数,用于验证 SSL 证书
- **App**: 支持 `firstIpv4` 参数,DNS 解析时优先使用 IPv4
## 注意事项
1. 默认超时时间为 60000ms(60秒)
2. 默认 `dataType``json`,会自动解析 JSON 数据
3. 请求 header 中不能设置 `Referer`
4. 部分平台支持 Promise 方式调用
5. 建议封装统一的请求函数,便于统一处理错误和拦截
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/api/request/request.html
- **网络请求最佳实践**: https://uniapp.dcloud.net.cn/api/request/request.html
@@ -0,0 +1,262 @@
# uni.uploadFile - 上传文件示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/api/request/network-file.html#uploadfile
## 概述
`uni.uploadFile` 用于将本地资源上传到服务器。
## 基础用法
```javascript
uni.uploadFile({
url: 'https://api.example.com/upload',
filePath: '/tmp/image.jpg',
name: 'file',
success: (res) => {
console.log('上传成功', res.data)
}
})
```
## 完整示例
### 示例 1: 上传图片
```javascript
// 先选择图片
uni.chooseImage({
count: 1,
success: (res) => {
const tempFilePath = res.tempFilePaths[0]
// 上传图片
uni.uploadFile({
url: 'https://api.example.com/upload',
filePath: tempFilePath,
name: 'file',
formData: {
'user': 'test'
},
success: (uploadRes) => {
const data = JSON.parse(uploadRes.data)
console.log('上传成功', data.url)
uni.showToast({
title: '上传成功',
icon: 'success'
})
},
fail: (err) => {
console.error('上传失败', err)
uni.showToast({
title: '上传失败',
icon: 'none'
})
}
})
}
})
```
### 示例 2: 上传多张图片
```javascript
uni.chooseImage({
count: 9,
success: (res) => {
const tempFilePaths = res.tempFilePaths
let uploadCount = 0
tempFilePaths.forEach((filePath, index) => {
uni.uploadFile({
url: 'https://api.example.com/upload',
filePath: filePath,
name: 'file',
success: () => {
uploadCount++
if (uploadCount === tempFilePaths.length) {
uni.showToast({
title: '全部上传成功',
icon: 'success'
})
}
},
fail: (err) => {
console.error(`${index + 1}张图片上传失败`, err)
}
})
})
}
})
```
### 示例 3: 显示上传进度
```javascript
uni.chooseImage({
count: 1,
success: (res) => {
const tempFilePath = res.tempFilePaths[0]
uni.uploadFile({
url: 'https://api.example.com/upload',
filePath: tempFilePath,
name: 'file',
success: (res) => {
console.log('上传成功', res)
},
fail: (err) => {
console.error('上传失败', err)
}
})
}
})
```
### 示例 4: 在页面中使用
```vue
<template>
<view class="container">
<button @click="uploadImage">上传图片</button>
<view v-if="uploading" class="upload-status">
<text>上传中...</text>
</view>
<image v-if="imageUrl" :src="imageUrl" mode="aspectFit" class="uploaded-image"></image>
</view>
</template>
<script>
export default {
data() {
return {
uploading: false,
imageUrl: ''
}
},
methods: {
uploadImage() {
uni.chooseImage({
count: 1,
success: (res) => {
this.uploading = true
const tempFilePath = res.tempFilePaths[0]
uni.uploadFile({
url: 'https://api.example.com/upload',
filePath: tempFilePath,
name: 'file',
header: {
'Authorization': 'Bearer ' + uni.getStorageSync('token')
},
success: (uploadRes) => {
const data = JSON.parse(uploadRes.data)
this.imageUrl = data.url
this.uploading = false
uni.showToast({
title: '上传成功',
icon: 'success'
})
},
fail: (err) => {
this.uploading = false
uni.showToast({
title: '上传失败',
icon: 'none'
})
}
})
}
})
}
}
}
</script>
```
### 示例 5: 封装上传函数
```javascript
// utils/upload.js
const upload = {
uploadImage(filePath, options = {}) {
return new Promise((resolve, reject) => {
uni.uploadFile({
url: options.url || 'https://api.example.com/upload',
filePath: filePath,
name: options.name || 'file',
formData: options.formData || {},
header: options.header || {},
success: (res) => {
try {
const data = JSON.parse(res.data)
resolve(data)
} catch (e) {
resolve(res.data)
}
},
fail: (err) => {
reject(err)
}
})
})
}
}
// 使用
const filePath = '/tmp/image.jpg'
upload.uploadImage(filePath, {
url: 'https://api.example.com/upload',
formData: { userId: '123' }
}).then(data => {
console.log('上传成功', data)
}).catch(err => {
console.error('上传失败', err)
})
```
## 参数说明
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| url | String | 是 | 开发者服务器地址 |
| filePath | String | 是 | 要上传文件资源的路径 |
| name | String | 是 | 文件对应的 key,开发者在服务端可以通过这个 key 获取文件的二进制内容 |
| header | Object | 否 | HTTP 请求 Header |
| formData | Object | 否 | HTTP 请求中其他额外的 form data |
## 返回值
| 参数名 | 类型 | 说明 |
|--------|------|------|
| data | String | 服务器返回的数据 |
| statusCode | Number | HTTP 状态码 |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. 上传文件前需要先选择文件(使用 `uni.chooseImage` 等)
2. `filePath` 必须是本地路径
3. 可以通过 `formData` 传递额外的表单数据
4. 建议在请求头中添加认证信息
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/api/request/network-file.html#uploadfile
- **选择图片**: https://uniapp.dcloud.net.cn/api/media/image.html#chooseimage
- **下载文件**: https://uniapp.dcloud.net.cn/api/request/network-file.html#downloadfile
@@ -0,0 +1,137 @@
# uni.clearStorage - 清除所有存储数据示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/api/storage/storage.html#clearstorage
## 概述
`uni.clearStorage` 用于清理本地数据缓存,清除所有存储的数据。
## 基础用法
```javascript
uni.clearStorage({
success: () => {
console.log('清除成功')
}
})
```
## 完整示例
### 示例 1: 清除所有数据
```javascript
uni.clearStorage({
success: () => {
console.log('所有数据已清除')
uni.showToast({
title: '清除成功',
icon: 'success'
})
},
fail: (err) => {
console.error('清除失败', err)
}
})
```
### 示例 2: 退出登录时清除
```javascript
function logout() {
uni.clearStorage({
success: () => {
console.log('数据已清除')
// 跳转到登录页
uni.reLaunch({
url: '/pages/login/login'
})
}
})
}
```
### 示例 3: 在页面中使用
```vue
<template>
<view class="container">
<button @click="clearAllData">清除所有数据</button>
</view>
</template>
<script>
export default {
methods: {
clearAllData() {
uni.showModal({
title: '提示',
content: '确定要清除所有数据吗?此操作不可恢复',
success: (res) => {
if (res.confirm) {
uni.clearStorage({
success: () => {
uni.showToast({
title: '清除成功',
icon: 'success'
})
// 重新加载页面
setTimeout(() => {
uni.reLaunch({
url: '/pages/index/index'
})
}, 1500)
}
})
}
}
})
}
}
}
</script>
```
### 示例 4: 同步版本
```javascript
try {
uni.clearStorageSync()
console.log('清除成功')
} catch (err) {
console.error('清除失败', err)
}
```
## 参数说明
此 API 无需参数。
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. 此操作会清除所有本地存储的数据,请谨慎使用
2. 建议在清除前提示用户确认
3. 同步版本 `clearStorageSync` 性能更好
4. 清除后可能需要重新登录或初始化数据
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/api/storage/storage.html#clearstorage
- **同步版本**: https://uniapp.dcloud.net.cn/api/storage/storage.html#clearstoragesync
- **删除单个**: https://uniapp.dcloud.net.cn/api/storage/storage.html#removestorage
@@ -0,0 +1,202 @@
# uni.getStorageInfo - 获取存储信息示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/api/storage/storage.html#getstorageinfo
## 概述
`uni.getStorageInfo` 用于异步获取当前 storage 的相关信息。
## 基础用法
```javascript
uni.getStorageInfo({
success: (res) => {
console.log('存储信息', res)
}
})
```
## 完整示例
### 示例 1: 获取存储信息
```javascript
uni.getStorageInfo({
success: (res) => {
console.log('所有key', res.keys)
console.log('当前占用的空间大小', res.currentSize, 'KB')
console.log('限制的空间大小', res.limitSize, 'KB')
},
fail: (err) => {
console.error('获取失败', err)
}
})
```
### 示例 2: 检查存储空间
```javascript
function checkStorageSpace() {
uni.getStorageInfo({
success: (res) => {
const usagePercent = (res.currentSize / res.limitSize * 100).toFixed(2)
console.log(`存储使用率:${usagePercent}%`)
if (usagePercent > 80) {
uni.showModal({
title: '提示',
content: '存储空间不足,建议清理缓存',
showCancel: false
})
}
}
})
}
```
### 示例 3: 在页面中使用
```vue
<template>
<view class="container">
<button @click="getStorageInfo">查看存储信息</button>
<view v-if="storageInfo" class="storage-info">
<text>已使用{{ storageInfo.currentSize }}KB / {{ storageInfo.limitSize }}KB</text>
<text>使用率{{ usagePercent }}%</text>
<text>存储的key数量{{ storageInfo.keys.length }}</text>
<view class="key-list">
<text v-for="key in storageInfo.keys" :key="key" class="key-item">
{{ key }}
</text>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
storageInfo: null
}
},
computed: {
usagePercent() {
if (!this.storageInfo) return 0
return ((this.storageInfo.currentSize / this.storageInfo.limitSize) * 100).toFixed(2)
}
},
methods: {
getStorageInfo() {
uni.getStorageInfo({
success: (res) => {
this.storageInfo = res
}
})
}
}
}
</script>
<style>
.storage-info {
margin-top: 20px;
padding: 20px;
background-color: #f5f5f5;
border-radius: 8px;
}
.key-list {
margin-top: 10px;
}
.key-item {
display: block;
padding: 5px;
font-size: 24rpx;
color: #666;
}
</style>
```
### 示例 4: 清理存储空间
```javascript
function clearStorageIfNeeded() {
uni.getStorageInfo({
success: (res) => {
const usagePercent = (res.currentSize / res.limitSize) * 100
if (usagePercent > 80) {
uni.showModal({
title: '提示',
content: '存储空间不足,是否清理缓存?',
success: (modalRes) => {
if (modalRes.confirm) {
// 清理非关键数据
const importantKeys = ['token', 'userInfo']
res.keys.forEach(key => {
if (!importantKeys.includes(key)) {
uni.removeStorageSync(key)
}
})
uni.showToast({
title: '清理完成',
icon: 'success'
})
}
}
})
}
}
})
}
```
### 示例 5: 同步版本
```javascript
try {
const storageInfo = uni.getStorageInfoSync()
console.log('所有key', storageInfo.keys)
console.log('当前大小', storageInfo.currentSize, 'KB')
console.log('限制大小', storageInfo.limitSize, 'KB')
} catch (err) {
console.error('获取失败', err)
}
```
## 返回值
| 参数名 | 类型 | 说明 |
|--------|------|------|
| keys | Array | 当前 storage 中所有的 key |
| currentSize | Number | 当前占用的空间大小,单位 KB |
| limitSize | Number | 限制的空间大小,单位 KB |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. 可以通过 `keys` 获取所有存储的 key
2. `currentSize``limitSize` 单位都是 KB
3. 建议定期检查存储空间使用情况
4. 同步版本 `getStorageInfoSync` 性能更好
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/api/storage/storage.html#getstorageinfo
- **同步版本**: https://uniapp.dcloud.net.cn/api/storage/storage.html#getstorageinfosync
- **清除存储**: https://uniapp.dcloud.net.cn/api/storage/storage.html#clearstorage
@@ -0,0 +1,200 @@
# uni.getStorageSync - 同步获取存储数据示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/api/storage/storage.html#getstoragesync
## 概述
`uni.getStorageSync` 用于从本地缓存中同步获取指定 key 的内容。
## 基础用法
```javascript
try {
const value = uni.getStorageSync('key')
console.log('获取的数据', value)
} catch (err) {
console.error('获取失败', err)
}
```
## 完整示例
### 示例 1: 获取用户信息
```javascript
try {
const userInfo = uni.getStorageSync('userInfo')
if (userInfo) {
console.log('用户信息', userInfo)
} else {
console.log('数据不存在')
}
} catch (err) {
console.error('获取失败', err)
}
```
### 示例 2: 获取 Token
```javascript
function getToken() {
try {
const token = uni.getStorageSync('token')
return token || null
} catch (err) {
console.error('获取Token失败', err)
return null
}
}
// 使用
const token = getToken()
if (token) {
console.log('Token存在', token)
} else {
console.log('未登录')
}
```
### 示例 3: 在页面中使用
```vue
<template>
<view class="container">
<view v-if="userInfo" class="user-info">
<text>用户名{{ userInfo.name }}</text>
<text>邮箱{{ userInfo.email }}</text>
</view>
<view v-else>
<text>未登录</text>
</view>
</view>
</template>
<script>
export default {
data() {
return {
userInfo: null
}
},
onLoad() {
this.loadUserInfo()
},
methods: {
loadUserInfo() {
try {
const userInfo = uni.getStorageSync('userInfo')
if (userInfo) {
this.userInfo = userInfo
}
} catch (err) {
console.error('获取用户信息失败', err)
}
}
}
}
</script>
```
### 示例 4: 封装获取函数
```javascript
// utils/storage.js
const storage = {
get(key, defaultValue = null) {
try {
const value = uni.getStorageSync(key)
return value !== '' ? value : defaultValue
} catch (err) {
console.error(`获取${key}失败`, err)
return defaultValue
}
},
getString(key, defaultValue = '') {
return this.get(key, defaultValue)
},
getNumber(key, defaultValue = 0) {
const value = this.get(key, defaultValue)
return Number(value) || defaultValue
},
getBoolean(key, defaultValue = false) {
const value = this.get(key, defaultValue)
return Boolean(value)
},
getObject(key, defaultValue = {}) {
const value = this.get(key, defaultValue)
return typeof value === 'object' ? value : defaultValue
}
}
// 使用
const userInfo = storage.getObject('userInfo', {})
const token = storage.getString('token', '')
const count = storage.getNumber('count', 0)
```
### 示例 5: 检查数据是否存在
```javascript
function hasStorage(key) {
try {
const value = uni.getStorageSync(key)
return value !== '' && value !== null && value !== undefined
} catch (err) {
return false
}
}
// 使用
if (hasStorage('userInfo')) {
console.log('用户信息存在')
} else {
console.log('用户信息不存在')
}
```
## 参数说明
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| key | String | 是 | 本地缓存中指定的 key |
## 返回值
| 类型 | 说明 |
|------|------|
| Any | key 对应的内容 |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. 同步接口会阻塞后续代码执行,性能比异步接口好
2. 如果 key 不存在,返回空字符串
3. 建议使用 try-catch 处理错误
4. 适合在页面初始化时获取数据
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/api/storage/storage.html#getstoragesync
- **异步版本**: https://uniapp.dcloud.net.cn/api/storage/storage.html#getstorage
- **设置存储**: https://uniapp.dcloud.net.cn/api/storage/storage.html#setstoragesync
@@ -0,0 +1,175 @@
# uni.getStorage - 获取存储数据示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/api/storage/storage.html#getstorage
## 概述
`uni.getStorage` 用于从本地缓存中异步获取指定 key 的内容。
## 基础用法
```javascript
uni.getStorage({
key: 'userInfo',
success: (res) => {
console.log('获取的数据', res.data)
}
})
```
## 完整示例
### 示例 1: 获取用户信息
```javascript
uni.getStorage({
key: 'userInfo',
success: (res) => {
const userInfo = res.data
console.log('用户信息', userInfo)
// 使用用户信息
},
fail: (err) => {
console.error('获取失败', err)
// 数据不存在或获取失败
}
})
```
### 示例 2: 获取字符串
```javascript
uni.getStorage({
key: 'token',
success: (res) => {
const token = res.data
console.log('Token', token)
// 使用 token
}
})
```
### 示例 3: 获取数组
```javascript
uni.getStorage({
key: 'shoppingCart',
success: (res) => {
const cart = res.data || []
console.log('购物车', cart)
}
})
```
### 示例 4: 封装获取函数
```javascript
// utils/storage.js
const storage = {
get(key) {
return new Promise((resolve, reject) => {
uni.getStorage({
key: key,
success: (res) => {
resolve(res.data)
},
fail: (err) => {
if (err.errMsg.includes('data not found')) {
resolve(null) // 数据不存在返回 null
} else {
reject(err)
}
}
})
})
}
}
// 使用
storage.get('userInfo')
.then(data => {
if (data) {
console.log('用户信息', data)
} else {
console.log('数据不存在')
}
})
.catch(err => {
console.error('获取失败', err)
})
```
### 示例 5: 在页面中使用
```vue
<template>
<view class="container">
<button @click="loadUserInfo">加载用户信息</button>
<view v-if="userInfo" class="user-info">
<text>用户名{{ userInfo.name }}</text>
<text>邮箱{{ userInfo.email }}</text>
</view>
</view>
</template>
<script>
export default {
data() {
return {
userInfo: null
}
},
onLoad() {
this.loadUserInfo()
},
methods: {
loadUserInfo() {
uni.getStorage({
key: 'userInfo',
success: (res) => {
this.userInfo = res.data
},
fail: () => {
uni.showToast({
title: '未登录',
icon: 'none'
})
}
})
}
}
}
</script>
```
## 同步版本
使用 `uni.getStorageSync` 进行同步获取:
```javascript
try {
const userInfo = uni.getStorageSync('userInfo')
if (userInfo) {
console.log('用户信息', userInfo)
} else {
console.log('数据不存在')
}
} catch (err) {
console.error('获取失败', err)
}
```
## 注意事项
1. 如果 key 不存在,会触发 fail 回调
2. 建议使用 try-catch 处理同步接口的错误
3. 获取的数据类型与存储时一致
4. 异步接口不会阻塞后续代码执行
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/api/storage/storage.html#getstorage
- **同步版本**: https://uniapp.dcloud.net.cn/api/storage/storage.html#getstoragesync
- **设置存储**: https://uniapp.dcloud.net.cn/api/storage/storage.html#setstorage
@@ -0,0 +1,160 @@
# uni.removeStorage - 删除存储数据示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/api/storage/storage.html#removestorage
## 概述
`uni.removeStorage` 用于从本地缓存中异步移除指定 key。
## 基础用法
```javascript
uni.removeStorage({
key: 'userInfo',
success: () => {
console.log('删除成功')
}
})
```
## 完整示例
### 示例 1: 删除单个数据
```javascript
uni.removeStorage({
key: 'token',
success: () => {
console.log('Token 已删除')
},
fail: (err) => {
console.error('删除失败', err)
}
})
```
### 示例 2: 退出登录时清除数据
```javascript
function logout() {
// 删除用户信息
uni.removeStorage({
key: 'userInfo',
success: () => {
console.log('用户信息已清除')
}
})
// 删除 Token
uni.removeStorage({
key: 'token',
success: () => {
console.log('Token 已清除')
// 跳转到登录页
uni.reLaunch({
url: '/pages/login/login'
})
}
})
}
```
### 示例 3: 批量删除
```javascript
const keysToRemove = ['userInfo', 'token', 'settings']
keysToRemove.forEach(key => {
uni.removeStorage({
key: key,
success: () => {
console.log(`${key} 已删除`)
}
})
})
```
### 示例 4: 在页面中使用
```vue
<template>
<view class="container">
<button @click="clearUserData">清除用户数据</button>
<button @click="clearAllData">清除所有数据</button>
</view>
</template>
<script>
export default {
methods: {
clearUserData() {
uni.removeStorage({
key: 'userInfo',
success: () => {
uni.showToast({
title: '用户数据已清除',
icon: 'success'
})
}
})
},
clearAllData() {
uni.clearStorage({
success: () => {
uni.showToast({
title: '所有数据已清除',
icon: 'success'
})
}
})
}
}
}
</script>
```
### 示例 5: 同步版本
```javascript
try {
uni.removeStorageSync('userInfo')
console.log('删除成功')
} catch (err) {
console.error('删除失败', err)
}
```
## 参数说明
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| key | String | 是 | 本地缓存中指定的 key |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. 如果 key 不存在,不会报错
2. 建议使用同步版本 `removeStorageSync` 性能更好
3. 删除操作是异步的,需要等待 success 回调
4. 退出登录时建议清除所有相关数据
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/api/storage/storage.html#removestorage
- **同步版本**: https://uniapp.dcloud.net.cn/api/storage/storage.html#removestoragesync
- **清除所有**: https://uniapp.dcloud.net.cn/api/storage/storage.html#clearstorage
@@ -0,0 +1,196 @@
# uni.setStorageSync - 同步设置存储数据示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/api/storage/storage.html#setstoragesync
## 概述
`uni.setStorageSync` 用于同步将数据存储在本地缓存中指定的 key 中。
## 基础用法
```javascript
try {
uni.setStorageSync('key', 'value')
console.log('存储成功')
} catch (err) {
console.error('存储失败', err)
}
```
## 完整示例
### 示例 1: 存储用户信息
```javascript
try {
const userInfo = {
name: 'John',
age: 30,
email: 'john@example.com'
}
uni.setStorageSync('userInfo', userInfo)
console.log('存储成功')
} catch (err) {
console.error('存储失败', err)
}
```
### 示例 2: 存储 Token
```javascript
function saveToken(token) {
try {
uni.setStorageSync('token', token)
return true
} catch (err) {
console.error('存储Token失败', err)
return false
}
}
// 使用
if (saveToken('abc123')) {
console.log('Token已保存')
}
```
### 示例 3: 在页面中使用
```vue
<template>
<view class="container">
<input v-model="username" placeholder="用户名" />
<input v-model="email" placeholder="邮箱" />
<button @click="saveUserInfo">保存用户信息</button>
</view>
</template>
<script>
export default {
data() {
return {
username: '',
email: ''
}
},
methods: {
saveUserInfo() {
try {
const userInfo = {
username: this.username,
email: this.email
}
uni.setStorageSync('userInfo', userInfo)
uni.showToast({
title: '保存成功',
icon: 'success'
})
} catch (err) {
uni.showToast({
title: '保存失败',
icon: 'none'
})
}
}
}
}
</script>
```
### 示例 4: 封装存储函数
```javascript
// utils/storage.js
const storage = {
set(key, value) {
try {
uni.setStorageSync(key, value)
return true
} catch (err) {
console.error(`存储${key}失败`, err)
return false
}
},
setString(key, value) {
return this.set(key, String(value))
},
setNumber(key, value) {
return this.set(key, Number(value))
},
setBoolean(key, value) {
return this.set(key, Boolean(value))
},
setObject(key, value) {
return this.set(key, value)
}
}
// 使用
storage.setString('token', 'abc123')
storage.setNumber('count', 10)
storage.setBoolean('isLogin', true)
storage.setObject('userInfo', { name: 'John' })
```
### 示例 5: 批量存储
```javascript
function saveMultipleData(data) {
try {
Object.keys(data).forEach(key => {
uni.setStorageSync(key, data[key])
})
return true
} catch (err) {
console.error('批量存储失败', err)
return false
}
}
// 使用
saveMultipleData({
token: 'abc123',
userInfo: { name: 'John' },
settings: { theme: 'dark' }
})
```
## 参数说明
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| key | String | 是 | 本地缓存中指定的 key |
| data | Any | 是 | 需要存储的内容 |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. 同步接口会阻塞后续代码执行,性能比异步接口好
2. 存储的数据类型与设置时一致
3. 建议使用 try-catch 处理错误
4. 单个 key 允许存储的最大数据长度为 1MB
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/api/storage/storage.html#setstoragesync
- **异步版本**: https://uniapp.dcloud.net.cn/api/storage/storage.html#setstorage
- **获取存储**: https://uniapp.dcloud.net.cn/api/storage/storage.html#getstoragesync
@@ -0,0 +1,160 @@
# uni.setStorage - 数据存储示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/api/storage/storage.html#setstorage
## 概述
`uni.setStorage` 用于将数据存储在本地缓存中指定的 key 中,异步接口。
## 基础用法
```javascript
uni.setStorage({
key: 'userInfo',
data: {
name: 'John',
age: 30
},
success: () => {
console.log('存储成功')
},
fail: (err) => {
console.error('存储失败', err)
}
})
```
## 完整示例
### 示例 1: 存储用户信息
```javascript
// 存储用户信息
const userInfo = {
id: 1,
name: 'John Doe',
email: 'john@example.com',
avatar: 'https://example.com/avatar.jpg'
}
uni.setStorage({
key: 'userInfo',
data: userInfo,
success: () => {
uni.showToast({
title: '保存成功',
icon: 'success'
})
},
fail: (err) => {
uni.showToast({
title: '保存失败',
icon: 'none'
})
}
})
```
### 示例 2: 存储字符串
```javascript
uni.setStorage({
key: 'token',
data: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...',
success: () => {
console.log('Token 已保存')
}
})
```
### 示例 3: 存储数组
```javascript
const shoppingCart = [
{ id: 1, name: '商品1', price: 99 },
{ id: 2, name: '商品2', price: 199 }
]
uni.setStorage({
key: 'shoppingCart',
data: shoppingCart,
success: () => {
console.log('购物车已保存')
}
})
```
### 示例 4: 封装存储函数
```javascript
// utils/storage.js
const storage = {
set(key, data) {
return new Promise((resolve, reject) => {
uni.setStorage({
key: key,
data: data,
success: () => {
resolve()
},
fail: (err) => {
reject(err)
}
})
})
},
get(key) {
return new Promise((resolve, reject) => {
uni.getStorage({
key: key,
success: (res) => {
resolve(res.data)
},
fail: (err) => {
reject(err)
}
})
})
}
}
// 使用
storage.set('userInfo', { name: 'John' })
.then(() => {
console.log('存储成功')
})
.catch(err => {
console.error('存储失败', err)
})
```
## 同步版本
使用 `uni.setStorageSync` 进行同步存储:
```javascript
try {
uni.setStorageSync('userInfo', {
name: 'John',
age: 30
})
console.log('存储成功')
} catch (err) {
console.error('存储失败', err)
}
```
## 注意事项
1. 存储的数据会被持久化,除非手动删除或清除缓存
2. 单个 key 允许存储的最大数据长度为 1MB
3. 异步接口不会阻塞后续代码执行
4. 建议使用 try-catch 处理同步接口的错误
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/api/storage/storage.html#setstorage
- **同步版本**: https://uniapp.dcloud.net.cn/api/storage/storage.html#setstoragesync
@@ -0,0 +1,189 @@
# uni.hideLoading - 隐藏加载提示示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/api/ui/prompt.html#hideloading
## 概述
`uni.hideLoading` 用于隐藏加载提示框。
## 基础用法
```javascript
uni.hideLoading()
```
## 完整示例
### 示例 1: 基本使用
```javascript
// 显示加载
uni.showLoading({
title: '加载中...'
})
// 隐藏加载
setTimeout(() => {
uni.hideLoading()
}, 2000)
```
### 示例 2: 网络请求中使用
```javascript
// 显示加载
uni.showLoading({
title: '加载中...',
mask: true
})
uni.request({
url: 'https://api.example.com/data',
success: (res) => {
console.log('数据', res.data)
},
complete: () => {
// 请求完成后隐藏加载
uni.hideLoading()
}
})
```
### 示例 3: 在页面中使用
```vue
<template>
<view class="container">
<button @click="loadData">加载数据</button>
</view>
</template>
<script>
export default {
methods: {
loadData() {
uni.showLoading({
title: '加载中...',
mask: true
})
uni.request({
url: 'https://api.example.com/data',
success: (res) => {
console.log('数据', res.data)
},
fail: (err) => {
console.error('加载失败', err)
},
complete: () => {
// 无论成功失败都要隐藏加载
uni.hideLoading()
}
})
}
}
}
</script>
```
### 示例 4: 封装加载函数
```javascript
// utils/loading.js
const loading = {
show(title = '加载中...') {
uni.showLoading({
title: title,
mask: true
})
},
hide() {
uni.hideLoading()
},
async withLoading(fn, title = '加载中...') {
this.show(title)
try {
const result = await fn()
return result
} finally {
this.hide()
}
}
}
// 使用
loading.withLoading(async () => {
const data = await fetchData()
return data
}, '加载数据中...')
```
### 示例 5: 确保隐藏加载
```javascript
function loadData() {
let loadingShown = false
try {
uni.showLoading({
title: '加载中...',
mask: true
})
loadingShown = true
// 执行加载逻辑
uni.request({
url: 'https://api.example.com/data',
success: (res) => {
console.log('数据', res.data)
},
complete: () => {
if (loadingShown) {
uni.hideLoading()
loadingShown = false
}
}
})
} catch (err) {
// 确保异常时也隐藏加载
if (loadingShown) {
uni.hideLoading()
loadingShown = false
}
}
}
```
## 参数说明
此 API 无需参数。
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. 必须与 `uni.showLoading` 配对使用
2. 建议在 `complete` 回调中调用,确保无论成功失败都会隐藏
3. 多次调用 `showLoading` 后,只需调用一次 `hideLoading` 即可隐藏
4. 建议使用 try-finally 确保异常时也能隐藏
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/api/ui/prompt.html#hideloading
- **显示加载**: https://uniapp.dcloud.net.cn/api/ui/prompt.html#showloading
@@ -0,0 +1,140 @@
# uni.hideNavigationBarLoading - 隐藏导航栏加载动画示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/api/ui/navigation-bar.html#hidenavigationbarloading
## 概述
`uni.hideNavigationBarLoading` 用于隐藏当前页面导航栏的加载动画。
## 基础用法
```javascript
uni.hideNavigationBarLoading()
```
## 完整示例
### 示例 1: 基本使用
```javascript
// 显示加载动画
uni.showNavigationBarLoading()
// 隐藏加载动画
uni.hideNavigationBarLoading()
```
### 示例 2: 网络请求中使用
```javascript
// 显示加载动画
uni.showNavigationBarLoading()
uni.request({
url: 'https://api.example.com/data',
success: (res) => {
console.log('数据', res.data)
},
complete: () => {
// 请求完成后隐藏
uni.hideNavigationBarLoading()
}
})
```
### 示例 3: 在页面中使用
```vue
<template>
<view class="container">
<button @click="loadData">加载数据</button>
</view>
</template>
<script>
export default {
methods: {
loadData() {
uni.showNavigationBarLoading()
uni.request({
url: 'https://api.example.com/data',
success: (res) => {
console.log('数据', res.data)
},
fail: (err) => {
console.error('加载失败', err)
},
complete: () => {
// 无论成功失败都要隐藏
uni.hideNavigationBarLoading()
}
})
}
}
}
</script>
```
### 示例 4: 确保隐藏
```javascript
function loadData() {
let loadingShown = false
try {
uni.showNavigationBarLoading()
loadingShown = true
uni.request({
url: 'https://api.example.com/data',
success: (res) => {
console.log('数据', res.data)
},
complete: () => {
if (loadingShown) {
uni.hideNavigationBarLoading()
loadingShown = false
}
}
})
} catch (err) {
// 确保异常时也隐藏
if (loadingShown) {
uni.hideNavigationBarLoading()
loadingShown = false
}
}
}
```
## 参数说明
此 API 无需参数。
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. 必须与 `uni.showNavigationBarLoading` 配对使用
2. 建议在 `complete` 回调中调用,确保无论成功失败都会隐藏
3. 多次调用 `showNavigationBarLoading` 后,只需调用一次 `hideNavigationBarLoading` 即可隐藏
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/api/ui/navigation-bar.html#hidenavigationbarloading
- **显示加载**: https://uniapp.dcloud.net.cn/api/ui/navigation-bar.html#shownavigationbarloading
@@ -0,0 +1,147 @@
# uni.hideTabBarRedDot - 隐藏 TabBar 红点示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/api/ui/tab-bar.html#hidetabbarreddot
## 概述
`uni.hideTabBarRedDot` 用于隐藏 tabBar 某一项的右上角的红点。
## 基础用法
```javascript
uni.hideTabBarRedDot({
index: 0
})
```
## 完整示例
### 示例 1: 隐藏红点
```javascript
uni.hideTabBarRedDot({
index: 0, // tabBar 的哪一项,从左边算起
success: () => {
console.log('隐藏成功')
},
fail: (err) => {
console.error('隐藏失败', err)
}
})
```
### 示例 2: 阅读消息后隐藏
```javascript
function readMessage(messageId) {
// 标记消息为已读
uni.request({
url: `https://api.example.com/messages/${messageId}/read`,
method: 'POST',
success: () => {
// 隐藏消息红点
uni.hideTabBarRedDot({
index: 1 // 消息页面的索引
})
}
})
}
```
### 示例 3: 在页面中使用
```vue
<template>
<view class="container">
<button @click="hideRedDot">隐藏红点</button>
</view>
</template>
<script>
export default {
methods: {
hideRedDot() {
uni.hideTabBarRedDot({
index: 0,
success: () => {
uni.showToast({
title: '已隐藏',
icon: 'success'
})
}
})
}
}
}
</script>
```
### 示例 4: 进入页面时隐藏
```vue
<template>
<view class="container">
<text>消息列表</text>
</view>
</template>
<script>
export default {
onLoad() {
// 进入消息页面时隐藏红点
uni.hideTabBarRedDot({
index: 1 // 当前页面的索引
})
}
}
</script>
```
### 示例 5: 清除所有红点
```javascript
function clearAllRedDots(tabBarCount) {
for (let i = 0; i < tabBarCount; i++) {
uni.hideTabBarRedDot({
index: i
})
}
}
// 使用(假设有4个tabBar
clearAllRedDots(4)
```
## 参数说明
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| index | Number | 是 | tabBar 的哪一项,从左边算起 |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. `index` 从 0 开始,对应 `pages.json` 中 tabBar 的配置顺序
2. 如果该 tabBar 项没有红点,调用此 API 不会报错
3. 建议在用户查看相关内容后隐藏红点
4.`showTabBarRedDot` 配合使用
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/api/ui/tab-bar.html#hidetabbarreddot
- **显示红点**: https://uniapp.dcloud.net.cn/api/ui/tab-bar.html#showtabbarreddot
@@ -0,0 +1,153 @@
# uni.hideToast - 隐藏消息提示示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/api/ui/prompt.html#hidetoast
## 概述
`uni.hideToast` 用于隐藏消息提示框。
## 基础用法
```javascript
uni.hideToast()
```
## 完整示例
### 示例 1: 基本使用
```javascript
// 显示提示
uni.showToast({
title: '操作成功',
icon: 'success'
})
// 提前隐藏
setTimeout(() => {
uni.hideToast()
}, 1000)
```
### 示例 2: 手动控制提示显示时间
```javascript
function showCustomToast(title, duration = 2000) {
uni.showToast({
title: title,
icon: 'none',
duration: duration
})
// 如果需要提前隐藏
setTimeout(() => {
uni.hideToast()
}, duration - 500)
}
```
### 示例 3: 在页面中使用
```vue
<template>
<view class="container">
<button @click="showMessage">显示消息</button>
<button @click="hideMessage">隐藏消息</button>
</view>
</template>
<script>
export default {
methods: {
showMessage() {
uni.showToast({
title: '这是一条消息',
icon: 'none',
duration: 5000
})
},
hideMessage() {
uni.hideToast()
}
}
}
</script>
```
### 示例 4: 替换提示内容
```javascript
function showReplacingToast(messages) {
let currentIndex = 0
const showNext = () => {
if (currentIndex < messages.length) {
uni.showToast({
title: messages[currentIndex],
icon: 'none',
duration: 2000
})
currentIndex++
setTimeout(() => {
uni.hideToast()
setTimeout(showNext, 100)
}, 2000)
}
}
showNext()
}
// 使用
showReplacingToast(['消息1', '消息2', '消息3'])
```
### 示例 5: 确保隐藏提示
```javascript
function showTemporaryToast(title) {
uni.showToast({
title: title,
icon: 'none',
duration: 3000
})
// 3秒后自动隐藏
setTimeout(() => {
uni.hideToast()
}, 3000)
}
```
## 参数说明
此 API 无需参数。
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. 用于提前隐藏通过 `uni.showToast` 显示的提示
2. 如果不调用,提示会在 `duration` 时间后自动消失
3. 建议在需要立即隐藏提示时使用
4. 通常不需要手动调用,除非需要提前隐藏
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/api/ui/prompt.html#hidetoast
- **显示提示**: https://uniapp.dcloud.net.cn/api/ui/prompt.html#showtoast
@@ -0,0 +1,171 @@
# uni.removeTabBarBadge - 移除 TabBar 徽标示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/api/ui/tab-bar.html#removetabbarbadge
## 概述
`uni.removeTabBarBadge` 用于移除 tabBar 某一项右上角的文本。
## 基础用法
```javascript
uni.removeTabBarBadge({
index: 0
})
```
## 完整示例
### 示例 1: 清除徽标
```javascript
uni.removeTabBarBadge({
index: 0, // tabBar 的哪一项,从左边算起
success: () => {
console.log('清除成功')
},
fail: (err) => {
console.error('清除失败', err)
}
})
```
### 示例 2: 清除未读消息徽标
```javascript
function clearUnreadBadge() {
uni.removeTabBarBadge({
index: 1, // 消息页面的索引
success: () => {
console.log('未读消息徽标已清除')
}
})
}
```
### 示例 3: 在页面中使用
```vue
<template>
<view class="container">
<button @click="clearBadge">清除徽标</button>
</view>
</template>
<script>
export default {
methods: {
clearBadge() {
uni.removeTabBarBadge({
index: 0,
success: () => {
uni.showToast({
title: '已清除',
icon: 'success'
})
}
})
}
}
}
</script>
```
### 示例 4: 阅读消息后清除
```vue
<template>
<view class="container">
<view
v-for="message in messages"
:key="message.id"
class="message-item"
@click="readMessage(message)"
>
<text>{{ message.content }}</text>
</view>
</view>
</template>
<script>
export default {
data() {
return {
messages: [
{ id: 1, content: '消息1', read: false },
{ id: 2, content: '消息2', read: false }
]
}
},
methods: {
readMessage(message) {
message.read = true
// 如果所有消息都已读,清除徽标
const allRead = this.messages.every(msg => msg.read)
if (allRead) {
uni.removeTabBarBadge({
index: 1 // 消息页面的索引
})
} else {
// 更新未读数
const unreadCount = this.messages.filter(msg => !msg.read).length
uni.setTabBarBadge({
index: 1,
text: String(unreadCount)
})
}
}
}
}
</script>
```
### 示例 5: 清除所有徽标
```javascript
function clearAllBadges(tabBarCount) {
for (let i = 0; i < tabBarCount; i++) {
uni.removeTabBarBadge({
index: i
})
}
}
// 使用(假设有4个tabBar
clearAllBadges(4)
```
## 参数说明
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| index | Number | 是 | tabBar 的哪一项,从左边算起 |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. `index` 从 0 开始,对应 `pages.json` 中 tabBar 的配置顺序
2. 如果该 tabBar 项没有徽标,调用此 API 不会报错
3. 建议在消息已读或数量为 0 时清除徽标
4.`setTabBarBadge` 配合使用
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/api/ui/tab-bar.html#removetabbarbadge
- **设置徽标**: https://uniapp.dcloud.net.cn/api/ui/tab-bar.html#settabbarbadge
@@ -0,0 +1,180 @@
# uni.setNavigationBarColor - 设置导航栏颜色示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/api/ui/navigation-bar.html#setnavigationbarcolor
## 概述
`uni.setNavigationBarColor` 用于设置页面导航栏颜色。
## 基础用法
```javascript
uni.setNavigationBarColor({
frontColor: '#ffffff',
backgroundColor: '#007aff'
})
```
## 完整示例
### 示例 1: 设置导航栏颜色
```javascript
uni.setNavigationBarColor({
frontColor: '#ffffff', // 前景颜色,包括按钮、标题、状态栏的颜色
backgroundColor: '#007aff', // 背景颜色
success: () => {
console.log('设置成功')
}
})
```
### 示例 2: 深色主题
```javascript
uni.setNavigationBarColor({
frontColor: '#ffffff',
backgroundColor: '#000000',
animation: {
duration: 400,
timingFunc: 'easeIn'
}
})
```
### 示例 3: 浅色主题
```javascript
uni.setNavigationBarColor({
frontColor: '#000000',
backgroundColor: '#ffffff',
animation: {
duration: 400,
timingFunc: 'easeIn'
}
})
```
### 示例 4: 在页面中使用
```vue
<template>
<view class="container">
<button @click="setDarkTheme">深色主题</button>
<button @click="setLightTheme">浅色主题</button>
<button @click="setCustomColor">自定义颜色</button>
</view>
</template>
<script>
export default {
methods: {
setDarkTheme() {
uni.setNavigationBarColor({
frontColor: '#ffffff',
backgroundColor: '#000000'
})
},
setLightTheme() {
uni.setNavigationBarColor({
frontColor: '#000000',
backgroundColor: '#ffffff'
})
},
setCustomColor() {
uni.setNavigationBarColor({
frontColor: '#ffffff',
backgroundColor: '#ff3b30',
animation: {
duration: 400,
timingFunc: 'easeIn'
}
})
}
}
}
</script>
```
### 示例 5: 根据内容动态设置
```vue
<template>
<view class="container">
<view v-if="article">
<text>{{ article.content }}</text>
</view>
</view>
</template>
<script>
export default {
data() {
return {
article: null
}
},
onLoad(options) {
this.loadArticle(options.id)
},
methods: {
loadArticle(id) {
uni.request({
url: `https://api.example.com/article/${id}`,
success: (res) => {
this.article = res.data
// 根据文章主题色设置导航栏
if (res.data.theme === 'dark') {
uni.setNavigationBarColor({
frontColor: '#ffffff',
backgroundColor: '#000000'
})
} else {
uni.setNavigationBarColor({
frontColor: '#000000',
backgroundColor: '#ffffff'
})
}
}
})
}
}
}
</script>
```
## 参数说明
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| frontColor | String | 是 | 前景颜色值,包括按钮、标题、状态栏的颜色,仅支持 #ffffff#000000 |
| backgroundColor | String | 是 | 背景颜色值,有效值为十六进制颜色 |
| animation | Object | 否 | 动画效果 |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. `frontColor` 仅支持 `#ffffff``#000000`
2. `backgroundColor` 支持任意十六进制颜色
3. 可以通过 `animation` 设置颜色切换动画
4. 建议与页面主题色保持一致
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/api/ui/navigation-bar.html#setnavigationbarcolor
- **设置标题**: https://uniapp.dcloud.net.cn/api/ui/navigation-bar.html#setnavigationbartitle
@@ -0,0 +1,191 @@
# uni.setNavigationBarTitle - 设置导航栏标题示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/api/ui/navigation-bar.html#setnavigationbartitle
## 概述
`uni.setNavigationBarTitle` 用于设置当前页面导航栏标题。
## 基础用法
```javascript
uni.setNavigationBarTitle({
title: '新标题'
})
```
## 完整示例
### 示例 1: 设置标题
```javascript
uni.setNavigationBarTitle({
title: '我的页面',
success: () => {
console.log('设置成功')
},
fail: (err) => {
console.error('设置失败', err)
}
})
```
### 示例 2: 动态设置标题
```vue
<template>
<view class="container">
<input v-model="pageTitle" placeholder="输入页面标题" />
<button @click="updateTitle">更新标题</button>
</view>
</template>
<script>
export default {
data() {
return {
pageTitle: ''
}
},
methods: {
updateTitle() {
if (this.pageTitle) {
uni.setNavigationBarTitle({
title: this.pageTitle
})
}
}
}
}
</script>
```
### 示例 3: 在页面生命周期中设置
```vue
<template>
<view class="container">
<text>页面内容</text>
</view>
</template>
<script>
export default {
onLoad(options) {
// 根据参数设置标题
if (options.type === 'detail') {
uni.setNavigationBarTitle({
title: '详情页'
})
} else {
uni.setNavigationBarTitle({
title: '列表页'
})
}
},
onReady() {
// 也可以在这里设置
uni.setNavigationBarTitle({
title: '页面标题'
})
}
}
</script>
```
### 示例 4: 根据数据设置标题
```vue
<template>
<view class="container">
<view v-if="article">
<text>{{ article.title }}</text>
</view>
</view>
</template>
<script>
export default {
data() {
return {
article: null
}
},
onLoad(options) {
this.loadArticle(options.id)
},
methods: {
loadArticle(id) {
uni.request({
url: `https://api.example.com/article/${id}`,
success: (res) => {
this.article = res.data
// 使用文章标题作为页面标题
uni.setNavigationBarTitle({
title: res.data.title
})
}
})
}
}
}
</script>
```
### 示例 5: 封装设置标题函数
```javascript
// utils/navigation.js
const navigation = {
setTitle(title) {
uni.setNavigationBarTitle({
title: title
})
},
setTitleWithSubtitle(mainTitle, subtitle) {
const fullTitle = subtitle ? `${mainTitle} - ${subtitle}` : mainTitle
uni.setNavigationBarTitle({
title: fullTitle
})
}
}
// 使用
navigation.setTitle('我的页面')
navigation.setTitleWithSubtitle('商品', '详情')
```
## 参数说明
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| title | String | 是 | 页面标题 |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. 标题长度建议不超过 10 个字符
2. 可以在 `onLoad``onReady` 中设置
3. 设置后立即生效
4. 建议根据页面内容动态设置标题
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/api/ui/navigation-bar.html#setnavigationbartitle
- **设置导航栏颜色**: https://uniapp.dcloud.net.cn/api/ui/navigation-bar.html#setnavigationbarcolor
@@ -0,0 +1,205 @@
# uni.setTabBarBadge - 设置 TabBar 徽标示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/api/ui/tab-bar.html#settabbarbadge
## 概述
`uni.setTabBarBadge` 用于为 tabBar 某一项的右上角添加文本。
## 基础用法
```javascript
uni.setTabBarBadge({
index: 0,
text: '1'
})
```
## 完整示例
### 示例 1: 设置徽标
```javascript
uni.setTabBarBadge({
index: 0, // tabBar 的哪一项,从左边算起
text: '5' // 显示的文本,超过 3 个字符则显示成 "..."
})
```
### 示例 2: 显示未读消息数
```javascript
function updateUnreadCount(count) {
if (count > 0) {
const text = count > 99 ? '99+' : String(count)
uni.setTabBarBadge({
index: 1, // 消息页面的索引
text: text
})
} else {
// 清除徽标
uni.removeTabBarBadge({
index: 1
})
}
}
// 使用
updateUnreadCount(5) // 显示 "5"
updateUnreadCount(100) // 显示 "99+"
updateUnreadCount(0) // 清除徽标
```
### 示例 3: 在页面中使用
```vue
<template>
<view class="container">
<button @click="setBadge">设置徽标</button>
<button @click="removeBadge">清除徽标</button>
</view>
</template>
<script>
export default {
methods: {
setBadge() {
uni.setTabBarBadge({
index: 0,
text: '5'
})
uni.showToast({
title: '已设置徽标',
icon: 'success'
})
},
removeBadge() {
uni.removeTabBarBadge({
index: 0
})
uni.showToast({
title: '已清除徽标',
icon: 'success'
})
}
}
}
</script>
```
### 示例 4: 实时更新未读消息
```vue
<template>
<view class="container">
<text>未读消息{{ unreadCount }}</text>
<button @click="refreshUnreadCount">刷新未读数</button>
</view>
</template>
<script>
export default {
data() {
return {
unreadCount: 0
}
},
onLoad() {
this.loadUnreadCount()
// 定时刷新
setInterval(() => {
this.loadUnreadCount()
}, 30000) // 每30秒刷新一次
},
methods: {
loadUnreadCount() {
uni.request({
url: 'https://api.example.com/unread-count',
success: (res) => {
this.unreadCount = res.data.count
this.updateTabBarBadge(res.data.count)
}
})
},
updateTabBarBadge(count) {
if (count > 0) {
const text = count > 99 ? '99+' : String(count)
uni.setTabBarBadge({
index: 1, // 消息页面的索引
text: text
})
} else {
uni.removeTabBarBadge({
index: 1
})
}
},
refreshUnreadCount() {
this.loadUnreadCount()
}
}
}
</script>
```
### 示例 5: 多个 TabBar 徽标
```javascript
function updateAllTabBarBadges(badges) {
// badges: [{ index: 0, text: '5' }, { index: 1, text: '10' }]
badges.forEach(badge => {
if (badge.text && badge.text !== '0') {
uni.setTabBarBadge({
index: badge.index,
text: badge.text
})
} else {
uni.removeTabBarBadge({
index: badge.index
})
}
})
}
// 使用
updateAllTabBarBadges([
{ index: 0, text: '5' },
{ index: 1, text: '10' },
{ index: 2, text: '0' } // 清除
])
```
## 参数说明
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| index | Number | 是 | tabBar 的哪一项,从左边算起 |
| text | String | 是 | 显示的文本,超过 3 个字符则显示成 "..." |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. `index` 从 0 开始,对应 `pages.json` 中 tabBar 的配置顺序
2. `text` 超过 3 个字符会显示成 "..."
3. 建议数字超过 99 时显示 "99+"
4. 使用 `removeTabBarBadge` 可以清除徽标
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/api/ui/tab-bar.html#settabbarbadge
- **清除徽标**: https://uniapp.dcloud.net.cn/api/ui/tab-bar.html#removetabbarbadge
@@ -0,0 +1,168 @@
# uni.setTabBarStyle - 设置 TabBar 样式示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/api/ui/tab-bar.html#settabbarstyle
## 概述
`uni.setTabBarStyle` 用于动态设置 tabBar 的整体样式。
## 基础用法
```javascript
uni.setTabBarStyle({
color: '#7A7E83',
selectedColor: '#3cc51f',
backgroundColor: '#ffffff'
})
```
## 完整示例
### 示例 1: 设置 TabBar 样式
```javascript
uni.setTabBarStyle({
color: '#7A7E83', // 未选中时的文字颜色
selectedColor: '#3cc51f', // 选中时的文字颜色
backgroundColor: '#ffffff', // 背景颜色
borderStyle: 'black', // 边框颜色
success: () => {
console.log('设置成功')
}
})
```
### 示例 2: 深色主题
```javascript
function setDarkTheme() {
uni.setTabBarStyle({
color: '#999999',
selectedColor: '#ffffff',
backgroundColor: '#000000',
borderStyle: 'white'
})
}
```
### 示例 3: 浅色主题
```javascript
function setLightTheme() {
uni.setTabBarStyle({
color: '#7A7E83',
selectedColor: '#007aff',
backgroundColor: '#ffffff',
borderStyle: 'black'
})
}
```
### 示例 4: 在页面中使用
```vue
<template>
<view class="container">
<button @click="setDarkTheme">深色主题</button>
<button @click="setLightTheme">浅色主题</button>
<button @click="setCustomTheme">自定义主题</button>
</view>
</template>
<script>
export default {
methods: {
setDarkTheme() {
uni.setTabBarStyle({
color: '#999999',
selectedColor: '#ffffff',
backgroundColor: '#000000',
borderStyle: 'white'
})
},
setLightTheme() {
uni.setTabBarStyle({
color: '#7A7E83',
selectedColor: '#007aff',
backgroundColor: '#ffffff',
borderStyle: 'black'
})
},
setCustomTheme() {
uni.setTabBarStyle({
color: '#666666',
selectedColor: '#ff3b30',
backgroundColor: '#f5f5f5',
borderStyle: 'black'
})
}
}
}
</script>
```
### 示例 5: 根据系统主题设置
```javascript
function setTabBarThemeBySystem() {
uni.getSystemInfo({
success: (res) => {
// 根据系统主题设置(需要自己判断)
const isDark = res.theme === 'dark' // 某些平台支持
if (isDark) {
uni.setTabBarStyle({
color: '#999999',
selectedColor: '#ffffff',
backgroundColor: '#000000',
borderStyle: 'white'
})
} else {
uni.setTabBarStyle({
color: '#7A7E83',
selectedColor: '#007aff',
backgroundColor: '#ffffff',
borderStyle: 'black'
})
}
}
})
}
```
## 参数说明
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| color | String | 否 | tab 上的文字默认颜色 |
| selectedColor | String | 否 | tab 上的文字选中时的颜色 |
| backgroundColor | String | 否 | tab 的背景色 |
| borderStyle | String | 否 | tabbar 上边框的颜色,可选值:black、white |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. 设置后立即生效
2. `color``selectedColor` 建议使用对比度高的颜色
3. `borderStyle` 可选值为 `black``white`
4. 建议与页面主题色保持一致
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/api/ui/tab-bar.html#settabbarstyle
- **设置 TabBar 项**: https://uniapp.dcloud.net.cn/api/ui/tab-bar.html#settabbaritem
@@ -0,0 +1,217 @@
# uni.showActionSheet - 操作菜单示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/api/ui/prompt.html#showactionsheet
## 概述
`uni.showActionSheet` 用于显示操作菜单,从底部弹出选择项。
## 基础用法
```javascript
uni.showActionSheet({
itemList: ['选项1', '选项2', '选项3'],
success: (res) => {
console.log('选择了第', res.tapIndex, '个选项')
}
})
```
## 完整示例
### 示例 1: 基本操作菜单
```javascript
uni.showActionSheet({
itemList: ['拍照', '从相册选择', '取消'],
success: (res) => {
if (res.tapIndex === 0) {
// 拍照
console.log('选择拍照')
} else if (res.tapIndex === 1) {
// 从相册选择
console.log('从相册选择')
}
}
})
```
### 示例 2: 图片选择
```javascript
uni.showActionSheet({
itemList: ['拍照', '从相册选择'],
success: (res) => {
if (res.tapIndex === 0) {
// 拍照
uni.chooseImage({
count: 1,
sourceType: ['camera'],
success: (imageRes) => {
console.log('拍照成功', imageRes.tempFilePaths)
}
})
} else if (res.tapIndex === 1) {
// 从相册选择
uni.chooseImage({
count: 1,
sourceType: ['album'],
success: (imageRes) => {
console.log('选择成功', imageRes.tempFilePaths)
}
})
}
}
})
```
### 示例 3: 分享功能
```javascript
uni.showActionSheet({
itemList: ['分享到微信', '分享到朋友圈', '复制链接'],
success: (res) => {
switch (res.tapIndex) {
case 0:
// 分享到微信
uni.share({
provider: 'weixin',
scene: 'WXSceneSession'
})
break
case 1:
// 分享到朋友圈
uni.share({
provider: 'weixin',
scene: 'WXSceneTimeline'
})
break
case 2:
// 复制链接
uni.setClipboardData({
data: 'https://example.com',
success: () => {
uni.showToast({
title: '链接已复制',
icon: 'success'
})
}
})
break
}
}
})
```
### 示例 4: 在页面中使用
```vue
<template>
<view class="container">
<button @click="showMoreOptions">更多操作</button>
</view>
</template>
<script>
export default {
methods: {
showMoreOptions() {
uni.showActionSheet({
itemList: ['编辑', '删除', '分享', '举报'],
success: (res) => {
switch (res.tapIndex) {
case 0:
this.handleEdit()
break
case 1:
this.handleDelete()
break
case 2:
this.handleShare()
break
case 3:
this.handleReport()
break
}
}
})
},
handleEdit() {
console.log('编辑')
},
handleDelete() {
uni.showModal({
title: '提示',
content: '确定要删除吗?',
success: (res) => {
if (res.confirm) {
console.log('删除')
}
}
})
},
handleShare() {
console.log('分享')
},
handleReport() {
console.log('举报')
}
}
}
</script>
```
### 示例 5: 带取消按钮
```javascript
uni.showActionSheet({
itemList: ['选项1', '选项2', '选项3'],
success: (res) => {
console.log('选择了', res.tapIndex)
},
fail: (res) => {
console.log('取消选择')
}
})
```
## 参数说明
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| itemList | Array | 是 | 按钮的文字数组 |
| itemColor | String | 否 | 按钮的文字颜色 |
## 返回值
| 参数名 | 类型 | 说明 |
|--------|------|------|
| tapIndex | Number | 用户点击的按钮序号,从上到下的顺序,从0开始 |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. `itemList` 数组最多支持 6 个选项
2. 用户点击取消或遮罩层会触发 fail 回调
3. `tapIndex` 从 0 开始,对应 `itemList` 的索引
4. 建议将"取消"选项放在最后
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/api/ui/prompt.html#showactionsheet
- **模态弹窗**: https://uniapp.dcloud.net.cn/api/ui/prompt.html#showmodal
@@ -0,0 +1,189 @@
# uni.showLoading - 加载提示示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/api/ui/prompt.html#showloading
## 概述
`uni.showLoading` 用于显示加载提示框,常用于异步操作时显示加载状态。
## 基础用法
```javascript
uni.showLoading({
title: '加载中...'
})
```
## 完整示例
### 示例 1: 基本加载提示
```javascript
uni.showLoading({
title: '加载中...',
mask: true
})
// 操作完成后隐藏
setTimeout(() => {
uni.hideLoading()
}, 2000)
```
### 示例 2: 网络请求时显示加载
```javascript
uni.showLoading({
title: '加载中...',
mask: true
})
uni.request({
url: 'https://api.example.com/data',
success: (res) => {
console.log('数据', res.data)
},
complete: () => {
uni.hideLoading()
}
})
```
### 示例 3: 在页面中使用
```vue
<template>
<view class="container">
<button @click="loadData">加载数据</button>
<view v-if="data">{{ data }}</view>
</view>
</template>
<script>
export default {
data() {
return {
data: null
}
},
methods: {
loadData() {
uni.showLoading({
title: '加载中...',
mask: true
})
// 模拟请求
setTimeout(() => {
this.data = '数据加载完成'
uni.hideLoading()
uni.showToast({
title: '加载成功',
icon: 'success'
})
}, 2000)
}
}
}
</script>
```
### 示例 4: 封装加载函数
```javascript
// utils/loading.js
const loading = {
show(title = '加载中...') {
uni.showLoading({
title: title,
mask: true
})
},
hide() {
uni.hideLoading()
},
async withLoading(fn, title = '加载中...') {
this.show(title)
try {
const result = await fn()
return result
} finally {
this.hide()
}
}
}
// 使用
loading.withLoading(async () => {
const data = await fetchData()
return data
}, '加载数据中...')
```
### 示例 5: 配合请求使用
```javascript
// 显示加载
uni.showLoading({
title: '提交中...',
mask: true
})
// 提交数据
uni.request({
url: 'https://api.example.com/submit',
method: 'POST',
data: { name: 'test' },
success: (res) => {
uni.hideLoading()
uni.showToast({
title: '提交成功',
icon: 'success'
})
},
fail: (err) => {
uni.hideLoading()
uni.showToast({
title: '提交失败',
icon: 'none'
})
}
})
```
## 参数说明
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| title | String | 是 | 提示的内容 |
| mask | Boolean | 否 | 是否显示透明蒙层,防止触摸穿透 |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. 必须调用 `uni.hideLoading()` 才能关闭加载提示
2. `mask: true` 可以防止用户在加载时操作页面
3. 建议在异步操作的开始显示,在完成时隐藏
4. 不要在 `success` 回调中忘记调用 `hideLoading`
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/api/ui/prompt.html#showloading
- **隐藏加载**: https://uniapp.dcloud.net.cn/api/ui/prompt.html#hideloading
@@ -0,0 +1,226 @@
# uni.showModal - 模态弹窗示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/api/ui/prompt.html#showmodal
## 概述
`uni.showModal` 用于显示模态弹窗,常用于确认操作。
## 基础用法
```javascript
uni.showModal({
title: '提示',
content: '确定要删除吗?',
success: (res) => {
if (res.confirm) {
console.log('用户点击确定')
} else if (res.cancel) {
console.log('用户点击取消')
}
}
})
```
## 完整示例
### 示例 1: 确认删除
```javascript
uni.showModal({
title: '提示',
content: '确定要删除这条记录吗?',
confirmText: '删除',
cancelText: '取消',
success: (res) => {
if (res.confirm) {
// 执行删除操作
console.log('确认删除')
}
}
})
```
### 示例 2: 自定义按钮文字
```javascript
uni.showModal({
title: '提示',
content: '确定要退出登录吗?',
confirmText: '退出',
cancelText: '取消',
confirmColor: '#ff3b30',
success: (res) => {
if (res.confirm) {
// 退出登录
uni.removeStorageSync('token')
uni.reLaunch({
url: '/pages/login/login'
})
}
}
})
```
### 示例 3: 只显示确定按钮
```javascript
uni.showModal({
title: '提示',
content: '操作成功',
showCancel: false,
success: (res) => {
if (res.confirm) {
console.log('用户点击确定')
}
}
})
```
### 示例 4: 在页面中使用
```vue
<template>
<view class="container">
<button @click="handleDelete">删除记录</button>
<button @click="handleLogout">退出登录</button>
</view>
</template>
<script>
export default {
methods: {
handleDelete() {
uni.showModal({
title: '确认删除',
content: '删除后无法恢复,确定要删除吗?',
confirmText: '删除',
cancelText: '取消',
confirmColor: '#ff3b30',
success: (res) => {
if (res.confirm) {
// 执行删除
this.deleteRecord()
}
}
})
},
handleLogout() {
uni.showModal({
title: '提示',
content: '确定要退出登录吗?',
success: (res) => {
if (res.confirm) {
uni.removeStorageSync('token')
uni.reLaunch({
url: '/pages/login/login'
})
}
}
})
},
deleteRecord() {
// 删除逻辑
uni.showToast({
title: '删除成功',
icon: 'success'
})
}
}
}
</script>
```
### 示例 5: 封装确认函数
```javascript
// utils/modal.js
const modal = {
confirm(title, content) {
return new Promise((resolve, reject) => {
uni.showModal({
title: title,
content: content,
success: (res) => {
if (res.confirm) {
resolve(true)
} else {
resolve(false)
}
},
fail: (err) => {
reject(err)
}
})
})
},
alert(title, content) {
return new Promise((resolve) => {
uni.showModal({
title: title,
content: content,
showCancel: false,
success: () => {
resolve()
}
})
})
}
}
// 使用
const result = await modal.confirm('提示', '确定要删除吗?')
if (result) {
console.log('用户确认')
} else {
console.log('用户取消')
}
```
## 参数说明
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| title | String | 否 | 提示的标题 |
| content | String | 否 | 提示的内容 |
| showCancel | Boolean | 否 | 是否显示取消按钮,默认 true |
| cancelText | String | 否 | 取消按钮的文字,默认"取消" |
| cancelColor | String | 否 | 取消按钮的文字颜色 |
| confirmText | String | 否 | 确认按钮的文字,默认"确定" |
| confirmColor | String | 否 | 确认按钮的文字颜色 |
## 返回值
| 参数名 | 类型 | 说明 |
|--------|------|------|
| confirm | Boolean | 为 true 时,表示用户点击了确定按钮 |
| cancel | Boolean | 为 true 时,表示用户点击了取消按钮 |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. `title``content` 至少需要提供一个
2. 确认和取消按钮的文字可以自定义
3. 可以通过 `showCancel: false` 只显示确定按钮
4. 建议用于重要的确认操作
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/api/ui/prompt.html#showmodal
- **消息提示**: https://uniapp.dcloud.net.cn/api/ui/prompt.html#showtoast
@@ -0,0 +1,194 @@
# uni.showNavigationBarLoading - 显示导航栏加载动画示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/api/ui/navigation-bar.html#shownavigationbarloading
## 概述
`uni.showNavigationBarLoading` 用于在当前页面导航栏显示加载动画。
## 基础用法
```javascript
uni.showNavigationBarLoading()
```
## 完整示例
### 示例 1: 基本使用
```javascript
// 显示加载动画
uni.showNavigationBarLoading()
// 隐藏加载动画
setTimeout(() => {
uni.hideNavigationBarLoading()
}, 2000)
```
### 示例 2: 网络请求时显示
```javascript
// 显示加载动画
uni.showNavigationBarLoading()
uni.request({
url: 'https://api.example.com/data',
success: (res) => {
console.log('数据', res.data)
},
complete: () => {
// 请求完成后隐藏
uni.hideNavigationBarLoading()
}
})
```
### 示例 3: 在页面中使用
```vue
<template>
<view class="container">
<button @click="loadData">加载数据</button>
</view>
</template>
<script>
export default {
methods: {
loadData() {
// 显示导航栏加载动画
uni.showNavigationBarLoading()
uni.request({
url: 'https://api.example.com/data',
success: (res) => {
console.log('数据', res.data)
},
fail: (err) => {
console.error('加载失败', err)
},
complete: () => {
// 无论成功失败都要隐藏
uni.hideNavigationBarLoading()
}
})
}
}
}
</script>
```
### 示例 4: 封装加载函数
```javascript
// utils/loading.js
const loading = {
showNavBar() {
uni.showNavigationBarLoading()
},
hideNavBar() {
uni.hideNavigationBarLoading()
},
async withNavBarLoading(fn) {
this.showNavBar()
try {
const result = await fn()
return result
} finally {
this.hideNavBar()
}
}
}
// 使用
loading.withNavBarLoading(async () => {
const data = await fetchData()
return data
})
```
### 示例 5: 页面刷新时显示
```vue
<template>
<view class="container">
<button @click="refresh">刷新</button>
</view>
</template>
<script>
export default {
methods: {
refresh() {
// 显示导航栏加载动画
uni.showNavigationBarLoading()
// 模拟刷新
setTimeout(() => {
uni.hideNavigationBarLoading()
uni.showToast({
title: '刷新成功',
icon: 'success'
})
}, 2000)
}
},
onPullDownRefresh() {
// 下拉刷新时显示
uni.showNavigationBarLoading()
// 刷新数据
this.loadData()
},
methods: {
loadData() {
uni.request({
url: 'https://api.example.com/data',
success: (res) => {
console.log('数据', res.data)
},
complete: () => {
uni.hideNavigationBarLoading()
uni.stopPullDownRefresh()
}
})
}
}
}
</script>
```
## 参数说明
此 API 无需参数。
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. 必须与 `uni.hideNavigationBarLoading` 配对使用
2. 在导航栏标题旁边显示加载动画
3. 适合页面级别的加载状态
4. 建议在 `complete` 回调中隐藏
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/api/ui/navigation-bar.html#shownavigationbarloading
- **隐藏加载**: https://uniapp.dcloud.net.cn/api/ui/navigation-bar.html#hidenavigationbarloading
@@ -0,0 +1,199 @@
# uni.showTabBarRedDot - 显示 TabBar 红点示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/api/ui/tab-bar.html#showtabbarreddot
## 概述
`uni.showTabBarRedDot` 用于显示 tabBar 某一项的右上角的红点。
## 基础用法
```javascript
uni.showTabBarRedDot({
index: 0
})
```
## 完整示例
### 示例 1: 显示红点
```javascript
uni.showTabBarRedDot({
index: 0, // tabBar 的哪一项,从左边算起
success: () => {
console.log('显示成功')
},
fail: (err) => {
console.error('显示失败', err)
}
})
```
### 示例 2: 显示消息红点
```javascript
function showMessageRedDot() {
uni.showTabBarRedDot({
index: 1, // 消息页面的索引
success: () => {
console.log('消息红点已显示')
}
})
}
```
### 示例 3: 在页面中使用
```vue
<template>
<view class="container">
<button @click="showRedDot">显示红点</button>
<button @click="hideRedDot">隐藏红点</button>
</view>
</template>
<script>
export default {
methods: {
showRedDot() {
uni.showTabBarRedDot({
index: 0,
success: () => {
uni.showToast({
title: '已显示红点',
icon: 'success'
})
}
})
},
hideRedDot() {
uni.hideTabBarRedDot({
index: 0,
success: () => {
uni.showToast({
title: '已隐藏红点',
icon: 'success'
})
}
})
}
}
}
</script>
```
### 示例 4: 根据状态显示红点
```vue
<template>
<view class="container">
<view v-if="hasNewMessage" class="message-list">
<view
v-for="message in messages"
:key="message.id"
class="message-item"
@click="readMessage(message)"
>
<text>{{ message.content }}</text>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
messages: [],
hasNewMessage: false
}
},
onLoad() {
this.loadMessages()
},
methods: {
loadMessages() {
uni.request({
url: 'https://api.example.com/messages',
success: (res) => {
this.messages = res.data
this.hasNewMessage = res.data.some(msg => !msg.read)
// 根据是否有新消息显示红点
if (this.hasNewMessage) {
uni.showTabBarRedDot({
index: 1 // 消息页面的索引
})
} else {
uni.hideTabBarRedDot({
index: 1
})
}
}
})
},
readMessage(message) {
message.read = true
this.hasNewMessage = this.messages.some(msg => !msg.read)
if (!this.hasNewMessage) {
uni.hideTabBarRedDot({
index: 1
})
}
}
}
}
</script>
```
### 示例 5: 多个 TabBar 红点
```javascript
function showAllRedDots(indices) {
indices.forEach(index => {
uni.showTabBarRedDot({
index: index
})
})
}
// 使用
showAllRedDots([0, 1, 2]) // 显示第0、1、2项的红点
```
## 参数说明
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| index | Number | 是 | tabBar 的哪一项,从左边算起 |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. `index` 从 0 开始,对应 `pages.json` 中 tabBar 的配置顺序
2. 红点不显示数字,只显示一个小红点
3.`setTabBarBadge` 的区别:红点不显示文字,徽标显示文字
4. 使用 `hideTabBarRedDot` 可以隐藏红点
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/api/ui/tab-bar.html#showtabbarreddot
- **隐藏红点**: https://uniapp.dcloud.net.cn/api/ui/tab-bar.html#hidetabbarreddot
- **设置徽标**: https://uniapp.dcloud.net.cn/api/ui/tab-bar.html#settabbarbadge
@@ -0,0 +1,188 @@
# uni.showToast - 消息提示示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/api/ui/prompt.html#showtoast
## 概述
`uni.showToast` 用于显示消息提示框,常用于操作反馈。
## 基础用法
```javascript
uni.showToast({
title: '操作成功',
icon: 'success'
})
```
## 完整示例
### 示例 1: 成功提示
```javascript
uni.showToast({
title: '操作成功',
icon: 'success',
duration: 2000
})
```
### 示例 2: 错误提示
```javascript
uni.showToast({
title: '操作失败',
icon: 'error',
duration: 2000
})
```
### 示例 3: 加载提示
```javascript
uni.showToast({
title: '加载中...',
icon: 'loading',
duration: 2000
})
```
### 示例 4: 无图标提示
```javascript
uni.showToast({
title: '这是一条消息',
icon: 'none',
duration: 2000
})
```
### 示例 5: 自定义图片
```javascript
uni.showToast({
title: '自定义图标',
image: '/static/custom-icon.png',
duration: 2000
})
```
### 示例 6: 封装提示函数
```javascript
// utils/toast.js
const toast = {
success(title, duration = 2000) {
uni.showToast({
title: title,
icon: 'success',
duration: duration
})
},
error(title, duration = 2000) {
uni.showToast({
title: title,
icon: 'error',
duration: duration
})
},
loading(title, duration = 2000) {
uni.showToast({
title: title,
icon: 'loading',
duration: duration
})
},
info(title, duration = 2000) {
uni.showToast({
title: title,
icon: 'none',
duration: duration
})
}
}
// 使用
toast.success('保存成功')
toast.error('保存失败')
toast.info('这是一条消息')
```
### 示例 7: 在页面中使用
```vue
<template>
<view class="container">
<button @click="handleSuccess">成功提示</button>
<button @click="handleError">错误提示</button>
<button @click="handleLoading">加载提示</button>
</view>
</template>
<script>
export default {
methods: {
handleSuccess() {
uni.showToast({
title: '操作成功',
icon: 'success'
})
},
handleError() {
uni.showToast({
title: '操作失败',
icon: 'error'
})
},
handleLoading() {
uni.showToast({
title: '加载中...',
icon: 'loading',
duration: 3000
})
}
}
}
</script>
```
## 参数说明
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| title | String | 是 | 提示的内容 |
| icon | String | 否 | 图标类型,可选值:success、error、loading、none |
| image | String | 否 | 自定义图标的本地路径 |
| duration | Number | 否 | 提示的延迟时间,单位 ms,默认 2000 |
| mask | Boolean | 否 | 是否显示透明蒙层,防止触摸穿透 |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. `title` 长度限制:微信小程序最多 7 个汉字长度
2. 同时只能显示一个 toast,新的 toast 会覆盖旧的
3. 使用 `uni.hideToast()` 可以手动关闭 toast
4. `mask` 参数在某些平台可能不支持
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/api/ui/prompt.html#showtoast
- **隐藏提示**: https://uniapp.dcloud.net.cn/api/ui/prompt.html#hidetoast
@@ -0,0 +1,320 @@
# audio 组件示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/component/audio.html
## 概述
`audio` 是音频播放组件,用于播放音频。
## 基础用法
```vue
<template>
<audio src="https://example.com/audio.mp3" controls></audio>
</template>
```
## 完整示例
### 示例 1: 基本音频播放
```vue
<template>
<view class="container">
<audio
:src="audioSrc"
controls
class="audio-player"
></audio>
</view>
</template>
<script>
export default {
data() {
return {
audioSrc: 'https://example.com/audio.mp3'
}
}
}
</script>
<style>
.audio-player {
width: 100%;
}
</style>
```
### 示例 2: 音频播放控制
```vue
<template>
<view class="container">
<audio
:src="audioSrc"
:controls="showControls"
:autoplay="autoplay"
:loop="loop"
@play="handlePlay"
@pause="handlePause"
@ended="handleEnded"
class="audio-player"
></audio>
<view class="controls">
<button @click="togglePlay">{{ isPlaying ? '暂停' : '播放' }}</button>
<button @click="toggleLoop">{{ loop ? '取消循环' : '循环播放' }}</button>
</view>
</view>
</template>
<script>
export default {
data() {
return {
audioSrc: 'https://example.com/audio.mp3',
showControls: true,
autoplay: false,
loop: false,
isPlaying: false
}
},
methods: {
handlePlay() {
this.isPlaying = true
console.log('音频开始播放')
},
handlePause() {
this.isPlaying = false
console.log('音频暂停')
},
handleEnded() {
this.isPlaying = false
console.log('音频播放结束')
},
togglePlay() {
// 需要通过 ref 调用音频组件的方法
if (this.isPlaying) {
this.$refs.audio.pause()
} else {
this.$refs.audio.play()
}
},
toggleLoop() {
this.loop = !this.loop
}
}
}
</script>
```
### 示例 3: 音频列表
```vue
<template>
<view class="container">
<view
v-for="(item, index) in audioList"
:key="index"
class="audio-item"
>
<text class="audio-title">{{ item.title }}</text>
<audio
:src="item.src"
controls
class="audio-player"
@play="handleAudioPlay(index)"
></audio>
</view>
</view>
</template>
<script>
export default {
data() {
return {
audioList: [
{
src: 'https://example.com/audio1.mp3',
title: '音频1'
},
{
src: 'https://example.com/audio2.mp3',
title: '音频2'
}
]
}
},
methods: {
handleAudioPlay(index) {
console.log('播放音频', index)
}
}
}
</script>
<style>
.audio-item {
margin-bottom: 20px;
padding: 20px;
border-bottom: 1px solid #eee;
}
.audio-title {
display: block;
font-size: 32rpx;
margin-bottom: 10px;
}
.audio-player {
width: 100%;
}
</style>
```
### 示例 4: 播放进度显示
```vue
<template>
<view class="container">
<audio
:src="audioSrc"
controls
@timeupdate="handleTimeUpdate"
class="audio-player"
></audio>
<view class="progress-info">
<text>播放进度{{ currentTime }}s / {{ duration }}s</text>
</view>
</view>
</template>
<script>
export default {
data() {
return {
audioSrc: 'https://example.com/audio.mp3',
currentTime: 0,
duration: 0
}
},
methods: {
handleTimeUpdate(e) {
this.currentTime = e.detail.currentTime
this.duration = e.detail.duration
}
}
}
</script>
```
### 示例 5: 自定义播放器
```vue
<template>
<view class="container">
<view class="custom-player">
<text class="audio-title">{{ currentAudio.title }}</text>
<view class="player-controls">
<button @click="playPrevious">上一首</button>
<button @click="togglePlay">{{ isPlaying ? '暂停' : '播放' }}</button>
<button @click="playNext">下一首</button>
</view>
<audio
ref="audio"
:src="currentAudio.src"
:autoplay="autoplay"
@play="handlePlay"
@pause="handlePause"
@ended="handleEnded"
></audio>
</view>
</view>
</template>
<script>
export default {
data() {
return {
audioList: [
{ src: 'https://example.com/audio1.mp3', title: '音频1' },
{ src: 'https://example.com/audio2.mp3', title: '音频2' },
{ src: 'https://example.com/audio3.mp3', title: '音频3' }
],
currentIndex: 0,
isPlaying: false,
autoplay: false
}
},
computed: {
currentAudio() {
return this.audioList[this.currentIndex]
}
},
methods: {
togglePlay() {
if (this.isPlaying) {
this.$refs.audio.pause()
} else {
this.$refs.audio.play()
}
},
playPrevious() {
this.currentIndex = (this.currentIndex - 1 + this.audioList.length) % this.audioList.length
this.autoplay = true
},
playNext() {
this.currentIndex = (this.currentIndex + 1) % this.audioList.length
this.autoplay = true
},
handlePlay() {
this.isPlaying = true
this.autoplay = false
},
handlePause() {
this.isPlaying = false
},
handleEnded() {
this.isPlaying = false
// 自动播放下一首
this.playNext()
}
}
}
</script>
```
## 属性说明
| 属性名 | 类型 | 默认值 | 说明 |
|--------|------|--------|------|
| src | String | - | 要播放音频的资源地址 |
| controls | Boolean | false | 是否显示默认播放控件 |
| autoplay | Boolean | false | 是否自动播放 |
| loop | Boolean | false | 是否循环播放 |
| muted | Boolean | false | 是否静音播放 |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. 音频地址需要配置合法域名
2. `autoplay` 在某些平台可能不生效
3. 可以通过事件监听播放状态
4. 建议使用 `controls` 显示播放控件
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/component/audio.html
@@ -0,0 +1,233 @@
# button 组件示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/component/button.html
## 概述
`button` 是按钮组件,用于触发操作。
## 基础用法
```vue
<template>
<button @click="handleClick">点击按钮</button>
</template>
<script>
export default {
methods: {
handleClick() {
console.log('按钮被点击')
}
}
}
</script>
```
## 完整示例
### 示例 1: 按钮类型
```vue
<template>
<view class="container">
<button type="default">默认按钮</button>
<button type="primary">主要按钮</button>
<button type="warn">警告按钮</button>
</view>
</template>
<style>
.container {
padding: 20px;
}
button {
margin-bottom: 20px;
}
</style>
```
### 示例 2: 按钮大小
```vue
<template>
<view class="container">
<button size="mini">小按钮</button>
<button size="default">默认按钮</button>
</view>
</template>
```
### 示例 3: 镂空按钮
```vue
<template>
<view class="container">
<button type="primary" plain>镂空按钮</button>
<button type="warn" plain>镂空警告按钮</button>
</view>
</template>
```
### 示例 4: 禁用按钮
```vue
<template>
<view class="container">
<button disabled>禁用按钮</button>
<button :disabled="isDisabled" @click="handleClick">
{{ isDisabled ? '已禁用' : '可点击' }}
</button>
</view>
</template>
<script>
export default {
data() {
return {
isDisabled: false
}
},
methods: {
handleClick() {
this.isDisabled = true
setTimeout(() => {
this.isDisabled = false
}, 2000)
}
}
}
</script>
```
### 示例 5: 加载状态
```vue
<template>
<view class="container">
<button :loading="isLoading" @click="handleSubmit">
提交
</button>
</view>
</template>
<script>
export default {
data() {
return {
isLoading: false
}
},
methods: {
async handleSubmit() {
this.isLoading = true
try {
// 模拟请求
await new Promise(resolve => setTimeout(resolve, 2000))
uni.showToast({
title: '提交成功',
icon: 'success'
})
} finally {
this.isLoading = false
}
}
}
}
</script>
```
### 示例 6: 表单提交
```vue
<template>
<form @submit="handleSubmit">
<input name="username" placeholder="用户名" />
<input name="password" type="password" placeholder="密码" />
<button form-type="submit">提交</button>
<button form-type="reset">重置</button>
</form>
</template>
<script>
export default {
methods: {
handleSubmit(e) {
console.log('表单数据', e.detail.value)
}
}
}
</script>
```
### 示例 7: 开放能力(微信小程序)
```vue
<template>
<view class="container">
<!-- 获取用户信息 -->
<button open-type="getUserInfo" @getuserinfo="getUserInfo">
获取用户信息
</button>
<!-- 打开客服会话 -->
<button open-type="contact">联系客服</button>
<!-- 分享 -->
<button open-type="share">分享</button>
<!-- 打开设置 -->
<button open-type="openSetting">打开设置</button>
</view>
</template>
<script>
export default {
methods: {
getUserInfo(e) {
console.log('用户信息', e.detail.userInfo)
}
}
}
</script>
```
## 属性说明
| 属性名 | 类型 | 默认值 | 说明 |
|--------|------|--------|------|
| size | String | default | 按钮的大小,可选值:default、mini |
| type | String | default | 按钮的样式类型,可选值:primary、default、warn |
| plain | Boolean | false | 按钮是否镂空,背景色透明 |
| disabled | Boolean | false | 是否禁用 |
| loading | Boolean | false | 名称前是否带 loading 图标 |
| form-type | String | - | 用于 form 组件,可选值:submit、reset |
| open-type | String | - | 开放能力,如:getUserInfo、contact、share 等 |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. `open-type` 在不同平台支持的能力不同
2. 按钮的样式可以通过 CSS 自定义
3. `loading` 图标在不同平台显示可能不同
4. 建议使用 `@click` 事件处理点击,而不是依赖 `open-type`
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/component/button.html
- **表单组件**: https://uniapp.dcloud.net.cn/component/form.html
@@ -0,0 +1,347 @@
# camera 组件示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/component/camera.html
## 概述
`camera` 是相机组件,用于调用设备相机进行拍照或录像。
## 基础用法
```vue
<template>
<camera
device-position="back"
@error="handleError"
></camera>
</template>
<script>
export default {
methods: {
handleError(e) {
console.error('相机错误', e.detail)
}
}
}
</script>
```
## 完整示例
### 示例 1: 基本相机
```vue
<template>
<view class="container">
<camera
device-position="back"
flash="off"
class="camera"
@error="handleError"
></camera>
<button @click="takePhoto">拍照</button>
</view>
</template>
<script>
export default {
methods: {
takePhoto() {
const ctx = uni.createCameraContext('myCamera', this)
ctx.takePhoto({
quality: 'high',
success: (res) => {
console.log('拍照成功', res.tempImagePath)
uni.previewImage({
urls: [res.tempImagePath]
})
}
})
},
handleError(e) {
console.error('相机错误', e.detail)
}
}
}
</script>
<style>
.camera {
width: 100%;
height: 500px;
}
</style>
```
### 示例 2: 拍照和录像
```vue
<template>
<view class="container">
<camera
ref="camera"
device-position="back"
flash="off"
class="camera"
@error="handleError"
></camera>
<view class="controls">
<button @click="takePhoto">拍照</button>
<button @click="startRecord">开始录像</button>
<button @click="stopRecord">停止录像</button>
<button @click="switchCamera">切换摄像头</button>
</view>
</view>
</template>
<script>
export default {
data() {
return {
isRecording: false
}
},
methods: {
takePhoto() {
const ctx = uni.createCameraContext('myCamera', this)
ctx.takePhoto({
quality: 'high',
success: (res) => {
console.log('拍照成功', res.tempImagePath)
}
})
},
startRecord() {
const ctx = uni.createCameraContext('myCamera', this)
ctx.startRecord({
success: () => {
this.isRecording = true
console.log('开始录像')
}
})
},
stopRecord() {
const ctx = uni.createCameraContext('myCamera', this)
ctx.stopRecord({
success: (res) => {
this.isRecording = false
console.log('录像成功', res.tempVideoPath)
}
})
},
switchCamera() {
// 需要通过 ref 切换
this.$refs.camera.switchCamera()
},
handleError(e) {
console.error('相机错误', e.detail)
}
}
}
</script>
```
### 示例 3: 切换摄像头和闪光灯
```vue
<template>
<view class="container">
<camera
:device-position="devicePosition"
:flash="flash"
class="camera"
></camera>
<view class="controls">
<button @click="switchCamera">切换摄像头</button>
<button @click="toggleFlash">切换闪光灯</button>
</view>
</view>
</template>
<script>
export default {
data() {
return {
devicePosition: 'back',
flash: 'off'
}
},
methods: {
switchCamera() {
this.devicePosition = this.devicePosition === 'back' ? 'front' : 'back'
},
toggleFlash() {
const flashOptions = ['off', 'on', 'auto', 'torch']
const currentIndex = flashOptions.indexOf(this.flash)
this.flash = flashOptions[(currentIndex + 1) % flashOptions.length]
}
}
}
</script>
```
### 示例 4: 拍照并上传
```vue
<template>
<view class="container">
<camera
device-position="back"
class="camera"
></camera>
<button @click="takePhotoAndUpload">拍照并上传</button>
</view>
</template>
<script>
export default {
methods: {
takePhotoAndUpload() {
const ctx = uni.createCameraContext('myCamera', this)
ctx.takePhoto({
quality: 'high',
success: (res) => {
// 上传图片
uni.uploadFile({
url: 'https://api.example.com/upload',
filePath: res.tempImagePath,
name: 'file',
success: (uploadRes) => {
const data = JSON.parse(uploadRes.data)
console.log('上传成功', data.url)
uni.showToast({
title: '上传成功',
icon: 'success'
})
}
})
}
})
}
}
}
</script>
```
### 示例 5: 自定义相机界面
```vue
<template>
<view class="container">
<camera
device-position="back"
flash="off"
class="camera"
></camera>
<view class="camera-overlay">
<view class="camera-controls">
<button class="control-btn" @click="switchCamera">切换</button>
<button class="control-btn capture-btn" @click="takePhoto">拍照</button>
<button class="control-btn" @click="toggleFlash">闪光</button>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
devicePosition: 'back',
flash: 'off'
}
},
methods: {
takePhoto() {
const ctx = uni.createCameraContext('myCamera', this)
ctx.takePhoto({
quality: 'high',
success: (res) => {
uni.previewImage({
urls: [res.tempImagePath]
})
}
})
},
switchCamera() {
this.devicePosition = this.devicePosition === 'back' ? 'front' : 'back'
},
toggleFlash() {
const flashOptions = ['off', 'on', 'auto']
const currentIndex = flashOptions.indexOf(this.flash)
this.flash = flashOptions[(currentIndex + 1) % flashOptions.length]
}
}
}
</script>
<style>
.camera {
width: 100%;
height: 100vh;
}
.camera-overlay {
position: fixed;
bottom: 0;
left: 0;
right: 0;
background: rgba(0, 0, 0, 0.5);
padding: 20px;
}
.camera-controls {
display: flex;
justify-content: space-around;
align-items: center;
}
.control-btn {
width: 60px;
height: 60px;
border-radius: 50%;
background-color: rgba(255, 255, 255, 0.3);
color: white;
}
.capture-btn {
width: 80px;
height: 80px;
background-color: white;
color: #333;
}
</style>
```
## 属性说明
| 属性名 | 类型 | 默认值 | 说明 |
|--------|------|--------|------|
| device-position | String | back | 摄像头朝向,可选值:back、front |
| flash | String | off | 闪光灯,可选值:on、off、auto、torch |
| frame-size | String | medium | 指定期望的相机帧数据尺寸,可选值:small、medium、large |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ❌ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. H5 平台不支持此组件
2. 需要通过 `uni.createCameraContext` 创建相机上下文
3. 拍照和录像需要通过上下文方法调用
4. 建议全屏显示相机组件
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/component/camera.html
- **Camera API**: https://uniapp.dcloud.net.cn/api/media/camera.html
@@ -0,0 +1,247 @@
# canvas 组件示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/component/canvas.html
## 概述
`canvas` 是画布组件,用于绘制图形、文字等。
## 基础用法
```vue
<template>
<canvas canvas-id="myCanvas" class="canvas"></canvas>
</template>
<script>
export default {
onReady() {
this.drawCanvas()
},
methods: {
drawCanvas() {
const ctx = uni.createCanvasContext('myCanvas', this)
ctx.setFillStyle('#007aff')
ctx.fillRect(0, 0, 200, 200)
ctx.draw()
}
}
}
</script>
<style>
.canvas {
width: 200px;
height: 200px;
}
</style>
```
## 完整示例
### 示例 1: 绘制矩形
```vue
<template>
<view class="container">
<canvas canvas-id="myCanvas" class="canvas"></canvas>
<button @click="drawRect">绘制矩形</button>
</view>
</template>
<script>
export default {
onReady() {
this.drawRect()
},
methods: {
drawRect() {
const ctx = uni.createCanvasContext('myCanvas', this)
ctx.setFillStyle('#007aff')
ctx.fillRect(10, 10, 150, 100)
ctx.draw()
}
}
}
</script>
<style>
.canvas {
width: 200px;
height: 200px;
border: 1px solid #eee;
}
</style>
```
### 示例 2: 绘制圆形
```vue
<template>
<view class="container">
<canvas canvas-id="myCanvas" class="canvas"></canvas>
<button @click="drawCircle">绘制圆形</button>
</view>
</template>
<script>
export default {
onReady() {
this.drawCircle()
},
methods: {
drawCircle() {
const ctx = uni.createCanvasContext('myCanvas', this)
ctx.beginPath()
ctx.arc(100, 100, 50, 0, 2 * Math.PI)
ctx.setFillStyle('#4cd964')
ctx.fill()
ctx.draw()
}
}
}
</script>
```
### 示例 3: 绘制文字
```vue
<template>
<view class="container">
<canvas canvas-id="myCanvas" class="canvas"></canvas>
<button @click="drawText">绘制文字</button>
</view>
</template>
<script>
export default {
onReady() {
this.drawText()
},
methods: {
drawText() {
const ctx = uni.createCanvasContext('myCanvas', this)
ctx.setFontSize(20)
ctx.setFillStyle('#333')
ctx.fillText('Hello Canvas', 10, 50)
ctx.draw()
}
}
}
</script>
```
### 示例 4: 绘制图片
```vue
<template>
<view class="container">
<canvas canvas-id="myCanvas" class="canvas"></canvas>
<button @click="drawImage">绘制图片</button>
</view>
</template>
<script>
export default {
onReady() {
this.drawImage()
},
methods: {
drawImage() {
const ctx = uni.createCanvasContext('myCanvas', this)
uni.downloadFile({
url: 'https://example.com/image.jpg',
success: (res) => {
ctx.drawImage(res.tempFilePath, 0, 0, 200, 200)
ctx.draw()
}
})
}
}
}
</script>
```
### 示例 5: 保存为图片
```vue
<template>
<view class="container">
<canvas canvas-id="myCanvas" class="canvas"></canvas>
<button @click="drawAndSave">绘制并保存</button>
</view>
</template>
<script>
export default {
onReady() {
this.drawCanvas()
},
methods: {
drawCanvas() {
const ctx = uni.createCanvasContext('myCanvas', this)
ctx.setFillStyle('#007aff')
ctx.fillRect(0, 0, 200, 200)
ctx.setFontSize(20)
ctx.setFillStyle('#fff')
ctx.fillText('Canvas', 70, 100)
ctx.draw()
},
drawAndSave() {
this.drawCanvas()
setTimeout(() => {
uni.canvasToTempFilePath({
canvasId: 'myCanvas',
success: (res) => {
uni.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success: () => {
uni.showToast({
title: '保存成功',
icon: 'success'
})
}
})
}
}, this)
}, 500)
}
}
}
</script>
```
## 属性说明
| 属性名 | 类型 | 默认值 | 说明 |
|--------|------|--------|------|
| canvas-id | String | - | canvas 组件的唯一标识符 |
| disable-scroll | Boolean | false | 当在 canvas 中移动时且有绑定手势事件时,禁止屏幕滚动以及下拉刷新 |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. 需要在 `onReady` 生命周期中绘制
2. 调用 `ctx.draw()` 才会真正绘制到画布上
3. 可以通过 `uni.canvasToTempFilePath` 将画布转为图片
4. 不同平台的 API 可能略有差异
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/component/canvas.html
- **Canvas API**: https://uniapp.dcloud.net.cn/api/canvas/canvas.html
@@ -0,0 +1,233 @@
# checkbox 组件示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/component/checkbox.html
## 概述
`checkbox` 是多项选择器组件,用于多选场景。
## 基础用法
```vue
<template>
<checkbox value="option1" checked>选项1</checkbox>
</template>
```
## 完整示例
### 示例 1: 单个复选框
```vue
<template>
<view class="container">
<checkbox value="agree" :checked="isAgreed" @tap="handleChange">
我已阅读并同意协议
</checkbox>
</view>
</template>
<script>
export default {
data() {
return {
isAgreed: false
}
},
methods: {
handleChange(e) {
this.isAgreed = e.detail.value.length > 0
console.log('选中状态', this.isAgreed)
}
}
}
</script>
```
### 示例 2: 复选框组
```vue
<template>
<view class="container">
<checkbox-group @change="handleGroupChange">
<label v-for="item in options" :key="item.value" class="checkbox-item">
<checkbox :value="item.value" :checked="item.checked" />
<text>{{ item.label }}</text>
</label>
</checkbox-group>
<text>已选择{{ selectedValues.join(', ') }}</text>
</view>
</template>
<script>
export default {
data() {
return {
options: [
{ value: 'option1', label: '选项1', checked: false },
{ value: 'option2', label: '选项2', checked: false },
{ value: 'option3', label: '选项3', checked: false }
],
selectedValues: []
}
},
methods: {
handleGroupChange(e) {
this.selectedValues = e.detail.value
console.log('选中的值', this.selectedValues)
}
}
}
</script>
<style>
.checkbox-item {
display: flex;
align-items: center;
padding: 10px;
}
</style>
```
### 示例 3: 全选功能
```vue
<template>
<view class="container">
<checkbox-group @change="handleGroupChange">
<label class="checkbox-item">
<checkbox
value="all"
:checked="isAllSelected"
@tap="handleSelectAll"
/>
<text>全选</text>
</label>
<label
v-for="item in list"
:key="item.id"
class="checkbox-item"
>
<checkbox
:value="item.id"
:checked="item.checked"
/>
<text>{{ item.name }}</text>
</label>
</checkbox-group>
</view>
</template>
<script>
export default {
data() {
return {
list: [
{ id: '1', name: '项目1', checked: false },
{ id: '2', name: '项目2', checked: false },
{ id: '3', name: '项目3', checked: false }
]
}
},
computed: {
isAllSelected() {
return this.list.every(item => item.checked)
}
},
methods: {
handleSelectAll() {
const allSelected = this.isAllSelected
this.list.forEach(item => {
item.checked = !allSelected
})
},
handleGroupChange(e) {
const selectedIds = e.detail.value.filter(id => id !== 'all')
this.list.forEach(item => {
item.checked = selectedIds.includes(item.id)
})
}
}
}
</script>
```
### 示例 4: 在表单中使用
```vue
<template>
<form @submit="handleSubmit">
<view class="form-item">
<text>兴趣爱好</text>
<checkbox-group name="hobbies" @change="handleHobbiesChange">
<label v-for="hobby in hobbies" :key="hobby.value" class="checkbox-item">
<checkbox :value="hobby.value" />
<text>{{ hobby.label }}</text>
</label>
</checkbox-group>
</view>
<button form-type="submit">提交</button>
</form>
</template>
<script>
export default {
data() {
return {
hobbies: [
{ value: 'reading', label: '阅读' },
{ value: 'music', label: '音乐' },
{ value: 'sports', label: '运动' },
{ value: 'travel', label: '旅行' }
],
selectedHobbies: []
}
},
methods: {
handleHobbiesChange(e) {
this.selectedHobbies = e.detail.value
},
handleSubmit(e) {
console.log('选中的兴趣爱好', this.selectedHobbies)
}
}
}
</script>
```
## 属性说明
| 属性名 | 类型 | 默认值 | 说明 |
|--------|------|--------|------|
| value | String | - | checkbox 标识,选中时触发 change 事件,并携带 value |
| checked | Boolean | false | 当前是否选中 |
| disabled | Boolean | false | 是否禁用 |
| color | String | #007aff | checkbox 的颜色 |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. 需要配合 `checkbox-group` 使用才能获取选中的值
2. `value` 用于标识不同的选项
3. `checked` 属性控制选中状态
4. 可以通过 `@change` 事件监听变化
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/component/checkbox.html
- **表单组件**: https://uniapp.dcloud.net.cn/component/form.html
@@ -0,0 +1,321 @@
# form 组件示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/component/form.html
## 概述
`form` 是表单组件,用于收集用户输入的数据。
## 基础用法
```vue
<template>
<form @submit="handleSubmit">
<input name="username" placeholder="用户名" />
<button form-type="submit">提交</button>
</form>
</template>
<script>
export default {
methods: {
handleSubmit(e) {
console.log('表单数据', e.detail.value)
}
}
}
</script>
```
## 完整示例
### 示例 1: 基本表单
```vue
<template>
<form @submit="handleSubmit">
<view class="form-item">
<text>用户名</text>
<input name="username" placeholder="请输入用户名" />
</view>
<view class="form-item">
<text>密码</text>
<input name="password" type="password" placeholder="请输入密码" />
</view>
<button form-type="submit">提交</button>
<button form-type="reset">重置</button>
</form>
</template>
<script>
export default {
methods: {
handleSubmit(e) {
const formData = e.detail.value
console.log('表单数据', formData)
// { username: 'xxx', password: 'xxx' }
}
}
}
</script>
<style>
.form-item {
display: flex;
align-items: center;
padding: 20px;
border-bottom: 1px solid #eee;
}
</style>
```
### 示例 2: 完整登录表单
```vue
<template>
<form @submit="handleLogin">
<view class="form-item">
<input
name="username"
placeholder="请输入用户名"
v-model="username"
/>
</view>
<view class="form-item">
<input
name="password"
type="password"
placeholder="请输入密码"
v-model="password"
/>
</view>
<button form-type="submit" :loading="loading">登录</button>
</form>
</template>
<script>
export default {
data() {
return {
username: '',
password: '',
loading: false
}
},
methods: {
handleLogin(e) {
const formData = e.detail.value
this.loading = true
uni.request({
url: 'https://api.example.com/login',
method: 'POST',
data: formData,
success: (res) => {
if (res.data.success) {
uni.setStorageSync('token', res.data.token)
uni.showToast({
title: '登录成功',
icon: 'success'
})
setTimeout(() => {
uni.switchTab({
url: '/pages/index/index'
})
}, 1500)
}
},
complete: () => {
this.loading = false
}
})
}
}
}
</script>
```
### 示例 3: 表单验证
```vue
<template>
<form @submit="handleSubmit">
<view class="form-item">
<input
name="email"
type="text"
placeholder="请输入邮箱"
v-model="email"
/>
<text v-if="emailError" class="error">{{ emailError }}</text>
</view>
<view class="form-item">
<input
name="phone"
type="tel"
placeholder="请输入手机号"
maxlength="11"
v-model="phone"
/>
<text v-if="phoneError" class="error">{{ phoneError }}</text>
</view>
<button form-type="submit">提交</button>
</form>
</template>
<script>
export default {
data() {
return {
email: '',
phone: '',
emailError: '',
phoneError: ''
}
},
methods: {
validateEmail() {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
if (!this.email) {
this.emailError = '邮箱不能为空'
} else if (!emailRegex.test(this.email)) {
this.emailError = '邮箱格式不正确'
} else {
this.emailError = ''
}
},
validatePhone() {
const phoneRegex = /^1[3-9]\d{9}$/
if (!this.phone) {
this.phoneError = '手机号不能为空'
} else if (!phoneRegex.test(this.phone)) {
this.phoneError = '手机号格式不正确'
} else {
this.phoneError = ''
}
},
handleSubmit(e) {
this.validateEmail()
this.validatePhone()
if (!this.emailError && !this.phoneError) {
const formData = e.detail.value
console.log('表单数据', formData)
uni.showToast({
title: '提交成功',
icon: 'success'
})
}
}
}
}
</script>
<style>
.error {
color: #ff3b30;
font-size: 24rpx;
margin-top: 10rpx;
}
</style>
```
### 示例 4: 复杂表单
```vue
<template>
<form @submit="handleSubmit">
<view class="form-item">
<text>姓名</text>
<input name="name" placeholder="请输入姓名" />
</view>
<view class="form-item">
<text>性别</text>
<radio-group name="gender">
<label>
<radio value="male" />
</label>
<label>
<radio value="female" />
</label>
</radio-group>
</view>
<view class="form-item">
<text>兴趣爱好</text>
<checkbox-group name="hobbies">
<label>
<checkbox value="reading" /> 阅读
</label>
<label>
<checkbox value="music" /> 音乐
</label>
<label>
<checkbox value="sports" /> 运动
</label>
</checkbox-group>
</view>
<view class="form-item">
<text>城市</text>
<picker mode="region" name="city">
<view>请选择城市</view>
</picker>
</view>
<button form-type="submit">提交</button>
</form>
</template>
<script>
export default {
methods: {
handleSubmit(e) {
console.log('表单数据', e.detail.value)
}
}
}
</script>
```
## 属性说明
| 属性名 | 类型 | 默认值 | 说明 |
|--------|------|--------|------|
| report-submit | Boolean | false | 是否返回 formId 用于发送模板消息 |
## 事件说明
| 事件名 | 说明 | 返回值 |
|--------|------|--------|
| @submit | 携带 form 中的数据触发 submit 事件 | e.detail.value 包含所有表单数据 |
| @reset | 表单重置时会触发 reset 事件 | - |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. 表单内的组件需要设置 `name` 属性才能被收集
2. `form-type="submit"` 的按钮会触发表单提交
3. `form-type="reset"` 的按钮会重置表单
4. 可以通过 `e.detail.value` 获取所有表单数据
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/component/form.html
- **输入框**: https://uniapp.dcloud.net.cn/component/input.html
@@ -0,0 +1,160 @@
# icon 组件示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/component/icon.html
## 概述
`icon` 是图标组件,用于显示各种图标。
## 基础用法
```vue
<template>
<icon type="success" size="20" color="#4cd964"></icon>
</template>
```
## 完整示例
### 示例 1: 不同类型的图标
```vue
<template>
<view class="container">
<view class="icon-item">
<icon type="success" size="26" color="#4cd964"></icon>
<text>成功</text>
</view>
<view class="icon-item">
<icon type="info" size="26" color="#909399"></icon>
<text>信息</text>
</view>
<view class="icon-item">
<icon type="warn" size="26" color="#ff9500"></icon>
<text>警告</text>
</view>
<view class="icon-item">
<icon type="waiting" size="26" color="#007aff"></icon>
<text>等待</text>
</view>
<view class="icon-item">
<icon type="clear" size="26" color="#ff3b30"></icon>
<text>清除</text>
</view>
<view class="icon-item">
<icon type="search" size="26" color="#333"></icon>
<text>搜索</text>
</view>
</view>
</template>
<style>
.container {
display: flex;
flex-wrap: wrap;
padding: 20px;
}
.icon-item {
display: flex;
flex-direction: column;
align-items: center;
margin: 20px;
}
</style>
```
### 示例 2: 不同大小的图标
```vue
<template>
<view class="container">
<icon type="success" size="20" color="#4cd964"></icon>
<icon type="success" size="30" color="#4cd964"></icon>
<icon type="success" size="40" color="#4cd964"></icon>
<icon type="success" size="50" color="#4cd964"></icon>
</view>
</template>
<style>
.container {
display: flex;
align-items: center;
gap: 20px;
padding: 20px;
}
</style>
```
### 示例 3: 不同颜色的图标
```vue
<template>
<view class="container">
<icon type="success" size="30" color="#4cd964"></icon>
<icon type="success" size="30" color="#007aff"></icon>
<icon type="success" size="30" color="#ff3b30"></icon>
<icon type="success" size="30" color="#ff9500"></icon>
</view>
</template>
```
### 示例 4: 在按钮中使用
```vue
<template>
<view class="container">
<button class="icon-button">
<icon type="search" size="20" color="#fff"></icon>
<text>搜索</text>
</button>
<button class="icon-button">
<icon type="success" size="20" color="#fff"></icon>
<text>确认</text>
</button>
</view>
</template>
<style>
.icon-button {
display: flex;
align-items: center;
gap: 10px;
}
</style>
```
## 属性说明
| 属性名 | 类型 | 默认值 | 说明 |
|--------|------|--------|------|
| type | String | - | icon 的类型,可选值:success、info、warn、waiting、clear、search 等 |
| size | Number | 23 | icon 的大小,单位 px |
| color | String | - | icon 的颜色,同 CSS 的 color |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. `type` 的值在不同平台可能不同
2. 建议使用 uni-icons 组件库获得更多图标
3. `size` 单位为 px,不是 rpx
4. `color` 可以使用任何 CSS 颜色值
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/component/icon.html
- **uni-icons**: https://ext.dcloud.net.cn/plugin?id=28
@@ -0,0 +1,373 @@
# image 组件示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/component/image.html
## 概述
`image` 是图片组件,用于显示图片。
## 基础用法
```vue
<template>
<image src="/static/logo.png" mode="aspectFit"></image>
</template>
```
## 完整示例
### 示例 1: 图片显示模式
```vue
<template>
<view class="container">
<view class="image-item">
<text>scaleToFill默认</text>
<image
src="/static/logo.png"
mode="scaleToFill"
style="width: 200px; height: 200px;"
></image>
</view>
<view class="image-item">
<text>aspectFit</text>
<image
src="/static/logo.png"
mode="aspectFit"
style="width: 200px; height: 200px;"
></image>
</view>
<view class="image-item">
<text>aspectFill</text>
<image
src="/static/logo.png"
mode="aspectFill"
style="width: 200px; height: 200px;"
></image>
</view>
<view class="image-item">
<text>widthFix</text>
<image
src="/static/logo.png"
mode="widthFix"
style="width: 200px;"
></image>
</view>
</view>
</template>
<style>
.container {
padding: 20px;
}
.image-item {
margin-bottom: 30px;
}
</style>
```
### 示例 2: 图片列表
```vue
<template>
<view class="container">
<view class="image-list">
<image
v-for="(item, index) in imageList"
:key="index"
:src="item"
mode="aspectFill"
class="image-item"
@click="previewImage(index)"
></image>
</view>
</view>
</template>
<script>
export default {
data() {
return {
imageList: [
'https://example.com/image1.jpg',
'https://example.com/image2.jpg',
'https://example.com/image3.jpg'
]
}
},
methods: {
previewImage(index) {
uni.previewImage({
current: index,
urls: this.imageList
})
}
}
}
</script>
<style>
.image-list {
display: flex;
flex-wrap: wrap;
}
.image-item {
width: 200rpx;
height: 200rpx;
margin: 10rpx;
border-radius: 8rpx;
}
</style>
```
### 示例 3: 图片懒加载
```vue
<template>
<scroll-view scroll-y class="scroll-view">
<image
v-for="(item, index) in imageList"
:key="index"
:src="item"
mode="aspectFill"
lazy-load
class="lazy-image"
></image>
</scroll-view>
</template>
<script>
export default {
data() {
return {
imageList: [
'https://example.com/image1.jpg',
'https://example.com/image2.jpg',
// ... 更多图片
]
}
}
}
</script>
<style>
.scroll-view {
height: 100vh;
}
.lazy-image {
width: 100%;
height: 400rpx;
margin-bottom: 20rpx;
}
</style>
```
### 示例 4: 图片加载和错误处理
```vue
<template>
<view class="container">
<image
:src="imageUrl"
mode="aspectFit"
@load="handleLoad"
@error="handleError"
:class="{ 'error-image': hasError }"
></image>
<text v-if="hasError" class="error-text">图片加载失败</text>
</view>
</template>
<script>
export default {
data() {
return {
imageUrl: 'https://example.com/image.jpg',
hasError: false
}
},
methods: {
handleLoad(e) {
console.log('图片加载成功', e.detail)
this.hasError = false
},
handleError(e) {
console.error('图片加载失败', e.detail)
this.hasError = true
}
}
}
</script>
<style>
.error-image {
background-color: #f5f5f5;
}
.error-text {
color: #ff3b30;
font-size: 24rpx;
margin-top: 10rpx;
}
</style>
```
### 示例 5: 占位图和加载状态
```vue
<template>
<view class="container">
<view class="image-wrapper">
<image
v-if="!imageLoaded"
src="/static/placeholder.png"
mode="aspectFit"
class="placeholder"
></image>
<image
:src="imageUrl"
mode="aspectFit"
@load="imageLoaded = true"
:class="{ 'hidden': !imageLoaded }"
class="main-image"
></image>
<view v-if="loading" class="loading">加载中...</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
imageUrl: 'https://example.com/image.jpg',
imageLoaded: false,
loading: true
}
},
methods: {
handleLoad() {
this.imageLoaded = true
this.loading = false
}
}
}
</script>
<style>
.image-wrapper {
position: relative;
width: 400rpx;
height: 400rpx;
}
.placeholder {
width: 100%;
height: 100%;
}
.main-image {
width: 100%;
height: 100%;
}
.hidden {
display: none;
}
.loading {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: #999;
}
</style>
```
### 示例 6: 网络图片和本地图片
```vue
<template>
<view class="container">
<!-- 本地图片 -->
<image src="/static/logo.png" mode="aspectFit"></image>
<!-- 网络图片 -->
<image
src="https://example.com/image.jpg"
mode="aspectFit"
></image>
<!-- 动态图片 -->
<image
:src="dynamicImageUrl"
mode="aspectFit"
></image>
</view>
</template>
<script>
export default {
data() {
return {
dynamicImageUrl: 'https://example.com/image.jpg'
}
}
}
</script>
```
## 属性说明
| 属性名 | 类型 | 默认值 | 说明 |
|--------|------|--------|------|
| src | String | - | 图片资源地址 |
| mode | String | scaleToFill | 图片裁剪、缩放的模式 |
| lazy-load | Boolean | false | 图片懒加载 |
| webp | Boolean | false | 是否启用 webp 格式 |
## mode 可选值
| 值 | 说明 |
|----|------|
| scaleToFill | 不保持纵横比缩放图片,使图片的宽高完全拉伸至填满 image 元素 |
| aspectFit | 保持纵横比缩放图片,使图片的长边能完全显示出来 |
| aspectFill | 保持纵横比缩放图片,只保证图片的短边能完全显示出来 |
| widthFix | 宽度不变,高度自动变化,保持原图宽高比不变 |
| heightFix | 高度不变,宽度自动变化,保持原图宽高比不变 |
| top | 不缩放图片,只显示图片的顶部区域 |
| bottom | 不缩放图片,只显示图片的底部区域 |
| center | 不缩放图片,只显示图片的中间区域 |
| left | 不缩放图片,只显示图片的左边区域 |
| right | 不缩放图片,只显示图片的右边区域 |
| top left | 不缩放图片,只显示图片的左上边区域 |
| top right | 不缩放图片,只显示图片的右上边区域 |
| bottom left | 不缩放图片,只显示图片的左下边区域 |
| bottom right | 不缩放图片,只显示图片的右下边区域 |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. 网络图片需要配置合法域名
2. 本地图片路径需要使用 `/static/` 开头
3. `lazy-load` 只对 page 和 scroll-view 下的 image 有效
4. 建议使用合适的 `mode` 值以优化显示效果
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/component/image.html
- **预览图片**: https://uniapp.dcloud.net.cn/api/media/image.html#previewimage
@@ -0,0 +1,331 @@
# input 组件示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/component/input.html
## 概述
`input` 是单行输入框组件,用于用户输入文本。
## 基础用法
```vue
<template>
<input v-model="value" placeholder="请输入内容" />
</template>
<script>
export default {
data() {
return {
value: ''
}
}
}
</script>
```
## 完整示例
### 示例 1: 基本输入框
```vue
<template>
<view class="container">
<input
v-model="inputValue"
placeholder="请输入内容"
@input="handleInput"
/>
<text>输入的内容{{ inputValue }}</text>
</view>
</template>
<script>
export default {
data() {
return {
inputValue: ''
}
},
methods: {
handleInput(e) {
this.inputValue = e.detail.value
}
}
}
</script>
```
### 示例 2: 不同类型的输入框
```vue
<template>
<view class="container">
<input type="text" placeholder="文本输入" />
<input type="number" placeholder="数字输入" />
<input type="digit" placeholder="带小数点的数字" />
<input type="idcard" placeholder="身份证号" />
<input type="tel" placeholder="电话号码" />
<input type="safe-password" placeholder="安全密码" />
<input type="nickname" placeholder="昵称" />
</view>
</template>
```
### 示例 3: 密码输入框
```vue
<template>
<view class="container">
<input
type="text"
password
placeholder="请输入密码"
v-model="password"
/>
<input
type="text"
:password="!showPassword"
placeholder="显示/隐藏密码"
v-model="password2"
/>
<button @click="showPassword = !showPassword">
{{ showPassword ? '隐藏' : '显示' }}密码
</button>
</view>
</template>
<script>
export default {
data() {
return {
password: '',
password2: '',
showPassword: false
}
}
}
</script>
```
### 示例 4: 限制输入长度
```vue
<template>
<view class="container">
<input
v-model="value"
placeholder="最多输入10个字符"
maxlength="10"
@input="handleInput"
/>
<text>已输入{{ value.length }}/10</text>
</view>
</template>
<script>
export default {
data() {
return {
value: ''
}
},
methods: {
handleInput(e) {
this.value = e.detail.value
}
}
}
</script>
```
### 示例 5: 获取焦点
```vue
<template>
<view class="container">
<input
ref="input"
v-model="value"
placeholder="点击按钮获取焦点"
:focus="isFocused"
/>
<button @click="focusInput">获取焦点</button>
<button @click="blurInput">失去焦点</button>
</view>
</template>
<script>
export default {
data() {
return {
value: '',
isFocused: false
}
},
methods: {
focusInput() {
this.isFocused = true
// 或使用组件方法
this.$refs.input.focus()
},
blurInput() {
this.isFocused = false
// 或使用组件方法
this.$refs.input.blur()
}
}
}
</script>
```
### 示例 6: 确认按钮
```vue
<template>
<view class="container">
<input
v-model="value"
placeholder="输入后点击键盘确认"
confirm-type="search"
@confirm="handleConfirm"
/>
</view>
</template>
<script>
export default {
data() {
return {
value: ''
}
},
methods: {
handleConfirm(e) {
console.log('确认输入', e.detail.value)
uni.showToast({
title: '搜索:' + e.detail.value,
icon: 'none'
})
}
}
}
</script>
```
### 示例 7: 表单验证
```vue
<template>
<view class="container">
<input
v-model="email"
type="text"
placeholder="请输入邮箱"
@blur="validateEmail"
/>
<text v-if="emailError" class="error">{{ emailError }}</text>
<input
v-model="phone"
type="tel"
placeholder="请输入手机号"
maxlength="11"
@blur="validatePhone"
/>
<text v-if="phoneError" class="error">{{ phoneError }}</text>
<button @click="submit">提交</button>
</view>
</template>
<script>
export default {
data() {
return {
email: '',
phone: '',
emailError: '',
phoneError: ''
}
},
methods: {
validateEmail() {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
if (this.email && !emailRegex.test(this.email)) {
this.emailError = '邮箱格式不正确'
} else {
this.emailError = ''
}
},
validatePhone() {
const phoneRegex = /^1[3-9]\d{9}$/
if (this.phone && !phoneRegex.test(this.phone)) {
this.phoneError = '手机号格式不正确'
} else {
this.phoneError = ''
}
},
submit() {
this.validateEmail()
this.validatePhone()
if (!this.emailError && !this.phoneError) {
uni.showToast({
title: '提交成功',
icon: 'success'
})
}
}
}
}
</script>
<style>
.error {
color: #ff3b30;
font-size: 24rpx;
margin-top: 10rpx;
}
</style>
```
## 属性说明
| 属性名 | 类型 | 默认值 | 说明 |
|--------|------|--------|------|
| value | String | - | 输入框的初始内容 |
| type | String | text | input 的类型,可选值:text、number、digit、idcard、tel、safe-password、nickname |
| password | Boolean | false | 是否是密码类型 |
| placeholder | String | - | 输入框为空时占位符 |
| disabled | Boolean | false | 是否禁用 |
| maxlength | Number | 140 | 最大输入长度,-1 表示不限制 |
| focus | Boolean | false | 获取焦点 |
| confirm-type | String | done | 设置键盘右下角按钮的文字 |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. `v-model` 是双向绑定的推荐方式
2. `maxlength` 设置为 -1 时不限制最大长度
3. `focus` 属性在 H5 和 App 上需要特殊处理
4. `confirm-type` 在不同平台支持的值可能不同
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/component/input.html
- **表单组件**: https://uniapp.dcloud.net.cn/component/form.html
@@ -0,0 +1,262 @@
# label 组件示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/component/label.html
## 概述
`label` 是标签组件,用于改进表单组件的可用性。
## 基础用法
```vue
<template>
<label>
<checkbox value="option1" />
<text>选项1</text>
</label>
</template>
```
## 完整示例
### 示例 1: 配合 checkbox 使用
```vue
<template>
<view class="container">
<checkbox-group @change="handleChange">
<label class="checkbox-label">
<checkbox value="option1" />
<text>选项1</text>
</label>
<label class="checkbox-label">
<checkbox value="option2" />
<text>选项2</text>
</label>
<label class="checkbox-label">
<checkbox value="option3" />
<text>选项3</text>
</label>
</checkbox-group>
</view>
</template>
<script>
export default {
methods: {
handleChange(e) {
console.log('选中的值', e.detail.value)
}
}
}
</script>
<style>
.checkbox-label {
display: flex;
align-items: center;
padding: 20px;
border-bottom: 1px solid #eee;
}
</style>
```
### 示例 2: 配合 radio 使用
```vue
<template>
<view class="container">
<radio-group @change="handleChange">
<label class="radio-label">
<radio value="male" />
<text></text>
</label>
<label class="radio-label">
<radio value="female" />
<text></text>
</label>
</radio-group>
</view>
</template>
<script>
export default {
methods: {
handleChange(e) {
console.log('选中的值', e.detail.value)
}
}
}
</script>
<style>
.radio-label {
display: flex;
align-items: center;
padding: 20px;
border-bottom: 1px solid #eee;
}
</style>
```
### 示例 3: 配合 switch 使用
```vue
<template>
<view class="container">
<label class="switch-label">
<text>开启通知</text>
<switch :checked="notifyEnabled" @change="handleSwitchChange" />
</label>
</view>
</template>
<script>
export default {
data() {
return {
notifyEnabled: false
}
},
methods: {
handleSwitchChange(e) {
this.notifyEnabled = e.detail.value
}
}
}
</script>
<style>
.switch-label {
display: flex;
justify-content: space-between;
align-items: center;
padding: 20px;
}
</style>
```
### 示例 4: 配合 input 使用
```vue
<template>
<view class="container">
<label class="input-label">
<text>用户名</text>
<input v-model="username" placeholder="请输入用户名" />
</label>
<label class="input-label">
<text>密码</text>
<input v-model="password" type="password" placeholder="请输入密码" />
</label>
</view>
</template>
<script>
export default {
data() {
return {
username: '',
password: ''
}
}
}
</script>
<style>
.input-label {
display: flex;
align-items: center;
padding: 20px;
border-bottom: 1px solid #eee;
}
</style>
```
### 示例 5: 表单列表
```vue
<template>
<view class="container">
<view class="form-list">
<label class="form-item">
<text class="label-text">同意协议</text>
<checkbox value="agree" />
</label>
<label class="form-item">
<text class="label-text">接收通知</text>
<switch :checked="notifyEnabled" @change="notifyEnabled = $event.detail.value" />
</label>
<label class="form-item">
<text class="label-text">性别</text>
<radio-group>
<radio value="male" />
<radio value="female" />
</radio-group>
</label>
</view>
</view>
</template>
<script>
export default {
data() {
return {
notifyEnabled: false
}
}
}
</script>
<style>
.form-list {
padding: 20px;
}
.form-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 20px 0;
border-bottom: 1px solid #eee;
}
.label-text {
font-size: 32rpx;
color: #333;
}
</style>
```
## 属性说明
| 属性名 | 类型 | 默认值 | 说明 |
|--------|------|--------|------|
| for | String | - | 绑定控件的 id |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. `label` 用于改进表单组件的可用性
2. 点击 `label` 内的文本可以触发关联的表单控件
3. 可以配合 `checkbox``radio``switch``input` 等使用
4. 建议使用 `label` 包裹表单控件和文本
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/component/label.html
- **复选框**: https://uniapp.dcloud.net.cn/component/checkbox.html
- **单选框**: https://uniapp.dcloud.net.cn/component/radio.html
@@ -0,0 +1,326 @@
# map 组件示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/component/map.html
## 概述
`map` 是地图组件,用于显示地图和标记位置。
## 基础用法
```vue
<template>
<map
:latitude="latitude"
:longitude="longitude"
:markers="markers"
></map>
</template>
<script>
export default {
data() {
return {
latitude: 39.908823,
longitude: 116.397470,
markers: [{
id: 1,
latitude: 39.908823,
longitude: 116.397470,
title: '天安门'
}]
}
}
}
</script>
```
## 完整示例
### 示例 1: 基本地图
```vue
<template>
<view class="container">
<map
:latitude="latitude"
:longitude="longitude"
:scale="scale"
class="map"
></map>
</view>
</template>
<script>
export default {
data() {
return {
latitude: 39.908823,
longitude: 116.397470,
scale: 16
}
}
}
</script>
<style>
.map {
width: 100%;
height: 500px;
}
</style>
```
### 示例 2: 地图标记
```vue
<template>
<view class="container">
<map
:latitude="latitude"
:longitude="longitude"
:markers="markers"
:show-location="true"
class="map"
@markertap="handleMarkerTap"
></map>
</view>
</template>
<script>
export default {
data() {
return {
latitude: 39.908823,
longitude: 116.397470,
markers: [
{
id: 1,
latitude: 39.908823,
longitude: 116.397470,
title: '天安门',
iconPath: '/static/marker.png',
width: 30,
height: 30
},
{
id: 2,
latitude: 39.918823,
longitude: 116.407470,
title: '故宫',
iconPath: '/static/marker.png',
width: 30,
height: 30
}
]
}
},
methods: {
handleMarkerTap(e) {
const markerId = e.detail.markerId
const marker = this.markers.find(m => m.id === markerId)
if (marker) {
uni.showToast({
title: marker.title,
icon: 'none'
})
}
}
}
}
</script>
```
### 示例 3: 显示当前位置
```vue
<template>
<view class="container">
<map
:latitude="latitude"
:longitude="longitude"
:show-location="true"
:enable-zoom="true"
class="map"
></map>
<button @click="getCurrentLocation">获取当前位置</button>
</view>
</template>
<script>
export default {
data() {
return {
latitude: 39.908823,
longitude: 116.397470
}
},
onLoad() {
this.getCurrentLocation()
},
methods: {
getCurrentLocation() {
uni.getLocation({
type: 'gcj02',
success: (res) => {
this.latitude = res.latitude
this.longitude = res.longitude
},
fail: () => {
uni.showToast({
title: '获取位置失败',
icon: 'none'
})
}
})
}
}
}
</script>
```
### 示例 4: 地图控件
```vue
<template>
<view class="container">
<map
:latitude="latitude"
:longitude="longitude"
:controls="controls"
:show-location="true"
class="map"
@controltap="handleControlTap"
></map>
</view>
</template>
<script>
export default {
data() {
return {
latitude: 39.908823,
longitude: 116.397470,
controls: [
{
id: 1,
iconPath: '/static/location.png',
position: {
left: 10,
top: 10,
width: 30,
height: 30
},
clickable: true
}
]
}
},
methods: {
handleControlTap(e) {
const controlId = e.detail.controlId
if (controlId === 1) {
this.getCurrentLocation()
}
},
getCurrentLocation() {
uni.getLocation({
type: 'gcj02',
success: (res) => {
this.latitude = res.latitude
this.longitude = res.longitude
}
})
}
}
}
</script>
```
### 示例 5: 地图事件
```vue
<template>
<view class="container">
<map
:latitude="latitude"
:longitude="longitude"
:markers="markers"
class="map"
@tap="handleMapTap"
@regionchange="handleRegionChange"
@updated="handleMapUpdated"
></map>
</view>
</template>
<script>
export default {
data() {
return {
latitude: 39.908823,
longitude: 116.397470,
markers: []
}
},
methods: {
handleMapTap(e) {
console.log('地图点击', e.detail)
// 添加标记
const newMarker = {
id: Date.now(),
latitude: e.detail.latitude,
longitude: e.detail.longitude,
title: '新位置'
}
this.markers.push(newMarker)
},
handleRegionChange(e) {
console.log('地图区域变化', e.detail)
},
handleMapUpdated() {
console.log('地图更新完成')
}
}
}
</script>
```
## 属性说明
| 属性名 | 类型 | 默认值 | 说明 |
|--------|------|--------|------|
| latitude | Number | - | 中心纬度 |
| longitude | Number | - | 中心经度 |
| scale | Number | 16 | 缩放级别,取值范围为 5-18 |
| markers | Array | [] | 标记点 |
| show-location | Boolean | false | 显示带有方向的当前定位点 |
| controls | Array | [] | 控件 |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. 需要使用 `gcj02` 类型的坐标
2. `markers` 数组中的每个标记需要唯一 `id`
3. `show-location` 可以显示当前位置
4. 可以通过事件监听地图交互
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/component/map.html
- **获取位置**: https://uniapp.dcloud.net.cn/api/location/location.html#getlocation
@@ -0,0 +1,204 @@
# navigator 组件示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/component/navigator.html
## 概述
`navigator` 是页面链接组件,用于页面跳转。
## 基础用法
```vue
<template>
<navigator url="/pages/detail/detail">跳转到详情页</navigator>
</template>
```
## 完整示例
### 示例 1: 基本跳转
```vue
<template>
<view class="container">
<navigator url="/pages/detail/detail">跳转到详情页</navigator>
</view>
</template>
```
### 示例 2: 带参数跳转
```vue
<template>
<view class="container">
<navigator url="/pages/detail/detail?id=123&name=test">
跳转到详情页
</navigator>
</view>
</template>
```
### 示例 3: 不同跳转方式
```vue
<template>
<view class="container">
<!-- 保留当前页面可以返回 -->
<navigator url="/pages/detail/detail" open-type="navigate">
保留页面跳转
</navigator>
<!-- 关闭当前页面不能返回 -->
<navigator url="/pages/detail/detail" open-type="redirect">
关闭页面跳转
</navigator>
<!-- 关闭所有页面重新启动 -->
<navigator url="/pages/index/index" open-type="reLaunch">
重新启动
</navigator>
<!-- 跳转到 tabBar 页面 -->
<navigator url="/pages/index/index" open-type="switchTab">
切换到首页
</navigator>
<!-- 返回上一页 -->
<navigator open-type="navigateBack" :delta="1">
返回上一页
</navigator>
</view>
</template>
```
### 示例 4: 列表跳转
```vue
<template>
<view class="container">
<view
v-for="item in list"
:key="item.id"
class="list-item"
>
<navigator :url="`/pages/detail/detail?id=${item.id}`">
<text>{{ item.title }}</text>
<text class="arrow">></text>
</navigator>
</view>
</view>
</template>
<script>
export default {
data() {
return {
list: [
{ id: 1, title: '项目1' },
{ id: 2, title: '项目2' },
{ id: 3, title: '项目3' }
]
}
}
}
</script>
<style>
.list-item {
padding: 20px;
border-bottom: 1px solid #eee;
}
.arrow {
float: right;
color: #999;
}
</style>
```
### 示例 5: 条件跳转
```vue
<template>
<view class="container">
<navigator
v-if="isLogin"
url="/pages/user/user"
open-type="navigate"
>
个人中心
</navigator>
<navigator
v-else
url="/pages/login/login"
open-type="navigate"
>
登录
</navigator>
</view>
</template>
<script>
export default {
data() {
return {
isLogin: false
}
},
onLoad() {
this.checkLogin()
},
methods: {
checkLogin() {
const token = uni.getStorageSync('token')
this.isLogin = !!token
}
}
}
</script>
```
## 属性说明
| 属性名 | 类型 | 默认值 | 说明 |
|--------|------|--------|------|
| url | String | - | 应用内的跳转链接 |
| open-type | String | navigate | 跳转方式,可选值:navigate、redirect、switchTab、reLaunch、navigateBack |
| delta | Number | 1 | 当 open-type 为 navigateBack 时有效,表示返回的页面数 |
## open-type 可选值
| 值 | 说明 |
|----|------|
| navigate | 保留当前页面,跳转到应用内的某个页面 |
| redirect | 关闭当前页面,跳转到应用内的某个页面 |
| switchTab | 跳转到 tabBar 页面 |
| reLaunch | 关闭所有页面,打开到应用内的某个页面 |
| navigateBack | 关闭当前页面,返回上一页面或多级页面 |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. `url` 必须以 `/` 开头
2. `open-type``switchTab` 时,只能跳转到 tabBar 页面
3. `open-type``navigateBack` 时,不需要 `url` 参数
4. 可以通过 `delta` 控制返回的页面数
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/component/navigator.html
- **页面路由**: https://uniapp.dcloud.net.cn/api/router.html
@@ -0,0 +1,290 @@
# picker 组件示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/component/picker.html
## 概述
`picker` 是滚动选择器组件,支持普通选择器、多列选择器、时间选择器、日期选择器等。
## 基础用法
```vue
<template>
<picker mode="selector" :range="options" @change="handleChange">
<view>请选择</view>
</picker>
</template>
<script>
export default {
data() {
return {
options: ['选项1', '选项2', '选项3']
}
},
methods: {
handleChange(e) {
console.log('选中的索引', e.detail.value)
}
}
}
</script>
```
## 完整示例
### 示例 1: 普通选择器
```vue
<template>
<view class="container">
<picker
mode="selector"
:range="options"
:value="selectedIndex"
@change="handleChange"
>
<view class="picker-view">
<text>{{ selectedText || '请选择' }}</text>
<text class="arrow">></text>
</view>
</picker>
</view>
</template>
<script>
export default {
data() {
return {
options: ['选项1', '选项2', '选项3', '选项4'],
selectedIndex: 0,
selectedText: ''
}
},
methods: {
handleChange(e) {
this.selectedIndex = e.detail.value
this.selectedText = this.options[e.detail.value]
console.log('选中的值', this.selectedText)
}
}
}
</script>
<style>
.picker-view {
display: flex;
justify-content: space-between;
align-items: center;
padding: 20px;
border-bottom: 1px solid #eee;
}
.arrow {
color: #999;
}
</style>
```
### 示例 2: 多列选择器
```vue
<template>
<view class="container">
<picker
mode="multiSelector"
:range="multiArray"
:value="multiIndex"
@change="handleMultiChange"
@columnchange="handleColumnChange"
>
<view class="picker-view">
<text>{{ displayText || '请选择省市区' }}</text>
<text class="arrow">></text>
</view>
</picker>
</view>
</template>
<script>
export default {
data() {
return {
multiArray: [
['北京', '上海', '广东'],
['朝阳区', '海淀区', '丰台区'],
['街道1', '街道2', '街道3']
],
multiIndex: [0, 0, 0],
displayText: ''
}
},
methods: {
handleMultiChange(e) {
this.multiIndex = e.detail.value
this.updateDisplayText()
},
handleColumnChange(e) {
// 当某一列改变时,可以更新其他列的数据
const column = e.detail.column
const row = e.detail.value
this.multiIndex[column] = row
this.updateDisplayText()
},
updateDisplayText() {
this.displayText = this.multiArray.map((arr, index) => {
return arr[this.multiIndex[index]]
}).join(' ')
}
}
}
</script>
```
### 示例 3: 时间选择器
```vue
<template>
<view class="container">
<picker
mode="time"
:value="time"
@change="handleTimeChange"
>
<view class="picker-view">
<text>{{ time || '请选择时间' }}</text>
<text class="arrow">></text>
</view>
</picker>
</view>
</template>
<script>
export default {
data() {
return {
time: ''
}
},
methods: {
handleTimeChange(e) {
this.time = e.detail.value
console.log('选择的时间', this.time)
}
}
}
</script>
```
### 示例 4: 日期选择器
```vue
<template>
<view class="container">
<picker
mode="date"
:value="date"
:start="startDate"
:end="endDate"
@change="handleDateChange"
>
<view class="picker-view">
<text>{{ date || '请选择日期' }}</text>
<text class="arrow">></text>
</view>
</picker>
</view>
</template>
<script>
export default {
data() {
return {
date: '',
startDate: '2020-01-01',
endDate: '2030-12-31'
}
},
methods: {
handleDateChange(e) {
this.date = e.detail.value
console.log('选择的日期', this.date)
}
}
}
</script>
```
### 示例 5: 地区选择器
```vue
<template>
<view class="container">
<picker
mode="region"
:value="region"
@change="handleRegionChange"
>
<view class="picker-view">
<text>{{ regionText || '请选择地区' }}</text>
<text class="arrow">></text>
</view>
</picker>
</view>
</template>
<script>
export default {
data() {
return {
region: [],
regionText: ''
}
},
methods: {
handleRegionChange(e) {
this.region = e.detail.value
this.regionText = e.detail.value.join(' ')
console.log('选择的地区', this.region)
}
}
}
</script>
```
## 属性说明
| 属性名 | 类型 | 默认值 | 说明 |
|--------|------|--------|------|
| mode | String | selector | 选择器类型,可选值:selector、multiSelector、time、date、region |
| range | Array | [] | mode 为 selector 或 multiSelector 时,range 有效 |
| value | Number/Array | 0 | 表示选择了 range 中的第几个(下标从 0 开始) |
| start | String | - | 有效值范围的开始,字符串格式为 "YYYY-MM-DD" |
| end | String | - | 有效值范围的结束,字符串格式为 "YYYY-MM-DD" |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. `mode` 不同,`range``value` 的格式也不同
2. 时间选择器的 `value` 格式为 "HH:mm"
3. 日期选择器的 `value` 格式为 "YYYY-MM-DD"
4. 多列选择器需要配合 `@columnchange` 事件处理联动
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/component/picker.html
- **滚动选择器**: https://uniapp.dcloud.net.cn/component/picker-view.html
@@ -0,0 +1,209 @@
# progress 组件示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/component/progress.html
## 概述
`progress` 是进度条组件,用于显示任务进度。
## 基础用法
```vue
<template>
<progress :percent="50"></progress>
</template>
```
## 完整示例
### 示例 1: 基本进度条
```vue
<template>
<view class="container">
<progress :percent="progress" />
<text>{{ progress }}%</text>
</view>
</template>
<script>
export default {
data() {
return {
progress: 50
}
}
}
</script>
```
### 示例 2: 显示进度百分比
```vue
<template>
<view class="container">
<progress :percent="progress" :show-info="true" />
<button @click="increaseProgress">增加进度</button>
</view>
</template>
<script>
export default {
data() {
return {
progress: 0
}
},
methods: {
increaseProgress() {
if (this.progress < 100) {
this.progress += 10
}
}
}
}
</script>
```
### 示例 3: 不同颜色
```vue
<template>
<view class="container">
<progress :percent="50" color="#007aff" />
<progress :percent="60" color="#4cd964" />
<progress :percent="70" color="#ff3b30" />
</view>
</template>
```
### 示例 4: 文件上传进度
```vue
<template>
<view class="container">
<progress :percent="uploadProgress" :show-info="true" />
<button @click="uploadFile">上传文件</button>
</view>
</template>
<script>
export default {
data() {
return {
uploadProgress: 0
}
},
methods: {
uploadFile() {
uni.chooseImage({
count: 1,
success: (res) => {
const tempFilePath = res.tempFilePaths[0]
this.uploadProgress = 0
// 模拟上传进度
const interval = setInterval(() => {
this.uploadProgress += 10
if (this.uploadProgress >= 100) {
clearInterval(interval)
uni.showToast({
title: '上传完成',
icon: 'success'
})
}
}, 200)
// 实际上传
uni.uploadFile({
url: 'https://api.example.com/upload',
filePath: tempFilePath,
name: 'file',
success: () => {
clearInterval(interval)
this.uploadProgress = 100
}
})
}
})
}
}
}
</script>
```
### 示例 5: 动画进度条
```vue
<template>
<view class="container">
<progress
:percent="progress"
:active="true"
:active-color="activeColor"
/>
<button @click="startProgress">开始进度</button>
</view>
</template>
<script>
export default {
data() {
return {
progress: 0,
activeColor: '#007aff'
}
},
methods: {
startProgress() {
this.progress = 0
const interval = setInterval(() => {
this.progress += 2
if (this.progress >= 100) {
clearInterval(interval)
this.activeColor = '#4cd964'
}
}, 100)
}
}
}
</script>
```
## 属性说明
| 属性名 | 类型 | 默认值 | 说明 |
|--------|------|--------|------|
| percent | Number | 0 | 百分比 0~100 |
| show-info | Boolean | false | 在进度条右侧显示百分比 |
| stroke-width | Number | 6 | 进度条线的宽度,单位 px |
| active | Boolean | false | 进度条是否显示动画 |
| active-color | String | #007aff | 已选择的进度条的颜色 |
| backgroundColor | String | #ebebeb | 未选择的进度条的颜色 |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. `percent` 值范围是 0-100
2. `show-info` 可以在右侧显示百分比文字
3. `active` 可以启用动画效果
4. 可以通过 `active-color` 自定义颜色
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/component/progress.html
@@ -0,0 +1,172 @@
# radio 组件示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/component/radio.html
## 概述
`radio` 是单项选择器组件,用于单选场景。
## 基础用法
```vue
<template>
<radio value="option1" checked>选项1</radio>
</template>
```
## 完整示例
### 示例 1: 单个单选框
```vue
<template>
<view class="container">
<radio value="male" :checked="gender === 'male'" @tap="handleChange">
</radio>
<radio value="female" :checked="gender === 'female'" @tap="handleChange">
</radio>
</view>
</template>
<script>
export default {
data() {
return {
gender: 'male'
}
},
methods: {
handleChange(e) {
this.gender = e.detail.value
console.log('选择的性别', this.gender)
}
}
}
</script>
```
### 示例 2: 单选框组
```vue
<template>
<view class="container">
<radio-group @change="handleGroupChange">
<label v-for="item in options" :key="item.value" class="radio-item">
<radio :value="item.value" :checked="selectedValue === item.value" />
<text>{{ item.label }}</text>
</label>
</radio-group>
<text>已选择{{ selectedValue }}</text>
</view>
</template>
<script>
export default {
data() {
return {
options: [
{ value: 'option1', label: '选项1' },
{ value: 'option2', label: '选项2' },
{ value: 'option3', label: '选项3' }
],
selectedValue: 'option1'
}
},
methods: {
handleGroupChange(e) {
this.selectedValue = e.detail.value
console.log('选中的值', this.selectedValue)
}
}
}
</script>
<style>
.radio-item {
display: flex;
align-items: center;
padding: 10px;
}
</style>
```
### 示例 3: 在表单中使用
```vue
<template>
<form @submit="handleSubmit">
<view class="form-item">
<text>支付方式</text>
<radio-group name="payment" @change="handlePaymentChange">
<label v-for="method in paymentMethods" :key="method.value" class="radio-item">
<radio :value="method.value" />
<text>{{ method.label }}</text>
</label>
</radio-group>
</view>
<button form-type="submit">提交</button>
</form>
</template>
<script>
export default {
data() {
return {
paymentMethods: [
{ value: 'alipay', label: '支付宝' },
{ value: 'wechat', label: '微信支付' },
{ value: 'bank', label: '银行卡' }
],
selectedPayment: ''
}
},
methods: {
handlePaymentChange(e) {
this.selectedPayment = e.detail.value
},
handleSubmit(e) {
console.log('选择的支付方式', this.selectedPayment)
}
}
}
</script>
```
## 属性说明
| 属性名 | 类型 | 默认值 | 说明 |
|--------|------|--------|------|
| value | String | - | radio 标识,选中时触发 change 事件,并携带 value |
| checked | Boolean | false | 当前是否选中 |
| disabled | Boolean | false | 是否禁用 |
| color | String | #007aff | radio 的颜色 |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. 需要配合 `radio-group` 使用才能获取选中的值
2. 同一组内只能选择一个选项
3. `value` 用于标识不同的选项
4. `checked` 属性控制选中状态
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/component/radio.html
- **表单组件**: https://uniapp.dcloud.net.cn/component/form.html
@@ -0,0 +1,247 @@
# rich-text 组件示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/component/rich-text.html
## 概述
`rich-text` 是富文本组件,用于显示富文本内容。
## 基础用法
```vue
<template>
<rich-text :nodes="htmlContent"></rich-text>
</template>
<script>
export default {
data() {
return {
htmlContent: '<div>这是富文本内容</div>'
}
}
}
</script>
```
## 完整示例
### 示例 1: 显示 HTML 内容
```vue
<template>
<view class="container">
<rich-text :nodes="htmlContent"></rich-text>
</view>
</template>
<script>
export default {
data() {
return {
htmlContent: `
<div>
<h1>标题</h1>
<p>这是一段<strong>加粗</strong>的文字</p>
<p>这是一段<em>斜体</em>的文字</p>
<ul>
<li>列表项1</li>
<li>列表项2</li>
</ul>
</div>
`
}
}
}
</script>
```
### 示例 2: 显示网络 HTML
```vue
<template>
<view class="container">
<rich-text :nodes="htmlContent"></rich-text>
</view>
</template>
<script>
export default {
data() {
return {
htmlContent: ''
}
},
onLoad() {
this.loadHtmlContent()
},
methods: {
loadHtmlContent() {
uni.request({
url: 'https://api.example.com/article',
success: (res) => {
this.htmlContent = res.data.content
}
})
}
}
}
</script>
```
### 示例 3: 使用对象数组
```vue
<template>
<view class="container">
<rich-text :nodes="nodes"></rich-text>
</view>
</template>
<script>
export default {
data() {
return {
nodes: [
{
name: 'div',
attrs: {
class: 'wrapper',
style: 'color: red;'
},
children: [
{
type: 'text',
text: 'Hello World!'
}
]
}
]
}
}
}
</script>
```
### 示例 4: 混合使用
```vue
<template>
<view class="container">
<rich-text :nodes="mixedContent"></rich-text>
</view>
</template>
<script>
export default {
data() {
return {
mixedContent: [
'<p>这是HTML字符串</p>',
{
name: 'div',
attrs: {
style: 'color: blue;'
},
children: [
{
type: 'text',
text: '这是对象节点'
}
]
}
]
}
}
}
</script>
```
### 示例 5: 文章详情页
```vue
<template>
<view class="container">
<view class="article-header">
<text class="title">{{ article.title }}</text>
<text class="date">{{ article.date }}</text>
</view>
<rich-text :nodes="article.content" class="article-content"></rich-text>
</view>
</template>
<script>
export default {
data() {
return {
article: {
title: '文章标题',
date: '2024-01-01',
content: `
<div>
<h2>第一章</h2>
<p>这是文章的第一段内容...</p>
<img src="https://example.com/image.jpg" />
<h2>第二章</h2>
<p>这是文章的第二段内容...</p>
</div>
`
}
}
}
}
</script>
<style>
.article-header {
padding: 20px;
border-bottom: 1px solid #eee;
}
.title {
font-size: 36rpx;
font-weight: bold;
display: block;
margin-bottom: 10px;
}
.date {
font-size: 24rpx;
color: #999;
}
.article-content {
padding: 20px;
}
</style>
```
## 属性说明
| 属性名 | 类型 | 默认值 | 说明 |
|--------|------|--------|------|
| nodes | String/Array | - | 节点列表/HTML String |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. `nodes` 可以是 HTML 字符串或对象数组
2. 不同平台支持的 HTML 标签可能不同
3. 建议使用对象数组格式以获得更好的兼容性
4. 图片需要配置合法域名
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/component/rich-text.html
@@ -0,0 +1,337 @@
# scroll-view 组件示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/component/scroll-view.html
## 概述
`scroll-view` 是可滚动视图容器组件,用于实现可滚动的区域。
## 基础用法
```vue
<template>
<scroll-view scroll-y class="scroll-view">
<view v-for="item in list" :key="item.id">{{ item.name }}</view>
</scroll-view>
</template>
<script>
export default {
data() {
return {
list: [
{ id: 1, name: '项目1' },
{ id: 2, name: '项目2' }
]
}
}
}
</script>
<style>
.scroll-view {
height: 400px;
}
</style>
```
## 完整示例
### 示例 1: 垂直滚动
```vue
<template>
<scroll-view
scroll-y
class="scroll-view"
@scroll="handleScroll"
>
<view
v-for="item in list"
:key="item.id"
class="list-item"
>
{{ item.name }}
</view>
</scroll-view>
</template>
<script>
export default {
data() {
return {
list: Array.from({ length: 50 }, (_, i) => ({
id: i + 1,
name: `项目 ${i + 1}`
}))
}
},
methods: {
handleScroll(e) {
console.log('滚动位置', e.detail.scrollTop)
}
}
}
</script>
<style>
.scroll-view {
height: 500px;
}
.list-item {
padding: 20px;
border-bottom: 1px solid #eee;
}
</style>
```
### 示例 2: 水平滚动
```vue
<template>
<scroll-view
scroll-x
class="scroll-view-horizontal"
show-scrollbar
>
<view
v-for="item in list"
:key="item.id"
class="horizontal-item"
>
{{ item.name }}
</view>
</scroll-view>
</template>
<script>
export default {
data() {
return {
list: Array.from({ length: 20 }, (_, i) => ({
id: i + 1,
name: `项目 ${i + 1}`
}))
}
}
}
</script>
<style>
.scroll-view-horizontal {
white-space: nowrap;
width: 100%;
}
.horizontal-item {
display: inline-block;
width: 200px;
padding: 20px;
margin-right: 10px;
background-color: #f5f5f5;
border-radius: 8px;
}
</style>
```
### 示例 3: 下拉刷新
```vue
<template>
<scroll-view
scroll-y
class="scroll-view"
refresher-enabled
:refresher-triggered="refreshing"
@refresherrefresh="onRefresh"
@refresherrestore="onRestore"
>
<view
v-for="item in list"
:key="item.id"
class="list-item"
>
{{ item.name }}
</view>
</scroll-view>
</template>
<script>
export default {
data() {
return {
refreshing: false,
list: Array.from({ length: 20 }, (_, i) => ({
id: i + 1,
name: `项目 ${i + 1}`
}))
}
},
methods: {
onRefresh() {
this.refreshing = true
// 模拟刷新
setTimeout(() => {
this.list = Array.from({ length: 20 }, (_, i) => ({
id: i + 1,
name: `新项目 ${i + 1}`
}))
this.refreshing = false
uni.showToast({
title: '刷新成功',
icon: 'success'
})
}, 2000)
},
onRestore() {
console.log('刷新恢复')
}
}
}
</script>
```
### 示例 4: 上拉加载
```vue
<template>
<scroll-view
scroll-y
class="scroll-view"
@scrolltolower="loadMore"
lower-threshold="50"
>
<view
v-for="item in list"
:key="item.id"
class="list-item"
>
{{ item.name }}
</view>
<view v-if="loading" class="loading">加载中...</view>
</scroll-view>
</template>
<script>
export default {
data() {
return {
loading: false,
page: 1,
list: Array.from({ length: 20 }, (_, i) => ({
id: i + 1,
name: `项目 ${i + 1}`
}))
}
},
methods: {
loadMore() {
if (this.loading) return
this.loading = true
// 模拟加载
setTimeout(() => {
const newList = Array.from({ length: 20 }, (_, i) => ({
id: this.list.length + i + 1,
name: `项目 ${this.list.length + i + 1}`
}))
this.list = [...this.list, ...newList]
this.page++
this.loading = false
}, 1000)
}
}
}
</script>
```
### 示例 5: 滚动到指定位置
```vue
<template>
<view class="container">
<button @click="scrollToTop">滚动到顶部</button>
<button @click="scrollToBottom">滚动到底部</button>
<button @click="scrollToIndex(10)">滚动到第10项</button>
<scroll-view
scroll-y
class="scroll-view"
:scroll-top="scrollTop"
scroll-with-animation
>
<view
v-for="(item, index) in list"
:key="item.id"
:id="`item-${index}`"
class="list-item"
>
{{ item.name }}
</view>
</scroll-view>
</view>
</template>
<script>
export default {
data() {
return {
scrollTop: 0,
list: Array.from({ length: 50 }, (_, i) => ({
id: i + 1,
name: `项目 ${i + 1}`
}))
}
},
methods: {
scrollToTop() {
this.scrollTop = 0
},
scrollToBottom() {
this.scrollTop = 9999
},
scrollToIndex(index) {
// 假设每项高度为 60px
this.scrollTop = index * 60
}
}
}
</script>
```
## 属性说明
| 属性名 | 类型 | 默认值 | 说明 |
|--------|------|--------|------|
| scroll-x | Boolean | false | 允许横向滚动 |
| scroll-y | Boolean | false | 允许纵向滚动 |
| scroll-top | Number | - | 设置竖向滚动条位置 |
| scroll-left | Number | - | 设置横向滚动条位置 |
| refresher-enabled | Boolean | false | 开启自定义下拉刷新 |
| refresher-triggered | Boolean | false | 设置当前下拉刷新状态 |
| lower-threshold | Number | 50 | 距底部/右边多远时触发 scrolltolower 事件 |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. 使用 `scroll-y` 时必须设置固定高度
2. 使用 `scroll-x` 时内容需要设置 `white-space: nowrap`
3. 下拉刷新需要设置 `refresher-enabled``refresher-triggered`
4. 上拉加载通过 `@scrolltolower` 事件实现
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/component/scroll-view.html
@@ -0,0 +1,262 @@
# slider 组件示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/component/slider.html
## 概述
`slider` 是滑动选择器组件,用于选择数值。
## 基础用法
```vue
<template>
<slider :value="50" @change="handleChange" />
</template>
<script>
export default {
methods: {
handleChange(e) {
console.log('当前值', e.detail.value)
}
}
}
</script>
```
## 完整示例
### 示例 1: 基本滑动条
```vue
<template>
<view class="container">
<slider :value="value" @change="handleChange" />
<text>当前值{{ value }}</text>
</view>
</template>
<script>
export default {
data() {
return {
value: 50
}
},
methods: {
handleChange(e) {
this.value = e.detail.value
}
}
}
</script>
```
### 示例 2: 设置范围
```vue
<template>
<view class="container">
<slider
:value="value"
min="0"
max="100"
step="5"
@change="handleChange"
/>
<text>当前值{{ value }}</text>
</view>
</template>
<script>
export default {
data() {
return {
value: 50
}
},
methods: {
handleChange(e) {
this.value = e.detail.value
}
}
}
</script>
```
### 示例 3: 音量控制
```vue
<template>
<view class="container">
<view class="volume-control">
<text>音量{{ volume }}%</text>
<slider
:value="volume"
min="0"
max="100"
activeColor="#007aff"
backgroundColor="#ebebeb"
block-color="#007aff"
@change="handleVolumeChange"
/>
</view>
</view>
</template>
<script>
export default {
data() {
return {
volume: 50
}
},
methods: {
handleVolumeChange(e) {
this.volume = e.detail.value
// 可以在这里控制实际音量
console.log('音量设置为', this.volume)
}
}
}
</script>
<style>
.volume-control {
padding: 20px;
}
</style>
```
### 示例 4: 亮度控制
```vue
<template>
<view class="container">
<view class="brightness-control">
<text>亮度{{ brightness }}%</text>
<slider
:value="brightness"
min="0"
max="100"
@change="handleBrightnessChange"
/>
</view>
</view>
</template>
<script>
export default {
data() {
return {
brightness: 50
}
},
methods: {
handleBrightnessChange(e) {
this.brightness = e.detail.value
// 设置屏幕亮度
uni.setScreenBrightness({
value: this.brightness / 100,
success: () => {
console.log('亮度已设置')
}
})
}
}
}
</script>
```
### 示例 5: 价格区间选择
```vue
<template>
<view class="container">
<view class="price-range">
<text>价格区间{{ minPrice }} - {{ maxPrice }}</text>
<slider
:value="minPrice"
min="0"
max="1000"
step="10"
@change="handleMinPriceChange"
/>
<text>最低价格{{ minPrice }}</text>
<slider
:value="maxPrice"
min="0"
max="1000"
step="10"
@change="handleMaxPriceChange"
/>
<text>最高价格{{ maxPrice }}</text>
</view>
</view>
</template>
<script>
export default {
data() {
return {
minPrice: 0,
maxPrice: 1000
}
},
methods: {
handleMinPriceChange(e) {
const value = e.detail.value
if (value <= this.maxPrice) {
this.minPrice = value
}
},
handleMaxPriceChange(e) {
const value = e.detail.value
if (value >= this.minPrice) {
this.maxPrice = value
}
}
}
}
</script>
```
## 属性说明
| 属性名 | 类型 | 默认值 | 说明 |
|--------|------|--------|------|
| min | Number | 0 | 最小值 |
| max | Number | 100 | 最大值 |
| step | Number | 1 | 步长,取值必须大于 0,并且可被(max - min)整除 |
| value | Number | 0 | 当前值 |
| activeColor | String | #007aff | 已选择的颜色 |
| backgroundColor | String | #ebebeb | 背景条的颜色 |
| block-size | Number | 28 | 滑块的大小,取值范围为 12 - 28 |
| block-color | String | #ffffff | 滑块的颜色 |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. `value` 必须在 `min``max` 之间
2. `step` 必须能被 `(max - min)` 整除
3. 可以通过 `@change` 事件监听值的变化
4. 适合用于音量、亮度、价格区间等场景
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/component/slider.html
@@ -0,0 +1,294 @@
# swiper 组件示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/component/swiper.html
## 概述
`swiper` 是滑块视图容器组件,常用于轮播图。
## 基础用法
```vue
<template>
<swiper class="swiper">
<swiper-item>
<view class="swiper-item">1</view>
</swiper-item>
<swiper-item>
<view class="swiper-item">2</view>
</swiper-item>
<swiper-item>
<view class="swiper-item">3</view>
</swiper-item>
</swiper>
</template>
<style>
.swiper {
height: 400px;
}
.swiper-item {
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
</style>
```
## 完整示例
### 示例 1: 基础轮播图
```vue
<template>
<swiper
class="swiper"
:indicator-dots="true"
:autoplay="true"
:interval="3000"
:duration="500"
>
<swiper-item v-for="(item, index) in bannerList" :key="index">
<image
:src="item.image"
mode="aspectFill"
class="swiper-image"
></image>
</swiper-item>
</swiper>
</template>
<script>
export default {
data() {
return {
bannerList: [
{ image: 'https://example.com/banner1.jpg' },
{ image: 'https://example.com/banner2.jpg' },
{ image: 'https://example.com/banner3.jpg' }
]
}
}
}
</script>
<style>
.swiper {
height: 400px;
}
.swiper-image {
width: 100%;
height: 100%;
}
</style>
```
### 示例 2: 自定义指示点
```vue
<template>
<swiper
class="swiper"
:indicator-dots="true"
indicator-color="rgba(0, 0, 0, 0.3)"
indicator-active-color="#007aff"
>
<swiper-item v-for="(item, index) in list" :key="index">
<view class="swiper-item">{{ item }}</view>
</swiper-item>
</swiper>
</template>
<script>
export default {
data() {
return {
list: ['页面1', '页面2', '页面3']
}
}
}
</script>
```
### 示例 3: 垂直滑动
```vue
<template>
<swiper
class="swiper-vertical"
:vertical="true"
:indicator-dots="true"
>
<swiper-item v-for="(item, index) in list" :key="index">
<view class="swiper-item">{{ item }}</view>
</swiper-item>
</swiper>
</template>
<script>
export default {
data() {
return {
list: ['页面1', '页面2', '页面3']
}
}
}
</script>
<style>
.swiper-vertical {
height: 500px;
}
</style>
```
### 示例 4: 切换事件
```vue
<template>
<view class="container">
<swiper
class="swiper"
:current="current"
@change="handleChange"
>
<swiper-item v-for="(item, index) in list" :key="index">
<view class="swiper-item">{{ item }}</view>
</swiper-item>
</swiper>
<text>当前页{{ current + 1 }} / {{ list.length }}</text>
</view>
</template>
<script>
export default {
data() {
return {
current: 0,
list: ['页面1', '页面2', '页面3']
}
},
methods: {
handleChange(e) {
this.current = e.detail.current
console.log('切换到', this.current + 1, '页')
}
}
}
</script>
```
### 示例 5: 图片轮播
```vue
<template>
<swiper
class="swiper"
:indicator-dots="true"
:autoplay="true"
:interval="3000"
:circular="true"
@change="handleChange"
>
<swiper-item
v-for="(item, index) in imageList"
:key="index"
@click="handleImageClick(item)"
>
<image
:src="item.url"
mode="aspectFill"
class="swiper-image"
></image>
<view class="image-title">{{ item.title }}</view>
</swiper-item>
</swiper>
</template>
<script>
export default {
data() {
return {
imageList: [
{ url: 'https://example.com/image1.jpg', title: '标题1' },
{ url: 'https://example.com/image2.jpg', title: '标题2' },
{ url: 'https://example.com/image3.jpg', title: '标题3' }
]
}
},
methods: {
handleChange(e) {
console.log('切换到', e.detail.current)
},
handleImageClick(item) {
uni.previewImage({
urls: this.imageList.map(img => img.url),
current: item.url
})
}
}
}
</script>
<style>
.swiper {
height: 400px;
position: relative;
}
.swiper-image {
width: 100%;
height: 100%;
}
.image-title {
position: absolute;
bottom: 0;
left: 0;
right: 0;
background: linear-gradient(transparent, rgba(0,0,0,0.5));
color: white;
padding: 20px;
}
</style>
```
## 属性说明
| 属性名 | 类型 | 默认值 | 说明 |
|--------|------|--------|------|
| indicator-dots | Boolean | false | 是否显示面板指示点 |
| indicator-color | String | rgba(0, 0, 0, 0.3) | 指示点颜色 |
| indicator-active-color | String | #000000 | 当前选中的指示点颜色 |
| autoplay | Boolean | false | 是否自动切换 |
| interval | Number | 5000 | 自动切换时间间隔 |
| duration | Number | 500 | 滑动动画时长 |
| circular | Boolean | false | 是否采用衔接滑动 |
| vertical | Boolean | false | 滑动方向是否为纵向 |
| current | Number | 0 | 当前所在滑块的 index |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. 必须设置固定高度才能正常显示
2. `swiper-item` 内只能放置一个根元素
3. `circular` 设置为 true 时可以实现循环轮播
4. 图片轮播建议使用 `mode="aspectFill"` 保持比例
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/component/swiper.html
@@ -0,0 +1,277 @@
# switch 组件示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/component/switch.html
## 概述
`switch` 是开关选择器组件,用于两种状态的切换。
## 基础用法
```vue
<template>
<switch :checked="isChecked" @change="handleChange" />
</template>
<script>
export default {
data() {
return {
isChecked: false
}
},
methods: {
handleChange(e) {
this.isChecked = e.detail.value
}
}
}
</script>
```
## 完整示例
### 示例 1: 基本开关
```vue
<template>
<view class="container">
<view class="switch-item">
<text>通知开关</text>
<switch :checked="notifyEnabled" @change="handleNotifyChange" />
</view>
<view class="switch-item">
<text>声音开关</text>
<switch :checked="soundEnabled" @change="handleSoundChange" />
</view>
</view>
</template>
<script>
export default {
data() {
return {
notifyEnabled: true,
soundEnabled: false
}
},
methods: {
handleNotifyChange(e) {
this.notifyEnabled = e.detail.value
console.log('通知开关', this.notifyEnabled)
},
handleSoundChange(e) {
this.soundEnabled = e.detail.value
console.log('声音开关', this.soundEnabled)
}
}
}
</script>
<style>
.switch-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 20px;
border-bottom: 1px solid #eee;
}
</style>
```
### 示例 2: 自定义颜色
```vue
<template>
<view class="container">
<view class="switch-item">
<text>默认颜色</text>
<switch :checked="checked1" @change="checked1 = $event.detail.value" />
</view>
<view class="switch-item">
<text>自定义颜色</text>
<switch
:checked="checked2"
color="#ff3b30"
@change="checked2 = $event.detail.value"
/>
</view>
</view>
</template>
<script>
export default {
data() {
return {
checked1: false,
checked2: false
}
}
}
</script>
```
### 示例 3: 禁用状态
```vue
<template>
<view class="container">
<view class="switch-item">
<text>可用开关</text>
<switch :checked="checked" @change="handleChange" />
</view>
<view class="switch-item">
<text>禁用开关</text>
<switch :checked="checked" disabled />
</view>
</view>
</template>
<script>
export default {
data() {
return {
checked: false
}
},
methods: {
handleChange(e) {
this.checked = e.detail.value
}
}
}
</script>
```
### 示例 4: 设置项列表
```vue
<template>
<view class="container">
<view
v-for="item in settings"
:key="item.key"
class="setting-item"
>
<view class="setting-info">
<text class="setting-title">{{ item.title }}</text>
<text class="setting-desc">{{ item.desc }}</text>
</view>
<switch
:checked="item.value"
@change="handleSettingChange(item.key, $event.detail.value)"
/>
</view>
</view>
</template>
<script>
export default {
data() {
return {
settings: [
{
key: 'notify',
title: '消息通知',
desc: '接收新消息通知',
value: true
},
{
key: 'sound',
title: '声音提醒',
desc: '收到消息时播放声音',
value: false
},
{
key: 'vibrate',
title: '震动提醒',
desc: '收到消息时震动',
value: true
}
]
}
},
methods: {
handleSettingChange(key, value) {
const item = this.settings.find(s => s.key === key)
if (item) {
item.value = value
// 保存设置
uni.setStorageSync(`setting_${key}`, value)
console.log(`设置 ${key} 已更新为`, value)
}
}
},
onLoad() {
// 加载保存的设置
this.settings.forEach(item => {
const saved = uni.getStorageSync(`setting_${item.key}`)
if (saved !== '') {
item.value = saved
}
})
}
}
</script>
<style>
.setting-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 20px;
border-bottom: 1px solid #eee;
}
.setting-info {
flex: 1;
margin-right: 20px;
}
.setting-title {
display: block;
font-size: 32rpx;
color: #333;
margin-bottom: 10rpx;
}
.setting-desc {
display: block;
font-size: 24rpx;
color: #999;
}
</style>
```
## 属性说明
| 属性名 | 类型 | 默认值 | 说明 |
|--------|------|--------|------|
| checked | Boolean | false | 是否选中 |
| disabled | Boolean | false | 是否禁用 |
| type | String | switch | 样式类型,可选值:switch、checkbox |
| color | String | #007aff | switch 的颜色 |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. `checked` 属性控制开关状态
2. `@change` 事件返回 `e.detail.value` 为布尔值
3. 可以通过 `color` 自定义开关颜色
4. `disabled` 为 true 时开关不可操作
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/component/switch.html
@@ -0,0 +1,151 @@
# text 组件示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/component/text.html
## 概述
`text` 是文本组件,用于显示文本内容。
## 基础用法
```vue
<template>
<text>这是一段文本</text>
</template>
```
## 完整示例
### 示例 1: 基本文本
```vue
<template>
<view class="container">
<text>普通文本</text>
<text class="bold-text">加粗文本</text>
<text class="colored-text">彩色文本</text>
</view>
</template>
<style>
.bold-text {
font-weight: bold;
}
.colored-text {
color: #007aff;
}
</style>
```
### 示例 2: 文本嵌套
```vue
<template>
<view class="container">
<text>
这是一段
<text class="highlight">高亮</text>
文本
</text>
</view>
</template>
<style>
.highlight {
color: #ff3b30;
font-weight: bold;
}
</style>
```
### 示例 3: 文本选择
```vue
<template>
<view class="container">
<text selectable>这段文本可以选择</text>
<text :selectable="false">这段文本不可选择</text>
</view>
</template>
```
### 示例 4: 文本换行
```vue
<template>
<view class="container">
<text class="text-wrap">
这是一段很长的文本会自动换行显示这是一段很长的文本会自动换行显示
</text>
</view>
</template>
<style>
.text-wrap {
width: 300px;
word-wrap: break-word;
}
</style>
```
### 示例 5: 文本样式
```vue
<template>
<view class="container">
<text class="text-style">样式文本</text>
<text class="text-decoration">装饰文本</text>
<text class="text-shadow">阴影文本</text>
</view>
</template>
<style>
.text-style {
font-size: 32rpx;
font-weight: bold;
color: #333;
}
.text-decoration {
text-decoration: underline;
color: #007aff;
}
.text-shadow {
text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
}
</style>
```
## 属性说明
| 属性名 | 类型 | 默认值 | 说明 |
|--------|------|--------|------|
| selectable | Boolean | false | 文本是否可选 |
| user-select | Boolean | false | 文本是否可选(H5 |
| space | String | - | 显示连续空格 |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. `text` 组件内只能嵌套 `text` 组件
2. `selectable` 属性用于控制文本是否可选择
3. 文本样式通过 CSS 控制
4. 建议使用 `text` 组件而不是直接在 `view` 中写文本
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/component/text.html
@@ -0,0 +1,261 @@
# textarea 组件示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/component/textarea.html
## 概述
`textarea` 是多行输入框组件,用于输入多行文本。
## 基础用法
```vue
<template>
<textarea v-model="content" placeholder="请输入内容"></textarea>
</template>
<script>
export default {
data() {
return {
content: ''
}
}
}
</script>
```
## 完整示例
### 示例 1: 基本多行输入
```vue
<template>
<view class="container">
<textarea
v-model="content"
placeholder="请输入内容"
@input="handleInput"
></textarea>
<text>已输入{{ content.length }} </text>
</view>
</template>
<script>
export default {
data() {
return {
content: ''
}
},
methods: {
handleInput(e) {
this.content = e.detail.value
}
}
}
</script>
```
### 示例 2: 限制输入长度
```vue
<template>
<view class="container">
<textarea
v-model="content"
placeholder="最多输入200字"
maxlength="200"
@input="handleInput"
></textarea>
<text class="count">{{ content.length }}/200</text>
</view>
</template>
<script>
export default {
data() {
return {
content: ''
}
},
methods: {
handleInput(e) {
this.content = e.detail.value
}
}
}
</script>
<style>
.count {
color: #999;
font-size: 24rpx;
text-align: right;
}
</style>
```
### 示例 3: 自动调整高度
```vue
<template>
<view class="container">
<textarea
v-model="content"
placeholder="输入内容会自动调整高度"
:auto-height="true"
:min-height="100"
></textarea>
</view>
</template>
<script>
export default {
data() {
return {
content: ''
}
}
}
</script>
```
### 示例 4: 固定高度
```vue
<template>
<view class="container">
<textarea
v-model="content"
placeholder="固定高度输入框"
:show-confirm-bar="true"
confirm-type="done"
@confirm="handleConfirm"
></textarea>
</view>
</template>
<script>
export default {
data() {
return {
content: ''
}
},
methods: {
handleConfirm(e) {
console.log('确认输入', e.detail.value)
}
}
}
</script>
<style>
textarea {
width: 100%;
height: 200px;
}
</style>
```
### 示例 5: 表单验证
```vue
<template>
<view class="container">
<textarea
v-model="content"
placeholder="请输入反馈内容"
maxlength="500"
@blur="validateContent"
></textarea>
<text v-if="error" class="error">{{ error }}</text>
<text class="count">{{ content.length }}/500</text>
<button @click="submit">提交</button>
</view>
</template>
<script>
export default {
data() {
return {
content: '',
error: ''
}
},
methods: {
validateContent() {
if (this.content.length < 10) {
this.error = '内容至少需要10个字符'
} else {
this.error = ''
}
},
submit() {
this.validateContent()
if (!this.error && this.content) {
uni.showToast({
title: '提交成功',
icon: 'success'
})
}
}
}
}
</script>
<style>
.error {
color: #ff3b30;
font-size: 24rpx;
margin-top: 10rpx;
}
.count {
color: #999;
font-size: 24rpx;
text-align: right;
}
</style>
```
## 属性说明
| 属性名 | 类型 | 默认值 | 说明 |
|--------|------|--------|------|
| value | String | - | 输入框的内容 |
| placeholder | String | - | 输入框为空时占位符 |
| placeholder-style | String | - | 指定 placeholder 的样式 |
| disabled | Boolean | false | 是否禁用 |
| maxlength | Number | 140 | 最大输入长度,-1 表示不限制 |
| auto-focus | Boolean | false | 是否自动聚焦 |
| focus | Boolean | false | 获取焦点 |
| auto-height | Boolean | false | 是否自动增高 |
| fixed | Boolean | false | 如果 textarea 是在一个 position:fixed 的区域,需要显示指定属性 fixed 为 true |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. `v-model` 是双向绑定的推荐方式
2. `maxlength` 设置为 -1 时不限制最大长度
3. `auto-height` 可以让输入框随内容自动调整高度
4. 建议使用 `@input` 事件监听输入变化
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/component/textarea.html
- **单行输入**: https://uniapp.dcloud.net.cn/component/input.html
@@ -0,0 +1,291 @@
# video 组件示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/component/video.html
## 概述
`video` 是视频播放组件,用于播放视频内容。
## 基础用法
```vue
<template>
<video
src="https://example.com/video.mp4"
controls
></video>
</template>
```
## 完整示例
### 示例 1: 基本视频播放
```vue
<template>
<view class="container">
<video
:src="videoSrc"
controls
class="video-player"
></video>
</view>
</template>
<script>
export default {
data() {
return {
videoSrc: 'https://example.com/video.mp4'
}
}
}
</script>
<style>
.video-player {
width: 100%;
height: 400px;
}
</style>
```
### 示例 2: 视频播放控制
```vue
<template>
<view class="container">
<video
:src="videoSrc"
:controls="showControls"
:autoplay="autoplay"
:loop="loop"
:muted="muted"
:poster="poster"
@play="handlePlay"
@pause="handlePause"
@ended="handleEnded"
class="video-player"
></video>
<view class="controls">
<button @click="togglePlay">{{ isPlaying ? '暂停' : '播放' }}</button>
<button @click="toggleMute">{{ muted ? '取消静音' : '静音' }}</button>
</view>
</view>
</template>
<script>
export default {
data() {
return {
videoSrc: 'https://example.com/video.mp4',
showControls: true,
autoplay: false,
loop: false,
muted: false,
poster: 'https://example.com/poster.jpg',
isPlaying: false
}
},
methods: {
handlePlay() {
this.isPlaying = true
console.log('视频开始播放')
},
handlePause() {
this.isPlaying = false
console.log('视频暂停')
},
handleEnded() {
this.isPlaying = false
console.log('视频播放结束')
},
togglePlay() {
// 需要通过 ref 调用视频组件的方法
this.$refs.video.play()
},
toggleMute() {
this.muted = !this.muted
}
}
}
</script>
```
### 示例 3: 视频列表
```vue
<template>
<view class="container">
<view
v-for="(item, index) in videoList"
:key="index"
class="video-item"
>
<video
:src="item.src"
:poster="item.poster"
controls
class="video-player"
@play="handleVideoPlay(index)"
></video>
<text class="video-title">{{ item.title }}</text>
</view>
</view>
</template>
<script>
export default {
data() {
return {
videoList: [
{
src: 'https://example.com/video1.mp4',
poster: 'https://example.com/poster1.jpg',
title: '视频1'
},
{
src: 'https://example.com/video2.mp4',
poster: 'https://example.com/poster2.jpg',
title: '视频2'
}
]
}
},
methods: {
handleVideoPlay(index) {
console.log('播放视频', index)
}
}
}
</script>
<style>
.video-item {
margin-bottom: 20px;
}
.video-player {
width: 100%;
height: 400px;
}
.video-title {
display: block;
padding: 10px;
font-size: 32rpx;
}
</style>
```
### 示例 4: 全屏播放
```vue
<template>
<view class="container">
<video
:src="videoSrc"
controls
:show-fullscreen-btn="true"
:enable-play-gesture="true"
@fullscreenchange="handleFullscreenChange"
class="video-player"
></video>
</view>
</template>
<script>
export default {
data() {
return {
videoSrc: 'https://example.com/video.mp4',
isFullscreen: false
}
},
methods: {
handleFullscreenChange(e) {
this.isFullscreen = e.detail.fullScreen
console.log('全屏状态', this.isFullscreen)
}
}
}
</script>
```
### 示例 5: 视频弹幕
```vue
<template>
<view class="container">
<video
:src="videoSrc"
:danmu-list="danmuList"
:enable-danmu="true"
:danmu-btn="true"
controls
class="video-player"
></video>
</view>
</template>
<script>
export default {
data() {
return {
videoSrc: 'https://example.com/video.mp4',
danmuList: [
{
text: '第一条弹幕',
color: '#ff0000',
time: 1
},
{
text: '第二条弹幕',
color: '#00ff00',
time: 3
}
]
}
}
}
</script>
```
## 属性说明
| 属性名 | 类型 | 默认值 | 说明 |
|--------|------|--------|------|
| src | String | - | 要播放视频的资源地址 |
| controls | Boolean | true | 是否显示默认播放控件 |
| autoplay | Boolean | false | 是否自动播放 |
| loop | Boolean | false | 是否循环播放 |
| muted | Boolean | false | 是否静音播放 |
| poster | String | - | 视频封面的图片网络资源地址 |
| show-fullscreen-btn | Boolean | true | 是否显示全屏按钮 |
| enable-play-gesture | Boolean | false | 是否开启播放手势 |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. 视频地址需要配置合法域名
2. `autoplay` 在某些平台可能不生效
3. 建议设置 `poster` 作为视频封面
4. 可以通过事件监听播放状态
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/component/video.html
- **选择视频**: https://uniapp.dcloud.net.cn/api/media/video.html#choosevideo
@@ -0,0 +1,407 @@
# view 组件示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/component/view.html
## 概述
`view` 是视图容器组件,类似于 HTML 中的 `div`,用于包裹各种元素内容。
## 基础用法
### 基本视图容器
```vue
<template>
<view class="container">
<text>这是内容</text>
</view>
</template>
<style>
.container {
padding: 20px;
background-color: #f5f5f5;
}
</style>
```
## 完整示例
### 示例 1: Flex 布局 - 横向布局
```vue
<template>
<view class="uni-padding-wrap uni-common-mt">
<view class="uni-title uni-common-mt">
flex-direction: row
<text>\n横向布局</text>
</view>
<view class="uni-flex uni-row">
<view class="flex-item uni-bg-red">A</view>
<view class="flex-item uni-bg-green">B</view>
<view class="flex-item uni-bg-blue">C</view>
</view>
</view>
</template>
<style>
.uni-flex {
display: flex;
}
.uni-row {
flex-direction: row;
}
.flex-item {
flex: 1;
height: 100px;
text-align: center;
line-height: 100px;
}
.uni-bg-red {
background-color: #ff3b30;
}
.uni-bg-green {
background-color: #4cd964;
}
.uni-bg-blue {
background-color: #007aff;
}
</style>
```
### 示例 2: Flex 布局 - 纵向布局
```vue
<template>
<view class="uni-padding-wrap uni-common-mt">
<view class="uni-title uni-common-mt">
flex-direction: column
<text>\n纵向布局</text>
</view>
<view class="uni-flex uni-column">
<view class="flex-item flex-item-V uni-bg-red">A</view>
<view class="flex-item flex-item-V uni-bg-green">B</view>
<view class="flex-item flex-item-V uni-bg-blue">C</view>
</view>
</view>
</template>
<style>
.uni-flex {
display: flex;
}
.uni-column {
flex-direction: column;
}
.flex-item-V {
width: 100%;
height: 100px;
text-align: center;
line-height: 100px;
}
</style>
```
### 示例 3: 点击态效果
```vue
<template>
<view class="container">
<view
class="clickable-item"
hover-class="hover"
hover-start-time="50"
hover-stay-time="400"
@click="handleClick"
>
点击我
</view>
</view>
</template>
<script>
export default {
methods: {
handleClick() {
uni.showToast({
title: '被点击了',
icon: 'success'
})
}
}
}
</script>
<style>
.clickable-item {
padding: 20px;
background-color: #007aff;
color: white;
text-align: center;
border-radius: 8px;
}
.hover {
background-color: #0051d5;
opacity: 0.8;
}
</style>
```
### 示例 4: 阻止点击态冒泡
```vue
<template>
<view class="container" hover-class="container-hover">
<view
class="inner-item"
hover-class="inner-hover"
hover-stop-propagation="true"
@click="handleInnerClick"
>
内部元素阻止冒泡
</view>
</view>
</template>
<script>
export default {
methods: {
handleInnerClick() {
console.log('内部元素被点击')
}
}
}
</script>
<style>
.container {
padding: 40px;
background-color: #f5f5f5;
}
.container-hover {
background-color: #e0e0e0;
}
.inner-item {
padding: 20px;
background-color: #007aff;
color: white;
text-align: center;
border-radius: 8px;
}
.inner-hover {
background-color: #0051d5;
}
</style>
```
### 示例 5: 嵌套视图
```vue
<template>
<view class="page">
<view class="header">
<text class="title">页面标题</text>
</view>
<view class="content">
<view class="section">
<text class="section-title">第一部分</text>
<view class="section-content">
<text>这是第一部分的内容</text>
</view>
</view>
<view class="section">
<text class="section-title">第二部分</text>
<view class="section-content">
<text>这是第二部分的内容</text>
</view>
</view>
</view>
<view class="footer">
<text>页脚</text>
</view>
</view>
</template>
<style>
.page {
min-height: 100vh;
display: flex;
flex-direction: column;
}
.header {
padding: 20px;
background-color: #007aff;
color: white;
}
.title {
font-size: 18px;
font-weight: bold;
}
.content {
flex: 1;
padding: 20px;
}
.section {
margin-bottom: 20px;
padding: 15px;
background-color: #f5f5f5;
border-radius: 8px;
}
.section-title {
font-size: 16px;
font-weight: bold;
margin-bottom: 10px;
}
.section-content {
padding: 10px;
background-color: white;
border-radius: 4px;
}
.footer {
padding: 20px;
background-color: #f5f5f5;
text-align: center;
}
</style>
```
### 示例 6: 条件渲染
```vue
<template>
<view class="container">
<view v-if="showContent" class="content">
<text>这是显示的内容</text>
</view>
<view v-else class="empty">
<text>暂无内容</text>
</view>
<button @click="toggleContent">切换显示</button>
</view>
</template>
<script>
export default {
data() {
return {
showContent: true
}
},
methods: {
toggleContent() {
this.showContent = !this.showContent
}
}
}
</script>
<style>
.container {
padding: 20px;
}
.content {
padding: 20px;
background-color: #4cd964;
color: white;
border-radius: 8px;
margin-bottom: 20px;
}
.empty {
padding: 20px;
background-color: #f5f5f5;
color: #999;
border-radius: 8px;
margin-bottom: 20px;
text-align: center;
}
</style>
```
### 示例 7: 列表渲染
```vue
<template>
<view class="container">
<view
v-for="(item, index) in list"
:key="index"
class="list-item"
@click="handleItemClick(item)"
>
<text>{{ item.name }}</text>
</view>
</view>
</template>
<script>
export default {
data() {
return {
list: [
{ id: 1, name: '项目 1' },
{ id: 2, name: '项目 2' },
{ id: 3, name: '项目 3' }
]
}
},
methods: {
handleItemClick(item) {
uni.showToast({
title: `点击了 ${item.name}`,
icon: 'none'
})
}
}
}
</script>
<style>
.container {
padding: 20px;
}
.list-item {
padding: 15px;
margin-bottom: 10px;
background-color: #f5f5f5;
border-radius: 8px;
}
</style>
```
## 属性说明
| 属性名 | 类型 | 默认值 | 说明 |
|--------|------|--------|------|
| hover-class | String | none | 指定按下去的样式类 |
| hover-stop-propagation | Boolean | false | 指定是否阻止本节点的祖先节点出现点击态 |
| hover-start-time | Number | 50 | 按住后多久出现点击态,单位毫秒 |
| hover-stay-time | Number | 400 | 手指松开后点击态保留时间,单位毫秒 |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. `view` 组件本身不显示任何可视化元素,主要用于包裹其他组件
2. 可以使用 CSS 样式控制 `view` 的显示效果
3. 支持 Flex 布局,常用于页面布局
4. `hover-class` 属性用于设置点击态效果
5. `hover-stop-propagation` 在某些平台可能不支持
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/component/view.html
- **Flex 布局**: https://uniapp.dcloud.net.cn/tutorial/css-flex.html
@@ -0,0 +1,196 @@
# web-view 组件示例
## 官方文档
参考官方文档:https://uniapp.dcloud.net.cn/component/web-view.html
## 概述
`web-view` 是网页视图组件,用于在页面中嵌入网页。
## 基础用法
```vue
<template>
<web-view src="https://example.com"></web-view>
</template>
```
## 完整示例
### 示例 1: 基本网页显示
```vue
<template>
<view class="container">
<web-view :src="webUrl"></web-view>
</view>
</template>
<script>
export default {
data() {
return {
webUrl: 'https://example.com'
}
}
}
</script>
<style>
.container {
width: 100%;
height: 100vh;
}
</style>
```
### 示例 2: 动态加载网页
```vue
<template>
<view class="container">
<input v-model="url" placeholder="输入网址" />
<button @click="loadUrl">加载网页</button>
<web-view v-if="webUrl" :src="webUrl"></web-view>
</view>
</template>
<script>
export default {
data() {
return {
url: '',
webUrl: ''
}
},
methods: {
loadUrl() {
if (this.url) {
// 确保 URL 以 http:// 或 https:// 开头
if (!this.url.startsWith('http://') && !this.url.startsWith('https://')) {
this.webUrl = 'https://' + this.url
} else {
this.webUrl = this.url
}
}
}
}
}
</script>
```
### 示例 3: 从参数加载网页
```vue
<template>
<view class="container">
<web-view :src="webUrl"></web-view>
</view>
</template>
<script>
export default {
data() {
return {
webUrl: ''
}
},
onLoad(options) {
if (options.url) {
this.webUrl = decodeURIComponent(options.url)
} else {
this.webUrl = 'https://example.com'
}
}
}
</script>
```
### 示例 4: 网页与小程序通信
```vue
<template>
<view class="container">
<web-view :src="webUrl" @message="handleMessage"></web-view>
</view>
</template>
<script>
export default {
data() {
return {
webUrl: 'https://example.com'
}
},
methods: {
handleMessage(e) {
console.log('收到网页消息', e.detail.data)
// 处理来自网页的消息
const data = e.detail.data[0]
if (data && data.type === 'close') {
uni.navigateBack()
}
}
}
}
</script>
```
### 示例 5: 加载本地 HTML
```vue
<template>
<view class="container">
<web-view :src="localHtmlUrl"></web-view>
</view>
</template>
<script>
export default {
data() {
return {
localHtmlUrl: '/static/webview.html'
}
}
}
</script>
```
## 属性说明
| 属性名 | 类型 | 默认值 | 说明 |
|--------|------|--------|------|
| src | String | - | webview 指向网页的链接 |
## 事件说明
| 事件名 | 说明 | 返回值 |
|--------|------|--------|
| @message | 网页向小程序 postMessage 时触发 | e.detail.data 包含网页传递的数据 |
## 平台兼容性
| 平台 | 支持情况 |
|------|---------|
| H5 | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 字节跳动小程序 | ✅ |
| QQ 小程序 | ✅ |
| 快手小程序 | ✅ |
| App | ✅ |
| 快应用 | ✅ |
## 注意事项
1. `src` 必须是 HTTPS 协议(H5 除外)
2. 需要在 `manifest.json` 中配置业务域名
3. 网页可以通过 `wx.miniProgram.postMessage` 向小程序发送消息
4. 建议使用全屏显示 web-view
## 参考资源
- **官方文档**: https://uniapp.dcloud.net.cn/component/web-view.html
- **配置业务域名**: https://uniapp.dcloud.net.cn/tutorial/app-webview.html
@@ -0,0 +1,98 @@
# uni-ui 组件示例文件
本目录包含所有 uni-ui 组件的完整示例代码,每个组件都有独立的示例文件。
## 文件命名规范
示例文件命名格式:`{组件名}.vue`
例如:
- `uni-badge.vue` - uni-badge 数字角标组件示例
- `uni-icons.vue` - uni-icons 图标组件示例
- `uni-card.vue` - uni-card 卡片组件示例
## 示例文件结构
每个示例文件包含:
1. **文件头部注释**:包含组件名称、官方文档地址、插件市场地址
2. **完整示例代码**:包含官网展示的所有示例场景
3. **模板代码**:完整的 template 部分
4. **脚本代码**:完整的 script 部分,包含数据和方法
5. **样式代码**:完整的 style 部分
## 组件列表
### 基础组件
- [uni-badge.vue](./uni-badge.vue) - 数字角标
- [uni-icons.vue](./uni-icons.vue) - 图标
- [uni-tag.vue](./uni-tag.vue) - 标签
- [uni-link.vue](./uni-link.vue) - 超链接
### 布局组件
- [uni-row.vue](./uni-row.vue) - 布局-行
- [uni-grid.vue](./uni-grid.vue) - 宫格
- [uni-group.vue](./uni-group.vue) - 分组
- [uni-section.vue](./uni-section.vue) - 标题栏
- [uni-title.vue](./uni-title.vue) - 章节标题
### 导航组件
- [uni-nav-bar.vue](./uni-nav-bar.vue) - 自定义导航栏
- [uni-breadcrumb.vue](./uni-breadcrumb.vue) - 面包屑
### 数据展示组件
- [uni-card.vue](./uni-card.vue) - 卡片
- [uni-list.vue](./uni-list.vue) - 列表
- [uni-indexed-list.vue](./uni-indexed-list.vue) - 索引列表
- [uni-table.vue](./uni-table.vue) - 表格
- [uni-load-more.vue](./uni-load-more.vue) - 加载更多
- [uni-pagination.vue](./uni-pagination.vue) - 分页器
### 数据录入组件
- [uni-easyinput.vue](./uni-easyinput.vue) - 增强输入框
- [uni-number-box.vue](./uni-number-box.vue) - 数字输入框
- [uni-forms.vue](./uni-forms.vue) - 表单
- [uni-data-checkbox.vue](./uni-data-checkbox.vue) - 数据选择器
- [uni-data-picker.vue](./uni-data-picker.vue) - 级联选择器
- [uni-data-select.vue](./uni-data-select.vue) - 下拉框
- [uni-combox.vue](./uni-combox.vue) - 组合框
### 日期时间组件
- [uni-calendar.vue](./uni-calendar.vue) - 日历
- [uni-datetime-picker.vue](./uni-datetime-picker.vue) - 日期选择器
- [uni-dateformat.vue](./uni-dateformat.vue) - 日期格式化
### 反馈组件
- [uni-popup.vue](./uni-popup.vue) - 弹出层
- [uni-drawer.vue](./uni-drawer.vue) - 抽屉
- [uni-notice-bar.vue](./uni-notice-bar.vue) - 通告栏
- [uni-tooltip.vue](./uni-tooltip.vue) - 文字提示
### 操作反馈组件
- [uni-rate.vue](./uni-rate.vue) - 评分
- [uni-fav.vue](./uni-fav.vue) - 收藏按钮
- [uni-fab.vue](./uni-fab.vue) - 悬浮按钮
- [uni-swipe-action.vue](./uni-swipe-action.vue) - 滑动操作
### 其他组件
- [uni-collapse.vue](./uni-collapse.vue) - 折叠面板
- [uni-countdown.vue](./uni-countdown.vue) - 倒计时
- [uni-search-bar.vue](./uni-search-bar.vue) - 搜索栏
- [uni-segmented-control.vue](./uni-segmented-control.vue) - 分段器
- [uni-steps.vue](./uni-steps.vue) - 步骤条
- [uni-swiper-dot.vue](./uni-swiper-dot.vue) - 轮播图指示点
- [uni-transition.vue](./uni-transition.vue) - 过渡动画
- [uni-file-picker.vue](./uni-file-picker.vue) - 文件选择上传
- [uni-goods-nav.vue](./uni-goods-nav.vue) - 商品导航
## 使用说明
1. 每个示例文件都是完整的、可运行的 Vue 组件
2. 示例代码来自 uni-ui 官方文档
3. 所有示例都包含完整的 template、script 和 style
4. 示例文件可以直接复制到项目中使用
## 参考资源
- [uni-ui 官方文档](https://uniapp.dcloud.net.cn/component/uniui/uni-ui.html)
- [uni-ui 插件市场](https://ext.dcloud.net.cn/plugin?id=55)
@@ -0,0 +1,160 @@
<!--
uni-badge 数字角标组件示例
官方文档https://uniapp.dcloud.net.cn/component/uniui/uni-badge.html
插件市场https://ext.dcloud.net.cn/plugin?name=uni-badge
-->
<template>
<view class="container">
<uni-card is-full :is-shadow="false">
<text class="uni-h6">数字角标通用来标记重点信息使用如接受到新消息有未读消息等</text>
</uni-card>
<!-- 基础用法 -->
<uni-section title="基础用法" type="line" padding>
<view class="example-body">
<uni-badge class="uni-badge-left-margin" text="1" />
<uni-badge class="uni-badge-left-margin" text="2" type="primary" />
<uni-badge class="uni-badge-left-margin" text="34" type="success" />
<uni-badge class="uni-badge-left-margin" text="45" type="warning" />
<uni-badge class="uni-badge-left-margin" text="123" type="info" />
</view>
</uni-section>
<!-- 无底色 -->
<uni-section title="无底色" type="line" padding>
<view class="example-body">
<uni-badge class="uni-badge-left-margin" :inverted="true" text="1" />
<uni-badge class="uni-badge-left-margin" :inverted="true" text="2" type="primary" />
<uni-badge class="uni-badge-left-margin" :inverted="true" text="34" type="success" />
<uni-badge class="uni-badge-left-margin" :inverted="true" text="45" type="warning" />
<uni-badge class="uni-badge-left-margin" :inverted="true" text="123" type="info" />
</view>
</uni-section>
<!-- 自定义样式 -->
<uni-section title="自定义样式" type="line" padding>
<view class="example-body">
<uni-badge
class="uni-badge-left-margin"
text="2"
type="primary"
:custom-style="{background: '#4335d6'}"
/>
<uni-badge
class="uni-badge-left-margin"
text="2"
type="primary"
:custom-style="customStyle"
/>
</view>
</uni-section>
<!-- 定位: absolute 属性 -->
<uni-section title="定位: aboslute 属性" sub-title="在安卓端不支持 nvue" type="line" padding>
<uni-badge
class="uni-badge-left-margin"
:text="value"
absolute="rightTop"
size="small"
>
<view class="box">
<text class="box-text">右上</text>
</view>
</uni-badge>
</uni-section>
<!-- 偏移: offset 属性(存在 aboslute) -->
<uni-section title="偏移: offset 属性(存在 aboslute)" type="line" padding>
<uni-badge
class="uni-badge-left-margin"
:text="8"
absolute="rightTop"
:offset="[-3, -3]"
size="small"
>
<view class="box">
<text class="box-text">右上</text>
</view>
</uni-badge>
</uni-section>
<!-- 仅显示点: is-dot 属性 -->
<uni-section title="仅显示点: is-dot 属性" type="line" padding>
<uni-badge
class="uni-badge-left-margin"
:is-dot="true"
:text="value"
absolute="rightTop"
size="small"
>
<view class="box">
<text class="box-text">圆点</text>
</view>
</uni-badge>
</uni-section>
</view>
</template>
<script>
export default {
data() {
return {
value: 0,
customStyle: {
backgroundColor: '#62ed0d',
color: '#fff'
}
}
},
mounted() {
const timer = setInterval(() => {
if (this.value >= 199) {
clearInterval(timer)
return
}
this.value++
}, 100)
}
}
</script>
<style lang="scss">
/* #ifdef MP-ALIPAY */
.uni-badge {
margin-left: 20rpx;
}
/* #endif */
.example-body {
flex-direction: row;
justify-content: flex-start;
}
.uni-badge-left-margin {
margin-left: 10px;
}
.uni-badge-absolute {
margin-left: 40px;
}
.box {
width: 40px;
height: 40px;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
background-color: #DCDFE6;
color: #fff;
font-size: 12px;
}
.box-text {
text-align: center;
color: #fff;
font-size: 12px;
}
</style>
@@ -0,0 +1,96 @@
<!--
面包屑 组件示例
官方文档https://uniapp.dcloud.net.cn/component/uniui/uni-breadcrumb.html
插件市场https://ext.dcloud.net.cn/plugin?name=uni-breadcrumb
-->
<template>
<view class="container">
<uni-card is-full :is-shadow="false">
<text class="uni-h6">面包屑组件用于显示当前页面的路径帮助用户了解当前位置</text>
</uni-card>
<uni-section title="基础用法" type="line" padding>
<view class="example-body">
<uni-breadcrumb :separator="separator">
<uni-breadcrumb-item v-for="(item, index) in breadcrumbList1" :key="index">
{{ item }}
</uni-breadcrumb-item>
</uni-breadcrumb>
</view>
</uni-section>
<uni-section title="自定义分隔符" type="line" padding>
<view class="example-body">
<uni-breadcrumb separator="/">
<uni-breadcrumb-item>首页</uni-breadcrumb-item>
<uni-breadcrumb-item>分类</uni-breadcrumb-item>
<uni-breadcrumb-item>详情</uni-breadcrumb-item>
</uni-breadcrumb>
<uni-breadcrumb separator=">">
<uni-breadcrumb-item>首页</uni-breadcrumb-item>
<uni-breadcrumb-item>分类</uni-breadcrumb-item>
<uni-breadcrumb-item>详情</uni-breadcrumb-item>
</uni-breadcrumb>
</view>
</uni-section>
<uni-section title="可点击" type="line" padding>
<view class="example-body">
<uni-breadcrumb>
<uni-breadcrumb-item v-for="(item, index) in breadcrumbList2" :key="index" @click="onBreadcrumbClick(item, index)">
{{ item.text }}
</uni-breadcrumb-item>
</uni-breadcrumb>
</view>
</uni-section>
<uni-section title="自定义样式" type="line" padding>
<view class="example-body">
<uni-breadcrumb separator="/" color="#ff6b6b">
<uni-breadcrumb-item>首页</uni-breadcrumb-item>
<uni-breadcrumb-item>分类</uni-breadcrumb-item>
<uni-breadcrumb-item>详情</uni-breadcrumb-item>
</uni-breadcrumb>
</view>
</uni-section>
</view>
</template>
<script>
export default {
data() {
return {
separator: '/',
breadcrumbList1: ['首页', '分类', '详情'],
breadcrumbList2: [
{ text: '首页', path: '/' },
{ text: '分类', path: '/category' },
{ text: '详情', path: '/detail' }
]
}
},
methods: {
onBreadcrumbClick(item, index) {
console.log('点击面包屑:', item, index)
uni.showToast({
title: `点击了${item.text}`,
icon: 'none'
})
}
}
}
</script>
<style lang="scss">
.container {
padding: 10px;
}
.example-body {
display: flex;
flex-direction: column;
gap: 20px;
}
</style>
@@ -0,0 +1,126 @@
<!--
日历 组件示例
官方文档https://uniapp.dcloud.net.cn/component/uniui/uni-calendar.html
插件市场https://ext.dcloud.net.cn/plugin?name=uni-calendar
-->
<template>
<view class="container">
<uni-card is-full :is-shadow="false">
<text class="uni-h6">日历组件用于日期选择支持单选多选范围选择</text>
</uni-card>
<uni-section title="基础用法" type="line" padding>
<view class="example-body">
<button type="primary" @click="openCalendar('single')">单选日期</button>
<uni-calendar ref="singleCalendar" :insert="false" :lunar="false" :start-date="startDate" :end-date="endDate" @confirm="onConfirm" />
</view>
</uni-section>
<uni-section title="多选日期" type="line" padding>
<view class="example-body">
<button type="primary" @click="openCalendar('multiple')">多选日期</button>
<text class="result-text">已选日期{{ multipleDates.join(', ') || '无' }}</text>
<uni-calendar ref="multipleCalendar" :insert="false" :multiple="true" @confirm="onMultipleConfirm" />
</view>
</uni-section>
<uni-section title="范围选择" type="line" padding>
<view class="example-body">
<button type="primary" @click="openCalendar('range')">范围选择</button>
<text class="result-text">选择范围{{ rangeDates.start || '' }} {{ rangeDates.end || '' }}</text>
<uni-calendar ref="rangeCalendar" :insert="false" :range="true" @confirm="onRangeConfirm" />
</view>
</uni-section>
<uni-section title="显示农历" type="line" padding>
<view class="example-body">
<button type="primary" @click="openCalendar('lunar')">显示农历</button>
<uni-calendar ref="lunarCalendar" :insert="false" :lunar="true" @confirm="onConfirm" />
</view>
</uni-section>
<uni-section title="自定义日期范围" type="line" padding>
<view class="example-body">
<button type="primary" @click="openCalendar('custom')">自定义范围</button>
<uni-calendar ref="customCalendar" :insert="false" :start-date="'2024-01-01'" :end-date="'2024-12-31'" @confirm="onConfirm" />
</view>
</uni-section>
</view>
</template>
<script>
export default {
data() {
return {
startDate: '2024-01-01',
endDate: '2024-12-31',
multipleDates: [],
rangeDates: {
start: '',
end: ''
}
}
},
methods: {
openCalendar(type) {
if (type === 'single') {
this.$refs.singleCalendar.open()
} else if (type === 'multiple') {
this.$refs.multipleCalendar.open()
} else if (type === 'range') {
this.$refs.rangeCalendar.open()
} else if (type === 'lunar') {
this.$refs.lunarCalendar.open()
} else if (type === 'custom') {
this.$refs.customCalendar.open()
}
},
onConfirm(e) {
console.log('选择日期:', e)
uni.showToast({
title: `选择了:${e.fulldate}`,
icon: 'none'
})
},
onMultipleConfirm(e) {
console.log('多选日期:', e)
this.multipleDates = e.fulldate || []
uni.showToast({
title: `选择了${this.multipleDates.length}个日期`,
icon: 'none'
})
},
onRangeConfirm(e) {
console.log('范围选择:', e)
this.rangeDates = {
start: e.fulldate[0] || '',
end: e.fulldate[1] || ''
}
uni.showToast({
title: `选择了范围`,
icon: 'none'
})
}
}
}
</script>
<style lang="scss">
.container {
padding: 10px;
}
.example-body {
display: flex;
flex-direction: column;
gap: 15px;
}
.result-text {
font-size: 14px;
color: #333;
margin-top: 10px;
}
</style>
@@ -0,0 +1,216 @@
<!--
uni-card 卡片组件示例
官方文档https://uniapp.dcloud.net.cn/component/uniui/uni-card.html
插件市场https://ext.dcloud.net.cn/plugin?name=uni-card
-->
<template>
<view class="container">
<uni-card :is-shadow="false" is-full>
<text class="uni-h6">卡片组件通用来显示完整独立的一段信息同时让用户理解他的作用例如一篇文章的预览图作者信息时间等卡片通常是更复杂和更详细信息的入口点</text>
</uni-card>
<!-- 基础卡片 -->
<uni-section title="基础卡片" type="line">
<uni-card :is-shadow="false">
<text class="uni-body">这是一个基础卡片示例内容较少此示例展示了一个没有任何属性不带阴影的卡片</text>
</uni-card>
</uni-section>
<!-- 卡片标题+额外信息 -->
<uni-section title="卡片标题+额外信息" type="line">
<uni-card title="基础卡片" extra="额外信息">
<text class="uni-body">这是一个基础卡片示例此示例展示了一个标题加标题额外信息的标准卡片</text>
</uni-card>
</uni-section>
<!-- 双标题卡片 -->
<uni-section title="双标题卡片" type="line">
<uni-card
title="基础卡片"
sub-title="副标题"
extra="额外信息"
:thumbnail="avatar"
@click="onClick"
>
<text class="uni-body">这是一个带头像和双标题的基础卡片此示例展示了一个完整的卡片</text>
</uni-card>
</uni-section>
<!-- 通栏卡片 -->
<uni-section title="通栏卡片" type="line">
<uni-card
title="基础卡片"
:isFull="true"
sub-title="副标题"
extra="额外信息"
:thumbnail="avatar"
>
<text class="uni-body">这是一个通栏卡片 通栏没有外边距左右会贴合父元素</text>
</uni-card>
</uni-section>
<!-- 卡片封面图+操作栏 -->
<uni-section title="卡片封面图+操作栏" type="line">
<uni-card :cover="cover" @click="onClick">
<text class="uni-body">这是一个带封面和操作栏的卡片示例此示例展示了封面插槽和操作栏插槽的用法</text>
<template v-slot:actions>
<view class="card-actions">
<view class="card-actions-item" @click.stop="actionsClick('分享')">
<uni-icons type="pengyouquan" size="18" color="#999"></uni-icons>
<text class="card-actions-item-text">分享</text>
</view>
<view class="card-actions-item" @click.stop="actionsClick('点赞')">
<uni-icons type="heart" size="18" color="#999"></uni-icons>
<text class="card-actions-item-text">点赞</text>
</view>
<view class="card-actions-item" @click.stop="actionsClick('评论')">
<uni-icons type="chatbubble" size="18" color="#999"></uni-icons>
<text class="card-actions-item-text">评论</text>
</view>
</view>
</template>
</uni-card>
</uni-section>
<!-- 自定义卡片内容 -->
<uni-section title="自定义卡片内容" type="line">
<uni-card
title="基础卡片"
sub-title="副标题"
extra="额外信息"
padding="10px 0"
:thumbnail="avatar"
>
<template v-slot:title>
<uni-list>
<uni-list-item :show-switch="true" title="自定义标题" />
</uni-list>
</template>
<image style="width: 100%;" :src="cover"></image>
<text class="uni-body uni-mt-5">卡片组件通用来显示完整独立的一段信息同时让用户理解他的作用例如一篇文章的预览图作者信息时间等卡片通常是更复杂和更详细信息的入口点</text>
<view slot="actions" class="card-actions">
<view class="card-actions-item" @click.stop="actionsClick('分享')">
<uni-icons type="pengyouquan" size="18" color="#999"></uni-icons>
<text class="card-actions-item-text">分享</text>
</view>
<view class="card-actions-item" @click.stop="actionsClick('点赞')">
<uni-icons type="heart" size="18" color="#999"></uni-icons>
<text class="card-actions-item-text">点赞</text>
</view>
<view class="card-actions-item" @click.stop="actionsClick('评论')">
<uni-icons type="chatbubble" size="18" color="#999"></uni-icons>
<text class="card-actions-item-text">评论</text>
</view>
</view>
</uni-card>
</uni-section>
<!-- 卡片+列表 -->
<uni-section title="卡片+列表" type="line">
<uni-card padding="0" spacing="0">
<template v-slot:cover>
<view class="custom-cover">
<image class="cover-image" mode="aspectFill" :src="cover"></image>
<view class="cover-content">
<text class="uni-subtitle uni-white">今日新闻热点</text>
</view>
</view>
</template>
<uni-list>
<uni-list-item title="今日新闻" showArrow></uni-list-item>
<uni-list-item title="今日新闻" showArrow></uni-list-item>
</uni-list>
<view slot="actions" class="card-actions no-border">
<view class="card-actions-item" @click.stop="actionsClick('分享')">
<uni-icons type="pengyouquan" size="18" color="#999"></uni-icons>
<text class="card-actions-item-text">分享</text>
</view>
<view class="card-actions-item" @click.stop="actionsClick('点赞')">
<uni-icons type="heart" size="18" color="#999"></uni-icons>
<text class="card-actions-item-text">点赞</text>
</view>
<view class="card-actions-item" @click.stop="actionsClick('评论')">
<uni-icons type="chatbubble" size="18" color="#999"></uni-icons>
<text class="card-actions-item-text">评论</text>
</view>
</view>
</uni-card>
</uni-section>
</view>
</template>
<script>
export default {
data() {
return {
avatar: 'https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/unicloudlogo.png',
cover: 'https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/unicloudlogo.png'
}
},
methods: {
onClick() {
uni.showToast({
title: '点击了卡片',
icon: 'none'
})
},
actionsClick(type) {
uni.showToast({
title: `点击了${type}`,
icon: 'none'
})
}
}
}
</script>
<style lang="scss">
.card-actions {
display: flex;
justify-content: space-around;
align-items: center;
height: 45px;
padding: 0 10px;
border-top: 1px solid #f0f0f0;
}
.card-actions.no-border {
border-top: none;
}
.card-actions-item {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
flex: 1;
}
.card-actions-item-text {
font-size: 12px;
color: #999;
margin-top: 5px;
}
.custom-cover {
position: relative;
width: 100%;
height: 200px;
}
.cover-image {
width: 100%;
height: 100%;
}
.cover-content {
position: absolute;
bottom: 0;
left: 0;
right: 0;
padding: 20rpx;
background: linear-gradient(to top, rgba(0, 0, 0, 0.5), transparent);
}
</style>
@@ -0,0 +1,122 @@
<!--
折叠面板 组件示例
官方文档https://uniapp.dcloud.net.cn/component/uniui/uni-collapse.html
插件市场https://ext.dcloud.net.cn/plugin?name=uni-collapse
-->
<template>
<view class="container">
<uni-card is-full :is-shadow="false">
<text class="uni-h6">折叠面板组件用于可折叠的内容展示</text>
</uni-card>
<uni-section title="基础用法" type="line" padding>
<view class="example-body">
<uni-collapse>
<uni-collapse-item title="标题1" name="item1">
<text>这是折叠面板的内容1</text>
</uni-collapse-item>
<uni-collapse-item title="标题2" name="item2">
<text>这是折叠面板的内容2</text>
</uni-collapse-item>
<uni-collapse-item title="标题3" name="item3">
<text>这是折叠面板的内容3</text>
</uni-collapse-item>
</uni-collapse>
</view>
</uni-section>
<uni-section title="手风琴模式" type="line" padding>
<view class="example-body">
<uni-collapse :accordion="true">
<uni-collapse-item title="标题1" name="item1">
<text>手风琴模式同时只能展开一个</text>
</uni-collapse-item>
<uni-collapse-item title="标题2" name="item2">
<text>手风琴模式同时只能展开一个</text>
</uni-collapse-item>
<uni-collapse-item title="标题3" name="item3">
<text>手风琴模式同时只能展开一个</text>
</uni-collapse-item>
</uni-collapse>
</view>
</uni-section>
<uni-section title="默认展开" type="line" padding>
<view class="example-body">
<uni-collapse>
<uni-collapse-item title="默认展开" name="item1" :open="true">
<text>这个面板默认展开</text>
</uni-collapse-item>
<uni-collapse-item title="默认收起" name="item2">
<text>这个面板默认收起</text>
</uni-collapse-item>
</uni-collapse>
</view>
</uni-section>
<uni-section title="禁用状态" type="line" padding>
<view class="example-body">
<uni-collapse>
<uni-collapse-item title="正常状态" name="item1">
<text>可以展开</text>
</uni-collapse-item>
<uni-collapse-item title="禁用状态" name="item2" :disabled="true">
<text>无法展开</text>
</uni-collapse-item>
</uni-collapse>
</view>
</uni-section>
<uni-section title="事件监听" type="line" padding>
<view class="example-body">
<uni-collapse @change="onChange">
<uni-collapse-item title="标题1" name="item1">
<text>点击展开/收起会触发事件</text>
</uni-collapse-item>
<uni-collapse-item title="标题2" name="item2">
<text>点击展开/收起会触发事件</text>
</uni-collapse-item>
</uni-collapse>
<text class="result-text">当前展开项{{ activeNames.join(', ') || '无' }}</text>
</view>
</uni-section>
</view>
</template>
<script>
export default {
data() {
return {
activeNames: []
}
},
methods: {
onChange(e) {
console.log('折叠面板状态改变:', e)
this.activeNames = e
uni.showToast({
title: `展开项:${e.join(', ')}`,
icon: 'none'
})
}
}
}
</script>
<style lang="scss">
.container {
padding: 10px;
}
.example-body {
margin-bottom: 20px;
}
.result-text {
margin-top: 10px;
font-size: 14px;
color: #333;
}
</style>
@@ -0,0 +1,93 @@
<!--
组合框 组件示例
官方文档https://uniapp.dcloud.net.cn/component/uniui/uni-combox.html
插件市场https://ext.dcloud.net.cn/plugin?name=uni-combox
-->
<template>
<view class="container">
<uni-card is-full :is-shadow="false">
<text class="uni-h6">组合框组件用于输入和选择的组合</text>
</uni-card>
<uni-section title="基础用法" type="line" padding>
<view class="example-body">
<uni-combox :candidates="candidates1" v-model="value1" placeholder="请输入或选择" />
<text class="result-text">当前值{{ value1 }}</text>
</view>
</uni-section>
<uni-section title="自定义候选列表" type="line" padding>
<view class="example-body">
<uni-combox :candidates="candidates2" v-model="value2" placeholder="请输入或选择" />
<text class="result-text">当前值{{ value2 }}</text>
</view>
</uni-section>
<uni-section title="禁用状态" type="line" padding>
<view class="example-body">
<uni-combox :candidates="candidates1" v-model="value3" placeholder="禁用状态" :disabled="true" />
</view>
</uni-section>
<uni-section title="只读状态" type="line" padding>
<view class="example-body">
<uni-combox :candidates="candidates1" v-model="value4" placeholder="只读状态" :readonly="true" />
</view>
</uni-section>
<uni-section title="事件监听" type="line" padding>
<view class="example-body">
<uni-combox :candidates="candidates1" v-model="value5" placeholder="请输入或选择" @input="onInput" @select="onSelect" />
<text class="result-text">当前值{{ value5 }}</text>
</view>
</uni-section>
</view>
</template>
<script>
export default {
data() {
return {
value1: '',
value2: '',
value3: '禁用内容',
value4: '只读内容',
value5: '',
candidates1: ['选项1', '选项2', '选项3', '选项4', '选项5'],
candidates2: ['北京', '上海', '广州', '深圳', '杭州', '成都']
}
},
methods: {
onInput(e) {
console.log('输入:', e)
},
onSelect(e) {
console.log('选择:', e)
uni.showToast({
title: `选择了:${e}`,
icon: 'none'
})
}
}
}
</script>
<style lang="scss">
.container {
padding: 10px;
}
.example-body {
display: flex;
flex-direction: column;
gap: 15px;
}
.result-text {
font-size: 14px;
color: #333;
margin-top: 10px;
}
</style>

Some files were not shown because too many files have changed in this diff Show More