咱们都知道 vue-router 的动态路由匹配 对组件是原地复用的策略,须要咱们在组件中根据不一样的$route
参数展现不一样的数据,这在大部分情景下是很高效的作法,但这无疑增长了组件的复杂度,并且不一样参数间切换由于是同组件复用,切换效果不加修饰的话会显得很生硬,这里放一张图片感觉一下。
若是咱们但愿可以每一个动态参数都能渲染出一个组件而不是去复用怎么办呢?
我这里提供一个简便的方案
一般动态路由咱们都是用来处理详情页html
const router = new VueRouter({ routes: [ // 动态路径参数 以冒号开头 { path: '/user/:id', component: User, props: true } ] })
User.vue
vue
<template> <div>{{ user.name }}</div> </template> <script> export default { name: 'User', props: ['id'], data() { return {data: {}}; }, watch: { id(id) { this.getUser(id); }, }, computed: { user() { return this.data[this.id] || {name: ''}; }, }, methods: { getUser(id) { setTimeout(() => { // 伪装异步 this.data[id] = {id, name: '张' + id}; }, 1000); }, }, mounted() { this.getUser(this.id); }, }; </script>
咱们能够发现基本上这样的组件是围绕着 路径参数
即例子中的id
作处理和渲染,只要咱们能提取到这个路径参数
,并维护成列表,经过这个列表来渲染实际组件,而后经过v-show
显示当前路径参数
下的组件,就能够实现不一样参数不一样组件的效果了。
简单的来个例子git
<template> <div> <user v-for="_id in idList" v-show="_id === id" :id="_id" :key="_id" /> </div> </template> <script> import User from './User.vue'; export default { name: 'UserPage', components: { User, }, props: ['id'], data() { return { idList: [this.id], }; }, watch: { id(id) { if (!this.idList.includes(id)) this.idList.push(id); }, }, }; </script>
而后把这个组件做为router
组件github
{ path: '/user/:id', component: UserPage, props: true }
如今咱们完成解耦,同路由组件间参数转变切换的是真实组件了,这里再放一张图片感觉一下。
这个方案说明白了很简单,但仍是有一些细节要注意处理,好比记录不一样参数页面的滚动条高度,好比怎么处理子页面关闭等等,个人开源项目e-admin
提供的ea-view
组件对这个解决方案作了完整的细节处理,有兴趣的话能够参考一下 ea-view。
我正在造一个基于element-ui
的中后台框架轮子 e-admin 欢迎starvue-router