目录
前言
在当今多端应用需求激增的时代,开发者为每个平台单独开发应用不仅效率低下,维护成本也极高。Uni-App作为一套使用Vue.js开发全平台应用的框架,让开发者能够一次编写,多端发布,大大提升了开发效率。本文将带您深入Uni-App的基础开发知识,并辅以实用代码示例。
什么是Uni-App?
Uni-App是由DCloud公司推出的跨端开发框架,基于Vue.js生态构建。开发者使用Vue语法编写一套代码,即可编译发布到:
-
iOS和Android原生应用
-
微信、支付宝、百度、字节跳动等主流小程序
-
H5移动网页
-
快应用等平台
Uni-App的核心优势:
-
真正跨平台:一套代码覆盖15个平台
-
性能接近原生:通过weex技术实现原生渲染
-
丰富的插件生态:超过数千款插件支持
-
开发体验好:基于Vue.js,学习曲线平缓
-
活跃的社区:超过百万开发者使用
环境搭建
安装HBuilderX(推荐)
HBuilderX是DCloud官方推出的IDE,内置uni-app开发环境:
-
下载最新版HBuilderX
-
安装后选择"新建项目" → "uni-app" → 选择默认模板
-
运行项目到不同平台:顶部菜单"运行" → 选择目标平台
使用Vue CLI创建项目(适合熟悉命令行的开发者)
# 全局安装vue-cli
npm install -g @vue/cli
# 创建uni-app项目
vue create -p dcloudio/uni-preset-vue my-uni-project
# 进入项目目录并运行
cd my-uni-project
npm run dev:%PLATFORM% # 如 dev:mp-weixin
项目结构详解
├── pages // 所有页面目录
│ ├── index // 首页目录
│ │ ├── index.vue // 首页组件
│ │ └── index.css // 首页样式(可选)
├── static // 静态资源(图片、字体等)
├── components // 可复用组件
├── App.vue // 应用入口组件
├── main.js // 入口文件
├── manifest.json // 应用配置(名称、图标等)
├── pages.json // 页面路由和全局样式配置
└── uni.scss // 全局SCSS变量
基础组件与示例
Uni-App提供了一套跨平台组件,在不同平台有良好表现:
<template>
<view class="container">
<!-- 顶部导航栏 -->
<uni-nav-bar title="欢迎使用Uni-App" />
<!-- 轮播图组件 -->
<swiper :indicator-dots="true" :autoplay="true">
<swiper-item v-for="(item, index) in banners" :key="index">
<image :src="item.image" mode="aspectFill" />
</swiper-item>
</swiper>
<!-- 网格布局 -->
<uni-grid :column="4">
<uni-grid-item v-for="(item, index) in menus" :key="index">
<image :src="item.icon" class="grid-icon" />
<text class="grid-text">{{ item.name }}</text>
</uni-grid-item>
</uni-grid>
<!-- 商品列表 -->
<view class="product-list">
<view v-for="product in products" :key="product.id" class="product-item">
<image :src="product.thumbnail" class="product-image" />
<view class="product-info">
<text class="product-title">{{ product.name }}</text>
<text class="product-price">¥{{ product.price }}</text>
</view>
<button class="buy-btn" @click="addToCart(product)">购买</button>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
banners: [
{ image: '/static/banner1.jpg' },
{ image: '/static/banner2.jpg' },
{ image: '/static/banner3.jpg' }
],
menus: [
{ name: '手机', icon: '/static/phone.png' },
{ name: '电脑', icon: '/static/laptop.png' },
{ name: '耳机', icon: '/static/headphones.png' },
{ name: '智能家居', icon: '/static/smart-home.png' }
],
products: [
{ id: 1, name: '无线蓝牙耳机', price: 299, thumbnail: '/static/earbuds.jpg' },
{ id: 2, name: '机械键盘', price: 459, thumbnail: '/static/keyboard.jpg' },
{ id: 3, name: '智能手表', price: 899, thumbnail: '/static/watch.jpg' }
]
}
},
methods: {
addToCart(product) {
uni.showToast({
title: `已添加${product.name}到购物车`,
icon: 'success'
});
// 实际项目中会调用Vuex存储状态
console.log('添加商品:', product);
}
}
}
</script>
<style scoped>
.container {
padding: 10px;
background-color: #f5f5f5;
}
swiper {
height: 200px;
margin-bottom: 15px;
}
.grid-icon {
width: 40px;
height: 40px;
margin-bottom: 5px;
}
.grid-text {
font-size: 12px;
color: #666;
}
.product-list {
margin-top: 20px;
}
.product-item {
display: flex;
background: white;
border-radius: 8px;
padding: 10px;
margin-bottom: 10px;
align-items: center;
}
.product-image {
width: 80px;
height: 80px;
border-radius: 4px;
margin-right: 15px;
}
.product-info {
flex: 1;
}
.product-title {
font-size: 16px;
font-weight: bold;
display: block;
margin-bottom: 5px;
}
.product-price {
color: #e64340;
font-size: 18px;
}
.buy-btn {
background: linear-gradient(to right, #ff9500, #ff5000);
color: white;
border-radius: 15px;
font-size: 14px;
padding: 0 15px;
height: 30px;
line-height: 30px;
}
</style>
路由与页面跳转
Uni-App使用基于配置的路由系统,在pages.json
中定义:
{
"pages": [
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "首页",
"enablePullDownRefresh": true
}
},
{
"path": "pages/product/detail",
"style": {
"navigationBarTitleText": "商品详情",
"app-plus": {
"titleNView": {
"buttons": [{
"text": "分享",
"fontSize": "16px"
}]
}
}
}
},
{
"path": "pages/cart/index",
"style": {
"navigationBarTitleText": "购物车"
}
}
],
"globalStyle": {
"navigationBarTextStyle": "white",
"navigationBarTitleText": "Uni商城",
"navigationBarBackgroundColor": "#ff5000",
"backgroundColor": "#f5f5f5"
}
}
页面跳转方法:
// 保留当前页面,跳转到新页面
uni.navigateTo({
url: '/pages/product/detail?id=123'
})
// 关闭当前页面,跳转到新页面
uni.redirectTo({
url: '/pages/cart/index'
})
// 返回上一页
uni.navigateBack()
// 跳转到TabBar页面
uni.switchTab({
url: '/pages/category/index'
})
跨平台API调用
Uni-App提供了丰富的API,支持多平台适配:
// 获取系统信息
const systemInfo = uni.getSystemInfoSync();
console.log('设备品牌:', systemInfo.brand);
console.log('屏幕高度:', systemInfo.screenHeight);
// 网络请求
uni.request({
url: 'https://api.example.com/products',
method: 'GET',
data: {
page: 1,
pageSize: 10
},
success: (res) => {
console.log('请求成功:', res.data);
},
fail: (err) => {
console.error('请求失败:', err);
uni.showToast({
title: '网络请求失败',
icon: 'none'
});
}
});
// 本地存储
uni.setStorage({
key: 'userToken',
data: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...',
success: () => {
console.log('存储成功');
}
});
// 获取位置信息
uni.getLocation({
type: 'gcj02',
success: (res) => {
console.log('当前位置:', res.latitude, res.longitude);
},
fail: (err) => {
console.error('获取位置失败:', err);
}
});
// 扫码功能
uni.scanCode({
success: (res) => {
console.log('扫码结果:', res.result);
uni.showModal({
title: '扫码结果',
content: res.result,
showCancel: false
});
}
});
条件编译技巧
Uni-App的条件编译功能让开发者可以针对不同平台编写特定代码:
<template>
<view>
<!-- 通用内容 -->
<text>所有平台可见的内容</text>
<!-- H5平台特有内容 -->
<!-- #ifdef H5 -->
<view class="h5-banner">
<text>仅H5平台显示的广告位</text>
</view>
<!-- #endif -->
<!-- 微信小程序特有功能 -->
<!-- #ifdef MP-WEIXIN -->
<ad unit-id="adunit-xxxxxxxx"></ad>
<!-- #endif -->
<!-- App平台特有组件 -->
<!-- #ifdef APP-PLUS -->
<uni-badge text="New" type="error"></uni-badge>
<!-- #endif -->
</view>
</template>
<script>
export default {
methods: {
share() {
// 平台特定API调用
// #ifdef MP-WEIXIN
wx.shareAppMessage({
title: '分享标题',
path: '/pages/index/index'
});
// #endif
// #ifdef H5
console.log('H5平台的分享逻辑');
// #endif
// #ifdef APP-PLUS
plus.share.sendWithSystem({
content: '分享内容',
href: 'https://example.com'
});
// #endif
}
}
}
</script>
<style>
/* 通用样式 */
.container {
padding: 10px;
}
/* 微信小程序特有样式 */
/* #ifdef MP-WEIXIN */
.container {
padding: 15px;
}
/* #endif */
/* App平台特有样式 */
/* #ifdef APP-PLUS */
.container {
padding-top: 20px;
}
/* #endif */
实用开发技巧
1. 自适应单位
使用rpx
(responsive pixel)单位实现完美适配:
/* 设计稿宽度为750rpx */
.container {
width: 750rpx; /* 等于100%宽度 */
padding: 20rpx;
font-size: 28rpx; /* 约等于14px */
}
.card {
width: 345rpx; /* 在750设计稿中占一半宽度减去间距 */
margin: 10rpx;
border-radius: 16rpx;
}
2. 全局样式管理
在uni.scss
中定义全局变量:
/* 主题色 */
$primary-color: #ff5000;
$secondary-color: #ff9500;
/* 文字色 */
$text-color: #333;
$text-secondary: #666;
$text-light: #999;
/* 间距 */
$spacing-sm: 10px;
$spacing-md: 20px;
$spacing-lg: 30px;
在组件中使用:
@import '@/uni.scss';
.header {
background-color: $primary-color;
color: white;
padding: $spacing-md;
}
.price {
color: $secondary-color;
font-size: 18px;
}
3. 性能优化
// 图片懒加载
<image lazy-load :src="product.image" />
// 使用v-if替代v-show减少初始渲染压力
<view v-if="dataLoaded">...</view>
// 大数据列表使用scroll-view虚拟滚动
<scroll-view scroll-y :enable-back-to-top="true">
<view v-for="item in bigList" :key="item.id">...</view>
</scroll-view>
// 避免频繁setData
// 错误做法
this.list.push(newItem);
this.setData({ list: this.list });
// 正确做法
this.setData({
list: [...this.list, newItem]
});
打包发布流程
小程序发布
-
在HBuilderX中选择"发行"→"小程序-微信"
-
填写小程序AppID
-
生成代码后使用微信开发者工具上传审核
App打包
-
选择"发行"→"原生App-云打包"
-
配置Android证书和iOS描述文件
-
选择需要包含的模块(地图、支付等)
-
提交云端打包,完成后下载安装包
H5发布
-
选择"发行"→"网站-H5手机版"
-
配置网站标题和域名
-
生成的代码在
unpackage/dist/build/h5
-
部署到Nginx、Apache等Web服务器
学习资源推荐
-
Uni-App官方文档 - 最权威的参考资料
-
Uni-App插件市场 - 数千款实用插件
-
DCloud社区 - 开发者问答社区
-
GitHub Uni-App示例项目 - 学习优秀项目结构
结语
Uni-App为开发者提供了强大的跨平台开发能力,通过本文介绍的基础知识和代码示例,您应该已经掌握了Uni-App的核心开发技能。随着不断实践,您将能更高效地开发出高质量的多端应用。
"跨平台开发不是未来,而是当下。掌握Uni-App,让您的应用无处不在。" - Uni-App开发者箴言
开发过程中遇到问题,不妨多查阅官方文档和社区讨论,百万Uni-App开发者是您强大的后盾。祝您在跨平台开发的道路上越走越远!