在 UniApp 开发中,页面间参数传递是核心功能之一。以下是 8 种常用的传参方式,每种方式都有其适用场景和特点:
一、URL 拼接传参(最常用)
适用场景 :简单数据传递,如 ID、状态值等基础类型数据
实现方式:
javascript
// 发送参数
uni.navigateTo({
url: '/pages/detail/detail?id=123&name=张三'
})
// 接收参数(在目标页面的 onLoad 生命周期中获取)
export default {
onLoad(options) {
console.log(options.id) // 123
console.log(options.name) // "张三"
}
}
特点:
- 参数自动解析为字符串
- 长度受限(URL 最大长度约 2KB)
- 不支持复杂对象(需手动序列化)
二、全局变量传参
适用场景 :跨页面共享数据(如用户信息)
实现方式:
javascript
// app.vue 中定义全局变量
export default {
globalData: {
userInfo: null
}
}
// 页面 A 设置数据
const app = getApp()
app.globalData.userInfo = { id: 1, name: '张三' }
// 页面 B 读取数据
const app = getApp()
console.log(app.globalData.userInfo)
特点:
- 适合共享频繁使用的数据
- 非响应式(需配合事件机制)
- 长期存在可能内存泄漏
三、Vuex 状态管理
适用场景 :复杂应用状态共享
实现方式:
javascript
// store.js
export default new Vuex.Store({
state: {
cartItems: []
},
mutations: {
addToCart(state, item) {
state.cartItems.push(item)
}
}
})
// 页面 A 提交数据
this.$store.commit('addToCart', { id: 101, name: '商品A' })
// 页面 B 获取数据
computed: {
cartItems() {
return this.$store.state.cartItems
}
}
特点:
- 响应式数据流
- 支持调试工具
- 适合中大型项目
四、本地存储传参
适用场景 :持久化数据传递(如登录状态)
实现方式:
javascript
// 页面 A 存储数据
uni.setStorageSync('token', 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9')
// 页面 B 读取数据
const token = uni.getStorageSync('token')
特点:
- 数据持久化(关闭应用仍存在)
- 同步操作可能阻塞渲染
- 容量限制(通常 5-10MB)
五、事件总线(EventBus)
适用场景 :任意组件/页面间通信
实现方式:
javascript
// utils/eventBus.js
export default new Vue()
// 页面 A 发送事件
import eventBus from '@/utils/eventBus'
eventBus.$emit('data-update', { newData: 42 })
// 页面 B 监听事件
export default {
onLoad() {
eventBus.$on('data-update', data => {
console.log('收到数据:', data)
})
},
onUnload() {
eventBus.$off('data-update') // 必须解绑!
}
}
特点:
- 完全解耦的通信方式
- 需手动管理事件监听
- 滥用可能导致"事件地狱"
六、页面通信通道
适用场景 :需要获取前序页面实例的场景
实现方式:
javascript
// 获取前序页面实例
const pages = getCurrentPages()
const prevPage = pages[pages.length - 2] // 上一页
// 直接调用前页方法
prevPage.$vm.updateData({ id: 2024 })
// 目标页面定义方法
methods: {
updateData(data) {
this.data = data
console.log('收到数据:', data)
}
}
特点:
- 可直接操作页面实例
- 破坏封装性(慎用)
- 小程序端最多 10 层页面栈
七、URL 编码复杂对象
适用场景 :需要传递 JSON 对象
实现方式:
javascript
// 发送复杂对象
const product = {
id: 1001,
name: '手机',
specs: { color: '黑色', memory: '256GB' }
}
uni.navigateTo({
url: `/pages/detail/detail?data=${encodeURIComponent(JSON.stringify(product))}`
})
// 接收端解析
onLoad(options) {
const product = JSON.parse(decodeURIComponent(options.data))
console.log(product.specs.color) // "黑色"
}
特点:
- 解决 URL 传对象问题
- 注意特殊字符编码
- 数据量受限
八、uni.emit和uni.emit 和 uni.emit和uni.on
适用场景 :跨页面事件通信(UniApp 2.8.0+)
实现方式:
javascript
// 页面 A 发送事件
uni.$emit('update', { msg: '数据更新' })
// 页面 B 监听事件
export default {
onLoad() {
uni.$on('update', this.handleUpdate)
},
methods: {
handleUpdate(data) {
console.log('收到更新:', data.msg)
}
},
onUnload() {
uni.$off('update', this.handleUpdate) // 必须解绑
}
}
特点:
- 官方提供的全局事件机制
- 需手动管理事件绑定
- 适合简单通知类通信
最佳实践建议
- 简单数据传递:优先使用 URL 传参
- 用户状态管理:Vuex + 本地存储持久化
- 复杂对象传递:URL 编码或全局变量
- 跨级通信:EventBus 或 uni.$emit
- 重要数据传递:始终添加参数校验
javascript
// 参数校验示例
onLoad(options) {
if (!options.id || isNaN(options.id)) {
uni.showToast({ title: '参数错误', icon: 'error' })
uni.navigateBack()
return
}
}
- 内存管理 :在
onUnload
中清理资源
javascript
onUnload() {
// 清除事件监听
eventBus.$off('update')
uni.$off('update')
// 释放大对象
this.largeData = null
}
性能优化技巧
- 大数据传递:使用 ID 传递,目标页面重新请求
- 频繁更新数据:使用 Vuex 响应式更新
- 页面返回刷新:
javascript
// 前页注册刷新方法
onShow() {
if (this.$options.refreshData) {
this.$options.refreshData()
}
}
// 后页触发刷新
const pages = getCurrentPages()
const prevPage = pages[pages.length - 2].$vm
prevPage.$options.refreshData = () => {
console.log('执行刷新操作')
}
根据具体场景选择合适的传参方式,可以显著提升应用的可维护性和性能表现。