uniapp基础 (二)
目录
UniApp 获取系统信息
获取系统信息的基本方法
1.异步方法示例:
2.同步方法示例:
返回的系统信息字段
获取特定平台信息
响应式适配方案
注意事项
UniApp 中如何实现数据绑定
v-model双向数据绑定
{{}}单向数据绑定
v-bind 属性绑定
v-if/ v-show条件渲染
v-for列表渲染
computed 计算属性
v-on 指令或简写 @ 事件绑定
注意事项
不同小程序平台的 UI 差异
使用跨平台开发框架
设计弹性布局与组件
动态加载平台资源
统一接口封装
条件编译样式
UniApp 的组件库有哪些推荐?如何自定义组件
UniApp 常用组件库推荐
1.官方组件库
2.第三方组件库
自定义组件方法
1.创建组件文件
2.全局/局部注册组件
3.使用组件
UniApp 的跨平台存储
本地存储(LocalStorage)
文件系统存储
全局变量管理
第三方存储服务
UniApp 如何处理网络请求
get请求
post 请求
封装网络请求工具
处理请求拦截和响应拦截
使用第三方库
上传和下载文件
UniApp 的页面传参
通过 URL 传参
使用全局变量
使用 Vuex 状态管理
通过事件总线传参
使用本地存储
下拉刷新和上拉加载
下拉刷新实现方法
上拉加载实现方法
自定义样式优化
注意事项
UniApp 如何支持国际化
使用 vue-i18n 插件
动态切换语言
UniApp 内置国际化
多语言文件按需加载
UniApp 实现动画效果
使用 CSS 动画
使用 UniApp 动画 API
使用第三方动画库
使用 Vue 过渡效果
性能优化建议
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); // 输出123console.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
调整