Vue跨页面通信实战:路由参数、Pinia/Vuex与localStorage详解
在Vue项目开发中,不同路由页面之间的数据传递和状态同步是高频需求,比如从列表页跳转详情页传递ID,或者页面A操作后让页面B实时更新。本文基于实际开发场景,梳理三种最实用的跨页面通信方式:路由参数传递(query/params)、全局状态管理(Pinia/Vuex)、本地存储(localStorage/sessionStorage),覆盖Vue2和Vue3,每个方案均附带完整可运行的Demo代码与关键注意事项。一、路由参数传递(页面跳转传值首选)
适用场景:列表页→详情页传递简单ID、名称等轻量数据,或传递敏感临时数据。分为 query 和 params 两种方式,按需选择。
1. query参数(路径可见,刷新不丢失)
优点:参数直接显示在URL中(如 /pageB?id=123),刷新页面仍保留,适合非敏感数据。
Vue3完整示例(组合式API):
// 路由配置(router/index.js)
import { createRouter, createWebHistory } from 'vue-router';
import PageA from '@/views/PageA.vue';
import PageB from '@/views/PageB.vue';
const routes = [
{ path: '/pageA', name: 'PageA', component: PageA },
{ path: '/pageB', name: 'PageB', component: PageB }
];
const router = createRouter({
history: createWebHistory(),
routes
});
export default router;
// 页面A(跳转方,@/views/PageA.vue)
<template>
<div>
<h3>页面A</h3>
<router-link :to="{ path: '/pageB', query: { id: 123, name: 'Vue跨页面通信Demo' } }" class="btn">
点击跳转页面B(router-link)
</router-link>
<button @click="goToPageB" class="btn">点击跳转页面B(编程式)</button>
</div>
</template>
<script setup>
import { useRouter } from 'vue-router';
const router = useRouter();
const goToPageB = () => {
router.push({
path: '/pageB',
query: { id: 123, name: 'Vue跨页面通信Demo' }
});
};
</script>
<style scoped>
.btn { margin: 0 10px; padding: 6px 12px; cursor: pointer; }
// 页面B(接收方,@/views/PageB.vue)
<template>
<div>
<h3>页面B</h3>
<div>接收的ID:{{ id }}</div>
<div>接收的名称:{{ name }}</div>
</div>
</template>
<script setup>
import { useRoute } from 'vue-router';
import { ref, watch } from 'vue';
const route = useRoute();
const id = ref(Number(route.query.id));
const name = ref(route.query.name);
watch(() => route.query, (newQuery) => {
id.value = Number(newQuery.id);
name.value = newQuery.name;
}, { immediate: true });
</script>
Vue2版本(选项式API)只需将 $router.push 和 $route.query 换成 this.$router 和 this.$route,并在 watch 中监听 '$route.query',结构类似,不再赘述。
2. params参数(路径不可见,适合敏感临时数据)
优点:参数不会出现在URL中,适合传递密码、token等敏感信息。注意:必须配合路由配置中的占位符(如 /pageB/:id/:name)使用,且跳转时必须使用 name,不能使用 path。刷新页面时若配置了占位符则不会丢失。
Vue3示例(仅展示差异部分):
// 路由配置(需添加占位符)
{ path: '/pageB/:id/:name', name: 'PageB', component: PageB }
// 页面A跳转(必须用name)
router.push({ name: 'PageB', params: { id: 456, name: '敏感数据Demo' } });
// 页面B接收
const id = ref(Number(route.params.id));
const name = ref(route.params.name);
Vue2跳转方式:this.$router.push({ name: 'PageB', params: { id: 456, name: '敏感数据Demo' } }),接收使用 this.$route.params。
注意事项:
- query参数路径可见,适合简单字符串/数字;params参数路径不可见,但若未配置占位符,刷新后丢失。
- 传递对象/数组时,需先 JSON.stringify,接收时 JSON.parse,避免数据错乱。
二、全局状态管理(Pinia / Vuex)
适用场景:多个页面共享同一份数据(如用户信息、全局配置),且需要实时联动更新。Vue3 推荐 Pinia,Vue2 常用 Vuex。
1. Pinia(Vue3首选,更轻量简洁)
使用步骤:安装依赖(npm install pinia)→ 创建 Pinia 实例并注册 → 定义 store → 在组件中直接调用。
// main.js 注册 Pinia
import { createApp } from 'vue';
import { createPinia } from 'pinia';
import App from './App.vue';
import router from './router';
const app = createApp(App);
app.use(createPinia());
app.use(router);
app.mount('#app');
// store/modules/user.js 定义仓库
export const useUserStore = defineStore('user', {
state: () => ({
userInfo: { id: 1, name: '测试用户', age: 20 },
count: 0
}),
actions: {
setUserInfo(info) { this.userInfo = info; },
addCount() { this.count++; },
resetCount() { this.count = 0; }
}
});
// 页面A(修改数据)
<script setup>
import { useUserStore } from '@/store/modules/user';
const userStore = useUserStore();
const updateUserInfo = () => {
userStore.setUserInfo({ id: 2, name: '新用户', age: 22 });
};
</script>
<template>
<div>当前计数器:{{ userStore.count }}</div>
<button @click="userStore.addCount">+1</button>
</template>
// 页面B(读取数据)
<script setup>
import { useUserStore } from '@/store/modules/user';
const userStore = useUserStore();
</script>
<template>
<div>用户:{{ userStore.userInfo.name }}</div>
</template>
注意:Pinia 无需手动注册到 Vue,直接 useStore() 即可。数据在页面刷新后会丢失,需配合 localStorage 做持久化。
2. Vuex(Vue2 标准方案)
使用前安装 vuex@3,在 main.js 中 Vue.use(Vuex) 并注入 store。
// store/index.js
export default new Vuex.Store({
state: { userInfo: { id: 1, name: '测试用户', age: 20 }, count: 0 },
mutations: {
setUserInfo(state, info) { state.userInfo = info; },
addCount(state) { state.count++; },
resetCount(state) { state.count = 0; }
},
actions: {
addCountAsync({ commit }) { setTimeout(() => commit('addCount'), 1000); }
},
getters: { userName: state => state.userInfo.name }
});
// 页面中通过 $store 访问
this.$store.commit('addCount');
this.$store.dispatch('addCountAsync');
this.$store.state.count;
this.$store.getters.userName;
Vuex 的 mutation 必须同步,异步操作需要放在 action 中。使用 getters 简化读取。
三、localStorage / sessionStorage(本地存储持久化)
适用场景:需要跨页面持久保存的数据(如登录 token、用户偏好设置),刷新页面也不会丢失。localStorage 除非手动删除否则永久保存,sessionStorage 在关闭浏览器标签后清除。
推荐封装通用工具函数,方便统一管理对象序列化/反序列化:
// utils/storage.js
export const setLocal = (key, value) => {
const val = typeof value === 'object' ? JSON.stringify(value) : value;
localStorage.setItem(key, val);
};
export const getLocal = (key) => {
const val = localStorage.getItem(key);
try { return JSON.parse(val); } catch { return val; }
};
export const removeLocal = (key) => { localStorage.removeItem(key); };
export const setSession = (key, value) => {
const val = typeof value === 'object' ? JSON.stringify(value) : value;
sessionStorage.setItem(key, val);
};
export const getSession = (key) => {
const val = sessionStorage.getItem(key);
try { return JSON.parse(val); } catch { return val; }
};
export const removeSession = (key) => { sessionStorage.removeItem(key); };
在 Vue 组件中使用时,直接调用这些方法即可同步数据。若要实现“多页面实时同步”,可配合 storage 事件(window.addEventListener('storage', handler))或定时器轮询。
总结:以上三种方式覆盖了 Vue 跨页面通信的绝大多数场景:简单的跳转传值用路由参数;多页面全局共享用 Pinia/Vuex;需要持久化且不依赖框架层则用 localStorage。根据实际需求选择最合适的方案,避免过度设计。后续还会补充 EventBus、Cookie、postMessage 等进阶方式,但在日常开发中,掌握这三种已足以应对 80% 的需求。
Re: Vue跨页面通信实战:路由参数、Pinia/Vuex与localStorage详解
感谢楼主分享,总结得很全面,代码示例也清晰易懂。我个人在项目里用得最多的是路由 query 传轻量数据,确实方便,但有时对象会先序列化一下。对于需要跨多个页面实时同步的状态,Pinia 确实比 Vuex 轻快不少,迁移成本也低。有个小疑问:params 配合占位符刷新不丢,但路径中还是会显示占位符里的值,严格来说不算完全隐藏吧?如果真要隐藏敏感数据,是不是还得结合 sessionStorage 或加密处理更稳妥?Re: Vue跨页面通信实战:路由参数、Pinia/Vuex与localStorage详解
楼主写得很详细,路由参数这块确实是跨页面传值最常用的基础方法。特别是query参数刷新不丢失、params配合占位符可以藏参数的对比,总结得很清晰。我在实际项目里也遇到过传对象忘记JSON.stringify导致接收端显示的情况,提醒得很及时。期待后续Pinia和localStorage的部分,尤其是Pinia与Vue Devtools的调试配合,希望能多讲讲。Re: Vue跨页面通信实战:路由参数、Pinia/Vuex与localStorage详解
楼主这篇帖子太实用了!三种跨页面通信方式都讲得很清楚,特别是query和params的区别、Pinia的使用,还有代码示例。正好最近在做Vue3项目,帮我理清了思路。感谢分享!
页:
[1]