UniApp 页面传参方式详解

发布于:2025-08-18 ⋅ 阅读:(17) ⋅ 点赞:(0)

在 UniApp 开发中,页面间参数传递是核心功能之一。以下是 8 种常用的传参方式,每种方式都有其适用场景和特点:


一、URL 拼接传参(最常用)

适用场景:简单数据传递,如 ID、状态值等基础类型数据
实现方式

// 发送参数
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)
  • 不支持复杂对象(需手动序列化)

二、全局变量传参

适用场景:跨页面共享数据(如用户信息)
实现方式

// 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 状态管理

适用场景:复杂应用状态共享
实现方式

// 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
  }
}

特点

  • 响应式数据流
  • 支持调试工具
  • 适合中大型项目

四、本地存储传参

适用场景:持久化数据传递(如登录状态)
实现方式

// 页面 A 存储数据
uni.setStorageSync('token', 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9')

// 页面 B 读取数据
const token = uni.getStorageSync('token')

特点

  • 数据持久化(关闭应用仍存在)
  • 同步操作可能阻塞渲染
  • 容量限制(通常 5-10MB)

五、事件总线(EventBus)

适用场景:任意组件/页面间通信
实现方式

// 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') // 必须解绑!
  }
}

特点

  • 完全解耦的通信方式
  • 需手动管理事件监听
  • 滥用可能导致"事件地狱"

六、页面通信通道

适用场景:需要获取前序页面实例的场景
实现方式

// 获取前序页面实例
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 对象
实现方式

// 发送复杂对象
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.emituni.on

适用场景:跨页面事件通信(UniApp 2.8.0+)
实现方式

// 页面 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) // 必须解绑
  }
}

特点

  • 官方提供的全局事件机制
  • 需手动管理事件绑定
  • 适合简单通知类通信

最佳实践建议

  1. 简单数据传递:优先使用 URL 传参
  2. 用户状态管理:Vuex + 本地存储持久化
  3. 复杂对象传递:URL 编码或全局变量
  4. 跨级通信:EventBus 或 uni.$emit
  5. 重要数据传递:始终添加参数校验
// 参数校验示例
onLoad(options) {
  if (!options.id || isNaN(options.id)) {
    uni.showToast({ title: '参数错误', icon: 'error' })
    uni.navigateBack()
    return
  }
}
  1. 内存管理:在 onUnload 中清理资源
onUnload() {
  // 清除事件监听
  eventBus.$off('update')
  uni.$off('update')
  
  // 释放大对象
  this.largeData = null
}

性能优化技巧

  1. 大数据传递:使用 ID 传递,目标页面重新请求
  2. 频繁更新数据:使用 Vuex 响应式更新
  3. 页面返回刷新
// 前页注册刷新方法
onShow() {
  if (this.$options.refreshData) {
    this.$options.refreshData()
  }
}

// 后页触发刷新
const pages = getCurrentPages()
const prevPage = pages[pages.length - 2].$vm
prevPage.$options.refreshData = () => {
  console.log('执行刷新操作')
}

根据具体场景选择合适的传参方式,可以显著提升应用的可维护性和性能表现。


网站公告

今日签到

点亮在社区的每一天
去签到