vue3 通过改变组件状态,复用已有页面生成新页面,新旧页面互不影响
·
核心思路
- 复用页面组件:让原页面和新页面共用同一个组件(避免重复开发)。
- 状态隔离:通过路由参数或状态标识,让组件根据 “是否为新页面” 维护独立的响应式状态(原页面和新页面的状态互不干扰)。
- 区分页面角色:用路由参数(如
isNewPage)标记当前页面是 “原页面” 还是 “新页面”,组件内部根据标记初始化和管理状态。
1. 复用组件设计(同一组件适配原页面和新页面)
创建一个可复用的页面组件(如 ReusablePage.vue),通过路由参数判断自身角色(原页面 / 新页面),并分别维护独立状态。
<!-- ReusablePage.vue(复用的页面组件) -->
<template>
<div>
<h2>{{ isNewPage ? '新页面' : '原页面' }}</h2>
<p>当前状态:{{ currentState.count }} - {{ currentState.text }}</p>
<button @click="increment">+1</button>
<input v-model="currentState.text" placeholder="修改文本" />
<button
v-if="!isNewPage"
@click="openNewPage"
>
基于当前状态生成新页面
</button>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue';
import { useRoute, useRouter } from 'vue-router';
// 路由工具
const route = useRoute();
const router = useRouter();
// 从路由参数判断是否为新页面
const isNewPage = ref(route.query.isNewPage === 'true');
// 状态容器(原页面和新页面的状态完全独立)
const currentState = ref({
count: 0,
text: '初始文本'
});
// 初始化状态:
// - 原页面:用默认初始值
// - 新页面:从路由参数接收原页面的状态并初始化
onMounted(() => {
if (isNewPage.value) {
// 新页面:解析原页面传递的状态(深拷贝避免引用关联)
const originState = JSON.parse(decodeURIComponent(route.query.originState || '{}'));
currentState.value = { ...originState }; // 浅拷贝(深层对象需用 JSON 深拷贝)
}
});
// 原页面:打开新页面(复用当前组件,传递自身状态)
const openNewPage = () => {
// 将当前状态转为 URL 安全的字符串(避免特殊字符)
const originState = encodeURIComponent(JSON.stringify(currentState.value));
// 跳转到同一个组件的路由,但标记为新页面并携带原状态
router.push({
path: '/reusable-page', // 复用同一路由路径(或新路径,只要组件相同即可)
query: {
isNewPage: 'true', // 标记为新页面
originState: originState // 传递原页面状态
}
});
};
// 修改状态的方法(仅影响当前页面的 currentState)
const increment = () => {
currentState.value.count++;
};
</script>
2. 路由配置(复用组件,通过参数区分页面)
在路由中配置一个路径,指向复用的组件,通过 query 参数(isNewPage)区分原页面和新页面。
// router/index.js
import { createRouter, createWebHistory } from 'vue-router';
import ReusablePage from '../views/ReusablePage.vue';
const router = createRouter({
history: createWebHistory(),
routes: [
{
path: '/reusable-page',
name: 'ReusablePage',
component: ReusablePage // 同一个组件适配两种页面角色
}
]
});
export default router;
3. 新标签页场景(如需保留原页面)
如果需要在新标签页打开新页面(而非路由跳转),修改 openNewPage 方法,通过 window.open 传递状态:
// ReusablePage.vue 中修改 openNewPage 方法
const openNewPage = () => {
const originState = encodeURIComponent(JSON.stringify(currentState.value));
// 新标签页打开同一组件的路由,携带参数
window.open(
`/reusable-page?isNewPage=true&originState=${originState}`,
'_blank'
);
};
优势
- 代码复用:无需开发新组件,直接复用已有页面逻辑。
- 状态彻底隔离:利用 Vue 组件实例的独立性,确保原页面和新页面状态互不影响。
- 扩展性强:可通过路由参数传递更多配置(如新页面的特殊权限、展示模式等)。
更多推荐


所有评论(0)