uni-app小程序开发-页面跳转(路由)及传值

小程序内跳转

uni.navigateTo

用法:uni.navigateTo({ url: '目标页面路径' })

描述:保留当前页面,跳转到应用内的某个页面。

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<template>
<view>
<button @click="navigateToPage">跳转到新页面</button>
</view>
</template>

<script>
export default {
methods: {
navigateToPage() {
uni.navigateTo({
url: '/pages/newPage/newPage'
});
}
}
}
</script>

uni.redirectTo

用法:uni.redirectTo({ url: '目标页面路径' })

描述:关闭当前页面,跳转到应用内的某个页面。不可返回到原页面。

示例:uni.redirectTo({ url: '/pages/login/login' })

1
2
3
uni.redirectTo({
url: '/pages/newPage/newPage'
});

uni.reLaunch

用法:uni.reLaunch({ url: '目标页面路径' })

描述:关闭所有页面,打开应用内的某个页面。适用于一些非常重要的页面,如应用启动页。

示例:uni.reLaunch({ url: '/pages/index/index' })

1
2
3
uni.reLaunch({
url: '/pages/newPage/newPage'
});

uni.switchTab

用法:uni.switchTab({ url: '目标页面路径' })

描述:跳转到应用内的某个tabBar页面,关闭其他所有非tabBar页面。

示例:uni.switchTab({ url: '/pages/home/home' })

1
2
3
uni.switchTab({
url: '/pages/tabBarPage/tabBarPage'
});

uni.navigateBack

用法:uni.navigateBack({ delta: 1 })

描述:返回上一级页面。参数delta表示返回的层数,默认为1。

示例:uni.navigateBack({ delta: 2 })

1
uni.navigateBack();

小程序内跳转对比

  • 参数传递: navigateToredirectToreLaunch 都支持通过 url 后面拼接参数传递数据,而 switchTabnavigateBack 不支持直接传递参数,需要通过其他方式实现。

  • 目的: navigateTo 用于普通页面跳转,redirectTo 用于页面重定向,reLaunch 用于关闭所有页面打开新页面,switchTab 用于切换 TabBar 页面,navigateBack 用于返回上一页。

  • 适用场景: 选择使用哪种方法取决于你的具体业务需求。

    如果需要保留当前页面并跳转到新页面,可以使用 navigateTo

    如果需要关闭当前页面并打开新页面,可以使用 redirectToreLaunch

    如果需要切换到 TabBar 页面,可以使用 switchTab;如果需要返回上一页,可以使用 navigateBack

  • 参数传递方式: 除了 navigateToredirectToreLaunchurl 后面拼接参数外,也可以使用全局变量、本地存储等方式进行参数传递,这对于 switchTabnavigateBack 是特别有用的。

不推荐uni-simple-router

这是基于uni-simple-router做页面跳转。不推荐使用.

https://www.hhyang.cn/guide/introduction.html

注意:

一个程序中不建议同时出现小程序本身的跳转和基于uni-simple-router的跳转。

调用示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import {
createRouter
} from '@/uni-simple-router'

const router = createRouter({
platform:process.env.VUE_APP_PLATFORM as platformRule,
routes:[
// ...
]
})

// 字符串路径
router.push('/users/eduardo')

// 带有路径的对象
router.push({ path: '/users/eduardo' })

// 命名的路由,并加上参数,让路由建立 url
router.push({ name: 'user', params: { username: 'eduardo' } })

// 带查询参数,结果是 /register?plan=private
router.push({ path: '/register', query: { plan: 'private' } })

// 跳转到原生Tabbar
router.pushTab({ name: 'tab1' })

// 关闭所有页面并打开指定页面
router.replaceAll({ name: 'my' })

// 替换当前页面栈并打开新页面
router.replace({ name: 'record' }).then(()=>{
console.log(`导航完成`)
})

// 返回页面
router.back(1)

小程序内传值

跳转传值

基本传值

navigateTo、redirectTo、reLaunch 的参数传递

描述:通过 query 参数传递数据到目标页面。

代码示例:

1
2
3
4
//在起始页面跳转到test.vue页面并传递参数
uni.navigateTo({
url: 'test?id=1&name=uniapp'
});

获取跳转页面的参数

描述:在目标页面的 onLoad 钩子函数中通过 options 获取跳转时传递的参数。

代码示例:

1
2
3
4
5
6
7
// 在test.vue页面接受参数
export default {
onLoad: function (option) { //option为object类型,会序列化上个页面传递的参数
console.log(option.id); //打印出上个页面传递的参数。
console.log(option.name); //打印出上个页面传递的参数。
}
}

参数拼接工具类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
export function getUrlWithParas(url, paras) {
// 提取参数的键
let keys = Object.keys(paras);

// 如果没有参数,则直接返回原始 URL
if (keys.length === 0) {
return url;
}

// 构建查询字符串
let queryString = keys.map(key => {
// 对参数值进行 URL 编码
return `${encodeURIComponent(key)}=${encodeURIComponent(paras[key])}`;
}).join('&');

// 如果 URL 已经包含查询参数,则需要添加 '&'
if (url.includes('?')) {
return `${url}&${queryString}`;
}

// 如果 URL 不包含查询参数,则添加 '?'
return `${url}?${queryString}`;
}

取参解密

1
2
3
4
onLoad(option) {
let { typeName } = option;
this.typeName = decodeURIComponent(typeName);
},

传对象

uni-app 中进行页面跳转时,可以传递对象,但需要将对象转换为字符串格式(通常是 JSON 字符串),因为 uni-app 的页面跳转传值只支持基本数据类型和字符串。

以下是一个简单的例子,演示如何在页面跳转时传递一个对象:

页面 A: 跳转并传递对象

1
2
3
4
5
6
7
8
9
10
// 假设我们要传递的对象
const obj = { name: 'John', age: 30 };

// 将对象转换为 JSON 字符串
const objStr = JSON.stringify(obj);

// 使用 uni.navigateTo 跳转并传递参数
uni.navigateTo({
url: '/pages/pageB/pageB?data=' + encodeURIComponent(objStr)
});

页面 B: 接收并解析对象

1
2
3
4
5
6
7
8
9
10
11
12
export default {
onLoad(options) {
// 获取传递的 JSON 字符串
const objStr = decodeURIComponent(options.data);

// 解析 JSON 字符串为对象
const obj = JSON.parse(objStr);

// 现在你可以使用这个对象了
console.log(obj);
}
}

在这个示例中:

  • 页面 A 中使用 JSON.stringify() 将对象转换为字符串,并通过 encodeURIComponent() 对字符串进行编码,以确保 URL 参数中的特殊字符不会破坏 URL。
  • 页面 B 中使用 decodeURIComponent() 对传递的字符串进行解码,然后用 JSON.parse() 将字符串转换回对象。

这样,你就可以在 uni-app 中进行页面跳转时传递和接收对象了。

页面关闭值回传

在A页面跳转到B页面,并监听B页面发送过来的事件数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
uni.navigateTo({
url: '/pages/test?id=1',
events: {
// 为指定事件添加一个监听器,获取被打开页面传送到当前页面的数据
acceptDataFromOpenedPage: function(data) {
console.log(data.data)
},
getSelectedEvent: function(data) {
console.log(data.data)
}
},
success: function(res) {
// 通过eventChannel向被打开页面传送数据
res.eventChannel.emit('AToBData', { data: 'data from A page' })
}
})

值回传

在B页面,向起始页通过事件传递数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
onLoad: function(option) {
const eventChannel = this.getOpenerEventChannel();
eventChannel.on('AToBData', function(data) {
console.log(data)
})
},
methods:{
sendToBClick(){
const eventChannel = this.getOpenerEventChannel();
eventChannel.emit('getSelectedEvent', {data: 'data from B page'});
uni.navigateBack();
}
}
}

全局存储globalData

小程序有globalData,这是一种简单的全局变量机制。这套机制在uni-app里也可以使用,并且全端通用。

当然vue框架的全局变量,另有其他方式定义。

页面返回的时候,判断之前的页面是否刷新,这种方式也相对更简单。

以下是 App.vue 中定义globalData的相关配置:

1
2
3
4
5
6
7
<script>  
export default {
globalData: {
needRefresh: false
},
}
</script>

JS中操作globalData的方式如下:

1
2
getApp().globalData.needRefresh = true
uni.navigateBack();

在应用onLaunch时,getApp对象还未获取,暂时可以使用this.globalData获取globalData

如果需要把globalData的数据绑定到页面上,可在页面的onShow页面生命周期里进行变量重赋值。

globalData是简单的全局变量,如果使用状态管理,请使用vuex(main.js中定义)

页面返回刷新,在返回的页面中

1
2
3
4
5
6
onShow() {
if (getApp().globalData.needRefresh) {
this.actionList();
getApp().globalData.needRefresh = false
}
}

事件总线

使用uni提供的API进行页面传值,如uni.$emituni.$on

通过事件触发和监听的方式在页面之间传递数据。

使用Uniapp的事件总线来进行组件之间的通信。在发送组件中,使用uni.$emit触发一个自定义事件,并在接收组件中使用uni.$on监听这个事件。

在发送组件:

1
uni.$emit('customEvent', data);

在接收组件:

1
2
3
uni.$on('customEvent', (data) => {
console.log(data);
});

使用本地存储(Storage)

使用本地存储(localStorage或uni提供的存储API)将数据存储到本地,然后在另一个页面中读取。

适用于需要持久保存数据的情况。如果数据不大,你也可以将数据存储在本地存储中,然后在目标页面读取。

其中根据使用情景可以使用同步StorageSync或者异步Storage来实现。

同步:使用uni.setStorageSyncuni.getStorageSync等方法,将数据存储在本地,然后在另一个页面读取。

1
2
3
4
5
// 在页面A中保存数据到本地存储
uni.setStorageSync('key', value);
// 在页面B中从本地存储中读取数据
const value = uni.getStorageSync('key');
console.log(value);

异步:使用uni.setStorageuni.getStorage等方法,将数据存储在本地,然后在另一个页面读取。

1
2
3
4
5
6
7
8
9
10
11
12
// 在页面A中保存数据到本地存储
uni.setStorage({
key: 'yourDataKey',
data: yourData,
});
// 在页面B中从本地存储中读取数据
uni.getStorage({
key: 'yourDataKey',
success: function (res) {
const pageData = res.data;
},
});

移除

1
2
3
4
5
try {
uni.removeStorageSync('storage_key');
} catch (e) {
// error
}

清空

1
uni.clearStorage();

Pinia

uni-app 内置了 Pinia 。Vue 2 项目暂不支持。

HBuilder X 已内置了 Pinia,无需手动安装。

可参考

https://www.psvmc.cn/article/2024-07-23-uni-app-pinia.html

/stores/common.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import {
defineStore
} from 'pinia';

export const useCommonStore = defineStore('common', {
state: () => {
return {
count: 0,
cityName: "郑州",
needRefresh:false
};
},
actions: {
increment() {
this.count++;
},
},
});

使用

1
2
3
4
5
6
7
8
import { useCommonStore } from '@/stores/common';
import { mapState, mapStores, mapActions } from 'pinia'
export default {
computed: {
// 允许访问 this.commonStore
...mapStores(useCommonStore),
},
}

赋值

1
this.commonStore.needRefresh = true;

Vuex状态管理

使用Vuex进行全局状态管理,可以在一个页面中修改状态,而在另一个页面中获取最新的状态。

适用于需要在多个页面之间共享数据的情况。

如果你的应用使用了Vuex,可以在一个页面的computed属性或methods中触发commit,然后在另一个页面通过this.$store.state获取值。

在第一个页面:

1
2
// 在页面中触发commit
this.$store.commit('setValue', value);

在第二个页面:

1
2
3
// 在另一个页面获取值
const value = this.$store.state.value;
console.log(value);

小程序间跳转

uni.navigateToMiniProgram

uni.navigateToMiniProgram 用于跳转到其他小程序。

1
2
3
4
5
6
7
8
9
10
uni.navigateToMiniProgram({
appId: 'targetAppId',
path: 'targetPath',
extraData: {
key: 'value'
},
success: function () {
console.log('跳转成功');
}
});

uni.redirectToMiniProgram

uni.redirectToMiniProgram 用于关闭当前小程序,跳转到其他小程序。

1
2
3
4
5
6
7
8
9
10
uni.redirectToMiniProgram({
appId: 'targetAppId',
path: 'targetPath',
extraData: {
key: 'value'
},
success: function () {
console.log('跳转成功');
}
});

uni.navigateToNative

uni.navigateToNative 用于跳转到原生页面。

1
2
3
4
5
6
uni.navigateToNative({
pageName: 'targetPage',
params: {
key: 'value'
}
});