从Vue3到UniApp:从入门到实战的完美指南
本文专为有Vue3基础的开发者设计,将带领你快速掌握UniApp跨平台开发,无需额外学习成本,让你的Vue3技能直接变现。
一、为什么选择UniApp?------ 你的Vue3技能可以跨平台使用
UniApp是基于Vue.js的跨平台开发框架,由DCloud(数字天堂)公司开发。它最大的优势是:
✅ 一套代码,多端发布:iOS、Android、H5、微信小程序、支付宝小程序、百度小程序、抖音小程序、QQ小程序、快手小程序、京东小程序、华为快应用、360小程序、飞书小程序、钉钉小程序、小红书小程序、鸿蒙元服务
✅ 学习成本极低:如果你已经会Vue3,几乎不需要额外学习
✅ 性能优秀:uni-ui是性能标杆,比其他框架更流畅
✅ 生态完善:有丰富的组件库(uni-ui)、插件市场、社区支持
✅ 官方支持:DCloud是HTML5中国产业联盟发起单位,拥有900万开发者、数百万应用
二、环境搭建:3分钟快速起步
1. 安装HBuilderX(官方推荐IDE)
- 下载地址:HBuilderX官网
- 为什么用HBuilderX?它专为UniApp设计,提供智能提示、调试、预览等功能,比VSCode更高效
- 安装完成后,打开HBuilderX
2. 创建第一个UniApp项目
- 打开HBuilderX → 点击"文件" → "新建" → "项目"
- 选择"uni-app"模板
- 填写项目名称(例如:myuniapp)
- 选择"默认模板"(这是最简单的模板,适合新手)
- 点击"创建"
3. 项目结构解析(新手必看)
myuniapp/
├── pages/ # 页面目录(每个页面有独立的.vue文件)
│ ├── index/ # 首页
│ │ ├── index.vue # 首页的Vue文件
│ │ └── index.json # 首页配置文件(如标题、导航栏等)
│ └── other/ # 其他页面
├── static/ # 静态资源(图片、音频等)
├── App.vue # 应用入口文件(全局配置、生命周期)
├── main.js # 应用入口JS文件
├── manifest.json # 应用配置文件(应用名称、图标等)
└── pages.json # 页面路由和全局配置
三、Vue3与UniApp的完美结合
1. 组合式API使用(和Vue3完全一致)
UniApp完全支持Vue3的组合式API,你不需要改变任何习惯:
vue
<script setup>
import { ref, onMounted } from 'vue'
// 响应式数据
const count = ref(0)
const message = ref('Hello UniApp!')
// 组件挂载时执行
onMounted(() => {
console.log('组件已挂载')
})
// 方法
function increment() {
count.value++
}
function updateMessage() {
message.value = 'UniApp太棒了!'
}
</script>
<template>
<view class="container">
<text class="title">UniApp示例</text>
<view class="counter">
<text>点击次数: {{ count }}</text>
<button @click="increment">点击增加</button>
</view>
<view class="message">
<text>{{ message }}</text>
<button @click="updateMessage">更新消息</button>
</view>
</view>
</template>
<style>
.container {
display: flex;
flex-direction: column;
align-items: center;
padding: 40rpx;
}
.title {
font-size: 40rpx;
color: #333;
margin-bottom: 30rpx;
}
.counter, .message {
width: 100%;
margin: 20rpx 0;
padding: 20rpx;
border: 1px solid #eee;
border-radius: 10rpx;
}
button {
margin-top: 15rpx;
background-color: #007AFF;
color: white;
border-radius: 5rpx;
padding: 10rpx 20rpx;
}
</style>
2. 与Vue3的区别(只需注意这些)
| Vue3特性 | UniApp中使用 | 说明 |
|---|---|---|
ref/reactive |
直接使用 | 完全兼容 |
setup函数 |
直接使用 | 完全兼容 |
| 组件注册 | 通过components选项 |
与Vue3一致 |
| 路由 | 通过pages.json配置 |
需要额外配置 |
| API调用 | 通过uni.xxx |
需要了解uni-app的API |
四、核心概念详解(新手必看)
1. 页面与路由
页面结构
在pages/index/index.vue中:
vue
<script setup>
// 页面生命周期
import { onLoad } from '@dcloudio/uni-app'
onLoad(() => {
console.log('首页加载完成')
})
</script>
<template>
<view class="page">
<text>这是首页</text>
</view>
</template>
路由配置
在pages.json中配置:
json
{
"pages": [
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "首页"
}
},
{
"path": "pages/user/user",
"style": {
"navigationBarTitleText": "用户中心"
}
}
],
"globalStyle": {
"navigationBarBackgroundColor": "#ffffff",
"navigationBarTitleText": "我的应用",
"navigationBarTextStyle": "black"
}
}
页面跳转
javascript
// 保留当前页面,跳转到新页面
uni.navigateTo({
url: '/pages/user/user'
})
// 关闭当前页面,跳转到新页面
uni.redirectTo({
url: '/pages/user/user'
})
// 返回上一页面
uni.navigateBack()
2. 生命周期
应用生命周期(App.vue中)
vue
<script setup>
import { onLaunch, onShow, onHide } from '@dcloudio/uni-app'
onLaunch(() => {
console.log('应用初始化完成')
})
onShow(() => {
console.log('应用显示')
})
onHide(() => {
console.log('应用隐藏')
})
</script>
页面生命周期
vue
<script setup>
import { onLoad, onShow, onReady, onHide, onUnload } from '@dcloudio/uni-app'
onLoad((options) => {
console.log('页面加载', options)
// 从上一个页面传递过来的参数
})
onShow(() => {
console.log('页面显示')
})
onReady(() => {
console.log('页面初次渲染完成')
})
onHide(() => {
console.log('页面隐藏')
})
onUnload(() => {
console.log('页面卸载')
})
</script>
五、UI开发:使用uni-ui组件库
1. 什么是uni-ui?
uni-ui是DCloud官方提供的跨端UI组件库,是uni-app的官方推荐UI库,有以下特点:
✅ 高性能 :自动diff更新数据,避免setData性能问题 ✅ 全端支持 :支持所有uni-app目标平台 ✅ 风格扩展 :支持uni.scss,可以自定义主题 ✅ 与uniCloud协作:自动集成uni统计,实现免打点
2. 安装uni-ui
在HBuilderX中,创建项目时选择"uni-ui项目"模板,或手动安装:
bash
npm install @dcloudio/uni-ui
3. 使用uni-ui组件
在App.vue中全局引入:
vue
<script setup>
import { onLaunch } from '@dcloudio/uni-app'
import 'uni-ui/lib/uni-ui.css' // 引入样式
// 全局注册uni-ui组件
import { uniBadge, uniButton } from '@dcloudio/uni-ui'
const components = [uniBadge, uniButton]
components.forEach(component => {
uniApp.use(component)
})
</script>
使用示例:按钮和数字角标
vue
<template>
<view class="container">
<uni-button type="primary" @click="handleClick">点击我</uni-button>
<uni-badge text="新" type="error"></uni-badge>
<uni-badge text="5" type="success"></uni-badge>
</view>
</template>
4. 常用uni-ui组件列表
| 组件 | 说明 | 使用示例 |
|---|---|---|
uni-button |
按钮 | <uni-button type="primary">按钮</uni-button> |
uni-badge |
数字角标 | <uni-badge text="5" type="success"></uni-badge> |
uni-card |
卡片 | <uni-card title="卡片标题" extra="更多">内容</uni-card> |
uni-list |
列表 | <uni-list><uni-list-item title="列表项"></uni-list-item></uni-list> |
uni-search-bar |
搜索栏 | <uni-search-bar @confirm="search"></uni-search-bar> |
uni-nav-bar |
导航栏 | <uni-nav-bar title="页面标题"></uni-nav-bar> |
六、API调用:uni-app的"魔法"功能
1. 网络请求
javascript
// GET请求
uni.request({
url: 'https://api.example.com/data',
method: 'GET',
success: (res) => {
console.log('请求成功', res.data)
},
fail: (err) => {
console.error('请求失败', err)
}
})
// POST请求
uni.request({
url: 'https://api.example.com/submit',
method: 'POST',
data: { name: '张三', age: 25 },
header: {
'Content-Type': 'application/json'
},
success: (res) => {
console.log('提交成功', res.data)
}
})
2. 数据存储
javascript
// 本地存储(异步)
uni.setStorage({
key: 'userToken',
data: 'abc123xyz',
success: () => {
console.log('存储成功')
}
})
// 本地存储(同步,推荐在setup中使用)
try {
uni.setStorageSync('userToken', 'abc123xyz')
console.log('存储成功')
} catch (e) {
console.error('存储失败', e)
}
// 读取数据
const token = uni.getStorageSync('userToken')
console.log('获取到的token:', token)
3. 设备信息
javascript
uni.getSystemInfo({
success: (res) => {
console.log('设备信息:', res)
console.log('平台:', res.platform) // 'ios'/'android'/'h5'
console.log('屏幕宽度:', res.windowWidth + 'rpx')
console.log('系统版本:', res.system)
}
})
七、状态管理:Pinia
1. 安装Pinia
bash
npm install pinia @pinia/nuxt
2. 创建store
在stores/counter.js中:
javascript
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', {
state: () => ({
count: 0,
name: 'UniApp'
}),
actions: {
increment() {
this.count++
},
setName(newName) {
this.name = newName
}
}
})
3. 配置Pinia(main.js)
javascript
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
const pinia = createPinia()
const app = createApp(App)
app.use(pinia)
app.mount('#app')
4. 在组件中使用
vue
<script setup>
import { useCounterStore } from '@/stores/counter'
import { storeToRefs } from 'pinia'
const counterStore = useCounterStore()
const { count, name } = storeToRefs(counterStore) // 保持响应式
function updateName() {
counterStore.setName('UniApp Pro')
}
</script>
<template>
<view class="container">
<text>计数: {{ count }}</text>
<button @click="counterStore.increment()">+1</button>
<text>名称: {{ name }}</text>
<button @click="updateName()">更新名称</button>
</view>
</template>
八、调试与发布
1. 调试方法
| 平台 | 调试方法 |
|---|---|
| H5 | 直接在浏览器中打开,使用浏览器开发者工具 |
| 小程序 | 使用对应平台的开发者工具(微信开发者工具等) |
| App | 使用HBuilderX的"运行到手机/模拟器"功能,或真机调试 |
| 本地测试 | HBuilderX内置的"运行"功能,可直接预览效果 |
2. 发布流程
- 打开HBuilderX
- 点击"发行" → 选择目标平台(如微信小程序、App等)
- 按照向导完成配置
- 生成发布包
- 提交到对应平台审核
九、实战项目:简易待办事项应用
让我们用所学知识,创建一个简单的待办事项应用:
1. 创建页面
- 在
pages目录下创建todo文件夹 - 创建
todo.vue和todo.json
2. 编写待办事项组件
vue
<script setup>
import { ref, onMounted } from 'vue'
import { useCounterStore } from '@/stores/counter'
const todos = ref([])
const newTodo = ref('')
const counterStore = useCounterStore()
onMounted(() => {
// 从本地存储加载待办事项
const savedTodos = uni.getStorageSync('todos')
if (savedTodos) {
todos.value = JSON.parse(savedTodos)
}
})
const addTodo = () => {
if (newTodo.value.trim() !== '') {
todos.value.push({
id: Date.now(),
text: newTodo.value,
completed: false
})
newTodo.value = ''
saveTodos()
}
}
const toggleTodo = (id) => {
const todo = todos.value.find(t => t.id === id)
if (todo) {
todo.completed = !todo.completed
saveTodos()
}
}
const removeTodo = (id) => {
todos.value = todos.value.filter(t => t.id !== id)
saveTodos()
}
const saveTodos = () => {
uni.setStorageSync('todos', JSON.stringify(todos.value))
}
const clearCompleted = () => {
todos.value = todos.value.filter(t => !t.completed)
saveTodos()
}
</script>
<template>
<view class="container">
<uni-nav-bar title="待办事项"></uni-nav-bar>
<view class="input-area">
<input
v-model="newTodo"
placeholder="添加新待办事项"
class="input"
/>
<button @click="addTodo" class="add-btn">添加</button>
</view>
<uni-list>
<uni-list-item
v-for="todo in todos"
:key="todo.id"
:title="todo.text"
:rightText="todo.completed ? '已完成' : ''"
:showExtraIcon="true"
:extraIcon="{ type: todo.completed ? 'checkmarkempty' : 'close' }"
@click="toggleTodo(todo.id)"
/>
</uni-list>
<view v-if="todos.length > 0" class="actions">
<button @click="clearCompleted" class="clear-btn">清除已完成</button>
</view>
<view v-if="todos.length === 0" class="empty">
<text>暂无待办事项</text>
</view>
</view>
</template>
<style>
.container {
padding: 20rpx;
}
.input-area {
display: flex;
margin-bottom: 20rpx;
}
.input {
flex: 1;
padding: 12rpx 15rpx;
border: 1px solid #eee;
border-radius: 4rpx;
margin-right: 10rpx;
}
.add-btn {
background-color: #007AFF;
color: white;
padding: 0 20rpx;
border-radius: 4rpx;
}
.actions {
margin-top: 20rpx;
display: flex;
justify-content: flex-end;
}
.clear-btn {
background-color: #ff3333;
color: white;
padding: 8rpx 15rpx;
border-radius: 4rpx;
}
.empty {
text-align: center;
color: #999;
margin-top: 40rpx;
}
</style>
3. 配置路由
在pages.json中添加:
json
{
"path": "pages/todo/todo",
"style": {
"navigationBarTitleText": "待办事项"
}
}
4. 添加导航
在pages/index/index.vue中添加跳转按钮:
vue
<template>
<view class="container">
<text class="title">UniApp示例</text>
<uni-button type="primary" @click="navigateToTodo">去待办事项</uni-button>
</view>
</template>
<script setup>
import { uniNavigateTo } from '@dcloudio/uni-app'
const navigateToTodo = () => {
uni.navigateTo({
url: '/pages/todo/todo'
})
}
</script>
十、学习资源推荐
- 官方文档 :https://uniapp.dcloud.net.cn/
- 详细、全面的文档,是学习的最佳起点
- uni-ui组件库 :https://uniapp.dcloud.net.cn/component/uniui/uni-ui.html
- 官方UI组件库,性能优秀,风格统一
- 插件市场 :https://ext.dcloud.net.cn/
- 数千款插件,解决各种功能需求
十一、常见问题解决
Q1: 为什么在H5上显示不正常?
A: 检查是否使用了rpx单位,H5需要使用rpx才能实现响应式。确保样式中使用了rpx,而不是px。
Q2: 如何处理不同平台的差异?
A: 使用条件编译:
vue
<!-- #ifdef MP-WEIXIN -->
<view>微信小程序专属内容</view>
<!-- #endif -->
<!-- #ifdef H5 -->
<view>H5专属内容</view>
<!-- #endif -->
Q3: 如何在uni-app中使用第三方库?
A: 在uni-app中,可以直接使用NPM包,但需要确保它们是轻量级的,且不依赖浏览器环境。
Q4: 为什么我的API在小程序中调用失败?
A: 检查是否配置了合法域名(在小程序后台配置),或者使用了uni.request的url是否是HTTPS。
十二、结语
UniApp是有Vue3基础的开发者跨平台开发的最佳选择。它不是"为了跨平台而跨平台",而是真正地利用了Vue3的优势,让开发者可以专注于业务逻辑,而不是平台差异。
记住这个核心理念:
一套代码,多端发布,但不牺牲平台特性。
现在,你已经掌握了UniApp的基础知识,可以开始开发自己的跨平台应用了。从简单的待办事项应用开始,逐渐增加功能,你会发现UniApp的开发效率远超预期。
下一步行动:
- 安装HBuilderX
- 创建第一个项目
- 按照本教程编写一个简单的应用
- 尝试在不同平台上预览
记住: 你不需要成为UniApp专家,只需要掌握Vue3,就能轻松上手。因为UniApp就是Vue3的跨平台延伸,而不是另一个框架。