目录
UniApp 获取系统信息
获取系统信息的基本方法
UniApp 提供了 uni.getSystemInfo
和 uni.getSystemInfoSync
API,用于获取设备系统信息。前者是异步方法,后者是同步方法。
1.异步方法示例:
uni.getSystemInfo({
success: (res) => {
console.log('系统信息:', res);
},
fail: (err) => {
console.log('获取失败:', err);
}
});
2.同步方法示例:
try {
const res = uni.getSystemInfoSync();
console.log('系统信息:', res);
} catch (err) {
console.log('获取失败:', err);
}
返回的系统信息字段
两种方法返回的对象包含以下常用字段:
brand
:设备品牌model
:设备型号pixelRatio
:设备像素比screenWidth
:屏幕宽度(单位px)screenHeight
:屏幕高度(单位px)windowWidth
:可使用窗口宽度windowHeight
:可使用窗口高度statusBarHeight
:状态栏高度platform
:客户端平台language
:应用设置的语言version
:操作系统版本system
:操作系统及版本fontSizeSetting
:用户设置的字体大小
获取特定平台信息
如需针对特定平台获取信息,可检查 platform
字段:
const res = uni.getSystemInfoSync();
if (res.platform === 'android') {
console.log('当前是Android设备');
} else if (res.platform === 'ios') {
console.log('当前是iOS设备');
}
响应式适配方案
结合系统信息实现响应式布局:
const systemInfo = uni.getSystemInfoSync();
const windowWidth = systemInfo.windowWidth;
const designWidth = 750; // 设计稿宽度
// rpx转换公式
function px2rpx(px) {
return (750 / windowWidth) * px;
}
注意事项
同步方法会阻塞JS线程直到返回结果,建议在非关键路径使用异步方法。不同平台返回的字段可能略有差异,开发时应做好兼容性处理。
UniApp 中如何实现数据绑定
v-model
双向数据绑定
使用 v-model
指令在表单元素上实现双向绑定:
<input v-model="message" placeholder="输入内容" />t
<text>当前内容:{{message}}</text>
脚本部分:
export default {
data() {
return {
message: ''
}
}
}
{{}}单向数据绑定
使用 Mustache 语法(双大括号)进行文本插值:
<view>{{ greeting }} World!</view>
脚本部分:
export default {
data() {
return {
greeting: 'Hello'
}
}
}
v-bind
属性绑定
使用 v-bind
指令或简写 :
绑定元素属性:
<image :src="imgUrl"></image>
脚本部分:
export default {
data() {
return {
imgUrl: '/static/logo.png'
}
}
}
v-if/ v-show
条件渲染
<view v-if="showContent">显示内容</view>
<view v-show="isVisible">可见内容</view>
v-for
列表渲染
<view v-for="(item, index) in items" :key="index">
{{ index }} - {{ item.text }}
</view>
脚本部分:
export default {
data() {
return {
items: [
{ text: '项目1' },
{ text: '项目2' }
]
}
}
}
computed
计算属性
export default {
data() {
return {
firstName: '张',
lastName: '三'
}
},
computed: {
fullName() {
return this.firstName + this.lastName
}
}
}
v-on
指令或简写 @
事件绑定
<button @click="handleClick">点击</button>
脚本部分:
export default {
methods: {
handleClick() {
console.log('按钮被点击')
}
}
}
注意事项
- 数据绑定仅针对 data 中声明的属性
- 数组和对象的变更需要使用 Vue.set 方法或数组的变更方法
- 避免在模板中使用复杂表达式,应使用计算属性
- 在自定义组件上使用 v-model 需要组件内部处理 value 属性和 input 事件
不同小程序平台的 UI 差异
使用跨平台开发框架
Taro、Uni-app、Chameleon等框架支持一套代码多端适配。通过条件编译或样式隔离处理平台差异。例如在Taro中可使用process.env.TARO_ENV
判断环境,针对性调整样式或逻辑:
if (process.env.TARO_ENV === 'weapp') {
// 微信小程序特定样式
} else if (process.env.TARO_ENV === 'alipay') {
// 支付宝适配代码
}
设计弹性布局与组件
采用Flex/Grid布局确保元素自适应。定义全局样式变量(如主色、间距),通过CSS变量或预处理器(Sass/Less)实现主题切换。
动态加载平台资源
将平台专属图片、文案等资源分目录存放,运行时动态拼接路径。
assets/
├── weapp/
├── alipay/
└── toutiao/
代码中通过环境变量引用对应资源:
const iconPath = `/assets/${platform}/home-icon.png`;
统一接口封装
各平台API调用方式差异(如微信的wx.request
与支付宝的my.request
),可通过适配器模式封装统一接口。
const request = (options) => {
if (typeof wx !== 'undefined') {
return wx.request(options);
} else if (typeof my !== 'undefined') {
return my.request(options);
}
};
条件编译样式
/* 条件编译样式 */
#ifdef MP-WEIXIN
button { padding: 10px; }
#endif
UniApp 的组件库有哪些推荐?如何自定义组件
UniApp 常用组件库推荐
1.官方组件库
UniApp 内置了基础组件(如 view
、button
、input
等),覆盖了大部分基础功能,可直接通过 uni-
前缀使用。
2.第三方组件库
uView UI
- 多平台兼容(H5、小程序、App),提供丰富的组件(表单、弹窗、布局等)。
- 支持主题定制,文档详细,适合快速开发。
- 安装方式:通过 npm 或直接下载导入。
ColorUI
- 注重视觉效果的组件库,提供动画和个性化样式。
- 适合需要高定制化界面的项目,但功能组件较少。
ThorUI
- 轻量级组件库,包含常用业务组件(如日历、级联选择器)。
- 支持按需引入,性能优化较好。
FirstUI
- 强调跨平台一致性,提供企业级组件(如图表、下拉刷新)。
- 需付费购买部分高级功能。
自定义组件方法
1.创建组件文件
在 components
目录下新建 .vue
文件
<template>
<button class="custom-btn" @click="handleClick">{{ text }}</button>
</template>
<script>
export default {
props: {
text: {
type: String,
default: '按钮'
}
},
methods: {
handleClick() {
this.$emit('click');
}
}
}
</script>
<style>
.custom-btn {
background-color: #007AFF;
color: white;
}
</style>
2.全局/局部注册组件
- 全局注册:在
main.js
中引入并注册:import MyButton from '@/components/my-button.vue'; Vue.component('my-button', MyButton);
- 局部注册:在页面中通过
components
选项引入:<script> import MyButton from '@/components/my-button.vue'; export default { components: { MyButton } } </script>
3.使用组件
在页面中直接调用组件:
<template>
<my-button text="点击" @click="onButtonClick" />
</template>
UniApp 的跨平台存储
本地存储(LocalStorage)
UniApp 支持 uni.setStorage
和 uni.getStorage
等 API,兼容小程序和 H5 平台。
// 存储数据
uni.setStorage({
key: 'key_name',
data: 'value',
success: function() {
console.log('存储成功');
}
});
// 读取数据
uni.getStorage({
key: 'key_name',
success: function(res) {
console.log(res.data);
}
});
文件系统存储
通过 uni.saveFile
和 uni.getFileSystemManager
实现文件读写,适用于需要持久化文件的场景。
// 写入文件
uni.getFileSystemManager().writeFile({
filePath: 'path/to/file',
data: 'content',
encoding: 'utf8',
success: () => console.log('写入成功')
});
// 读取文件
uni.getFileSystemManager().readFile({
filePath: 'path/to/file',
encoding: 'utf8',
success: res => console.log(res.data)
});
全局变量管理
对于临时数据或状态共享,可使用 globalData
或 Vuex 状态管理。
// 在 App.vue 中定义全局变量
export default {
globalData: {
userInfo: null
}
};
// 使用时获取
const app = getApp();
console.log(app.globalData.userInfo);
第三方存储服务
集成云开发(如 UniCloud)或第三方服务(如 Firebase),实现跨平台数据同步。
// UniCloud 示例
const db = uniCloud.database();
db.collection('users').get().then(res => {
console.log(res.data);
});
UniApp 如何处理网络请求
get请求
uni.request({
url: 'https://example.com/api/data',
method: 'GET',
data: {
key: 'value'
},
header: {
'Content-Type': 'application/json'
},
success: (res) => {
console.log('请求成功:', res.data);
},
fail: (err) => {
console.error('请求失败:', err);
}
});
post 请求
uni.request({
url: 'https://example.com/api/post', // 接口地址
method: 'POST', // 请求方法
data: { // 请求参数
username: 'admin',
password: '123456'
},
header: { // 请求头
'Content-Type': 'application/json' // 根据后端要求设置
},
success: (res) => { // 请求成功回调
console.log('请求成功:', res.data);
},
fail: (err) => { // 请求失败回调
console.error('请求失败:', err);
},
complete: () => { // 请求完成回调(无论成功失败)
uni.hideLoading(); // 示例:关闭加载动画
}
});
封装网络请求工具
创建一个 http.js
文件
const BASE_URL = 'https://example.com/api';
function request(options) {
return new Promise((resolve, reject) => {
uni.request({
url: BASE_URL + options.url,
method: options.method || 'GET',
data: options.data || {},
header: options.header || {
'Content-Type': 'application/json'
},
success: (res) => {
if (res.statusCode === 200) {
resolve(res.data);
} else {
reject(res);
}
},
fail: (err) => {
reject(err);
}
});
});
}
export default request;
使用时可以按需调用:
import request from './http.js';
request({
url: '/user',
method: 'POST',
data: { name: 'John' }
}).then(res => {
console.log('请求结果:', res);
}).catch(err => {
console.error('请求错误:', err);
});
处理请求拦截和响应拦截
如果需要统一处理请求前的参数或响应后的数据,可以扩展封装逻辑
const BASE_URL = 'https://example.com/api';
function request(options) {
// 请求拦截
options.url = BASE_URL + options.url;
options.header = {
...options.header,
'Authorization': uni.getStorageSync('token')
};
return new Promise((resolve, reject) => {
uni.request({
...options,
success: (res) => {
// 响应拦截
if (res.statusCode === 200) {
resolve(res.data);
} else if (res.statusCode === 401) {
uni.navigateTo({ url: '/pages/login' });
reject(res);
} else {
reject(res);
}
},
fail: (err) => {
reject(err);
}
});
});
}
使用第三方库
如果需要更强大的功能(如自动重试、缓存等),可以使用第三方库如 axios
结合适配器。在 UniApp 中,可以通过 axios-miniprogram-adapter
实现:
import axios from 'axios';
import adapter from 'axios-miniprogram-adapter';
axios.defaults.adapter = adapter;
axios.get('https://example.com/api/data')
.then(res => {
console.log(res.data);
})
.catch(err => {
console.error(err);
});
上传和下载文件
UniApp 提供了 uni.uploadFile
和 uni.downloadFile
来处理文件操作:
// 文件上传
uni.uploadFile({
url: 'https://example.com/api/upload',
filePath: tempFilePath,
name: 'file',
success: (res) => {
console.log('上传成功:', res.data);
}
});
// 文件下载
uni.downloadFile({
url: 'https://example.com/file.pdf',
success: (res) => {
if (res.statusCode === 200) {
console.log('下载完成:', res.tempFilePath);
}
}
});
UniApp 的页面传参
通过 URL 传参
在跳转页面时,直接在 URL 后面拼接参数。目标页面通过 onLoad
生命周期函数接收参数。
// 页面A跳转并传参
uni.navigateTo({
url: '/pages/pageB/pageB?id=123&name=test'
});
// 页面B接收参数
export default {
onLoad(options) {
console.log(options.id); // 输出123
console.log(options.name); // 输出test
}
}
使用全局变量
通过 getApp().globalData
设置全局变量,在不同页面之间共享数据。
// app.vue中定义全局变量
globalData: {
userInfo: null
}
// 页面A设置全局变量
getApp().globalData.userInfo = { id: 123, name: 'test' };
// 页面B获取全局变量
onLoad() {
const userInfo = getApp().globalData.userInfo;
console.log(userInfo);
}
使用 Vuex 状态管理
适用于复杂应用,通过 Vuex 集中管理状态,实现跨页面数据共享。
// store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment(state, payload) {
state.count += payload.amount
}
}
})
export default store
// 页面A修改状态
this.$store.commit('increment', { amount: 10 });
// 页面B获取状态
computed: {
count() {
return this.$store.state.count;
}
}
通过事件总线传参
创建一个 Vue 实例作为事件总线,通过事件触发和监听实现传参。
// eventBus.js
import Vue from 'vue'
export const EventBus = new Vue()
// 页面A发送事件
EventBus.$emit('dataEvent', { id: 123, name: 'test' });
// 页面B监听事件
EventBus.$on('dataEvent', data => {
console.log(data.id, data.name);
});
使用本地存储
通过 uni.setStorage
和 uni.getStorage
将数据存储在本地,适合需要持久化的数据。
// 页面A存储数据
uni.setStorage({
key: 'userInfo',
data: { id: 123, name: 'test' }
});
// 页面B获取数据
uni.getStorage({
key: 'userInfo',
success: res => {
console.log(res.data);
}
});
下拉刷新和上拉加载
下拉刷新实现方法
在uniapp中实现下拉刷新功能,需要使用onPullDownRefresh
生命周期函数和uni.stopPullDownRefresh
方法。在页面的pages.json
中需要先开启下拉刷新配置:
{
"path": "pages/index/index",
"style": {
"enablePullDownRefresh": true
}
}
在页面中监听下拉刷新事件:
export default {
onPullDownRefresh() {
console.log('下拉刷新触发');
// 模拟请求数据
setTimeout(() => {
uni.stopPullDownRefresh();
}, 1000);
}
}
上拉加载实现方法
上拉加载通过onReachBottom
生命周期函数实现,通常配合分页功能使用:
export default {
data() {
return {
page: 1,
pageSize: 10,
list: [],
noMore: false
}
},
onReachBottom() {
if(this.noMore) return;
this.page++;
this.loadMoreData();
},
methods: {
async loadMoreData() {
const res = await api.getList({
page: this.page,
pageSize: this.pageSize
});
this.list = [...this.list, ...res.data];
if(res.data.length < this.pageSize) {
this.noMore = true;
}
}
}
}
自定义样式优化
可以使用uni.setBackgroundTextStyle
和uni.setBackgroundColor
修改下拉刷新样式:
onPullDownRefresh() {
uni.setBackgroundTextStyle({
textStyle: 'dark' // 下拉箭头和文字颜色
});
uni.setBackgroundColor({
backgroundColor: '#f8f8f8' // 背景颜色
});
// 业务逻辑
}
注意事项
下拉刷新和上拉加载行为在iOS和Android上表现略有差异,需要测试不同平台的表现。在自定义组件中使用时,需要确保组件高度足够触发上拉加载。
对于复杂列表,建议使用mescroll-uni等第三方库,它们提供了更完善的分页加载解决方案:
import MescrollUni from 'mescroll-uni'
export default {
components: { MescrollUni },
data() {
return {
mescroll: null
}
},
methods: {
mescrollInit(mescroll) {
this.mescroll = mescroll;
},
downCallback() {
// 下拉刷新回调
},
upCallback() {
// 上拉加载回调
}
}
}
UniApp 如何支持国际化
使用 vue-i18n 插件
在 UniApp 中可以通过集成 vue-i18n
插件实现国际化。需要安装 vue-i18n
并配置多语言文件。
安装依赖:
npm install vue-i18n --save
创建语言文件(如 lang/en.js
和 lang/zh-CN.js
):
// lang/en.js
export default {
welcome: 'Welcome',
button: {
confirm: 'Confirm'
}
};
// lang/zh-CN.js
export default {
welcome: '欢迎',
button: {
confirm: '确认'
}
};
在 main.js
中配置 vue-i18n
:
import Vue from 'vue'
import App from './App'
import VueI18n from 'vue-i18n'
import en from './lang/en'
import zh from './lang/zh-CN'
Vue.use(VueI18n)
const i18n = new VueI18n({
locale: 'zh-CN', // 默认语言
messages: {
'en': en,
'zh-CN': zh
}
})
const app = new Vue({
i18n,
...App
})
app.$mount()
在页面中使用:
<template>
<view>
<text>{{ $t('welcome') }}</text>
<button>{{ $t('button.confirm') }}</button>
</view>
</template>
动态切换语言
通过修改 locale
实现语言切换:
this.$i18n.locale = 'en'; // 切换为英文
UniApp 内置国际化
UniApp 内置了部分国际化支持,如日期、时间格式。可以通过 uni.getLocale()
和 uni.setLocale()
获取或设置系统语言。
// 获取当前语言
const locale = uni.getLocale();
// 设置语言
uni.setLocale('en');
多语言文件按需加载
为优化性能,可以按需加载语言文件:
async function loadLocale(lang) {
const messages = await import(`./lang/${lang}.js`);
i18n.setLocaleMessage(lang, messages.default);
}
UniApp 实现动画效果
使用 CSS 动画
在 UniApp 中,可以通过 CSS 的 transition
或 animation
属性实现基础的动画效果。transition
适用于简单的属性变化(如颜色、大小、位置等),而 animation
可以定义更复杂的关键帧动画。
/* transition 示例 */
.box {
width: 100px;
height: 100px;
background: blue;
transition: all 0.3s ease;
}
.box:hover {
width: 200px;
background: red;
}
/* animation 示例 */
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
.fade-in {
animation: fadeIn 1s ease-in-out;
}
使用 UniApp 动画 API
UniApp 提供了 uni.createAnimation
API,用于通过 JavaScript 动态控制动画。该 API 支持平移、缩放、旋转等效果,并支持链式调用。
const animation = uni.createAnimation({
duration: 1000,
timingFunction: 'ease',
});
// 定义动画
animation.translateX(100).rotate(45).step();
// 应用到组件
this.setData({
animationData: animation.export()
});
在模板中使用:
<view :animation="animationData" class="box"></view>
使用第三方动画库
可以引入第三方动画库(如 animate.css
)快速实现预设动画效果。先将库文件放入 static
目录,再在页面中引入。
<!-- 引入 animate.css -->
<link rel="stylesheet" href="/static/animate.css">
<!-- 使用预设动画类 -->
<view class="animate__animated animate__bounce">弹跳效果</view>
使用 Vue 过渡效果
通过 Vue 的 <transition>
组件实现元素进入/离开的过渡动画。需结合 CSS 定义过渡效果。
<transition name="fade">
<view v-if="show">淡入淡出的内容</view>
</transition>
.fade-enter-active, .fade-leave-active {
transition: opacity 0.5s;
}
.fade-enter, .fade-leave-to {
opacity: 0;
}
性能优化建议
- 避免过多使用
box-shadow
和filter
等高耗能属性。 - 使用
transform
和opacity
实现动画,这些属性不会触发重排。 - 对复杂动画启用硬件加速,例如添加
transform: translateZ(0)
。 - 小程序端需注意动画层级问题,必要时使用
z-index
调整