9.路由
vue 属于单页面应用,所谓的路由,就是根据浏览器路径不同,用不同的视图组件替换这个页面内容展示
默认路由的配置是router目录下的index.js文件
可以根据这个文件来写路由
静态导入
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
| import Vue from 'vue' import VueRouter from 'vue-router'
import ContainerView from '@/views/example13/ContainerView.vue' import LoginView from '@/views/example13/LoginView.vue' import NotFoundView from '@/views/example13/NotFoundView.vue'
Vue.use(VueRouter)
const routes = [ { path:'/', component: ContainerView }, { path:'/login', component: LoginView }, { path:'/404', component: NotFoundView } ]
const router = new VueRouter({ routes })
export default router
|
1
| import router from './router/example13'
|
修改主视图
<router-view>
起到占位作用,改变路径后,这个路径对应的视图组件就会占据 <router-view>
的位置,替换掉它之前的内容
1 2 3 4 5 6 7 8 9 10
| <template> <div> <router-view></router-view> </div> </template>
<script>
</script>
|
动态导入
- 静态导入是将所有组件的 js 代码打包到一起,如果组件非常多,打包后的 js 文件会很大,影响页面加载速度
- 动态导入是将组件的 js 代码放入独立的文件,用到时才加载
案例
将上面的静态导入改为动态导入
通过lambda表达式() => import('文件路径')
来动态导入
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
| import Vue from 'vue' import VueRouter from 'vue-router'
Vue.use(VueRouter)
const routes = [ { path:'/', component: () => import('@/views/example13/ContainerView.vue') }, { path:'/login', component: () => import('@/views/example13/LoginView.vue') }, { path:'/404', component: () => import('@/views/example13/NotFoundView.vue') } ]
const router = new VueRouter({ routes })
export default router
|
嵌套导入
也叫子路由,组件内再要切换内容,就需要用到嵌套路由
通过children属性来定义嵌套路由
案例
定义嵌套路由和重定向
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 37 38 39 40 41 42 43 44 45 46 47 48 49
| import Vue from 'vue' import VueRouter from 'vue-router'
Vue.use(VueRouter)
const routes = [ { path:'/', component: () => import('@/views/example13/ContainerView.vue'), redirect: '/c/p1', children: [ { path: 'c/p1', component: () => import('@/views/example13/container/P1View.vue') }, { path: 'c/p2', component: () => import('@/views/example13/container/P2View.vue') }, { path: 'c/p3', component: () => import('@/views/example13/container/P3View.vue') }, ] }, { path:'/login', component: () => import('@/views/example13/LoginView.vue') }, { path:'/404', component: () => import('@/views/example13/NotFoundView.vue') }, { path:'*', redirect: '/404' } ]
const router = new VueRouter({ routes })
export default router
|
路由跳转
跳转方式:
- 标签式:通过to属性实现跳转
- 编程式:自定义方法,通过this.$router.push(url)方式实现跳转
案例
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
| <template> <div class="container"> <el-container> <el-header> <!-- 编程式 --> <el-button icon="el-icon-search" circle size="mini" @click="jump('/c/p1')"></el-button> <el-button type="primary" icon="el-icon-edit" circle size="mini" @click="jump('/c/p2')"></el-button> <el-button type="success" icon="el-icon-check" circle size="mini" @click="jump('/c/p3')"></el-button> </el-header> <el-container> <el-aside width="200px"> <!-- 标签式 --> <router-link to="/c/p1">p1</router-link> <router-link to="/c/p2">p2</router-link> <router-link to="/c/p3">p3</router-link> </el-aside> <el-main> <router-view></router-view> </el-main> </el-container> </el-container> </div> </template> <script> const options = { methods: { jump(url) { // 根据路径进行跳转 this.$router.push(url); } } } export default options; </script>
|
动态路由
从后端动态的获取路由信息添加到路由中
案例
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 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| <template> <div class="login"> <el-input v-model="username" placeholder="请输入用户名" size="mini"></el-input> <el-button type="primary" size="mini" @click="login()">登录</el-button> </div> </template> <script> import axios from '../../utils/myaxios.js' import {resetRouter} from '@/router/example14'
const options = { data() { return { username: 'admin' } }, methods: { // 将登录用户可以访问的路径添加到路由中 async login() { resetRouter(); const resp = await axios.get(`/api/menu/${this.username}`) for (const {id, path, component} of resp.data.data) { if (component !== null) { // 在父路由中添加路由 this.$router.addRoute('c', { path: path, name: id, component: () => import(`@/views/example14/container/${component}`) }) } } // 打印路由 console.log(this.$router.getRoutes()) } }
}
export default options; </script>
<style scoped> .login { height: 100%; background-color: darkseagreen; /* background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3Ctext x='15' y='10' font-size='14' font-family='system-ui, sans-serif' text-anchor='middle' dominant-baseline='middle'%3E登录%3C/text%3E%3C/svg%3E"); */ }
.el-input--mini { width: 193px; margin: 10px 10px 0 10px; } </style>
|
保存路由信息
每次刷新页面,路由信息都会丢失
将路由数据存到localStorage或sessionStorage可以在每次刷新时来恢复路由
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
| const serverRoutes = sessionStorage.getItem('serverRoutes') if (serverRoutes) { const array = JSON.parse(serverRoutes) addServerRoutes(array) }
export function resetRouter() { router.matcher = new VueRouter({routes}).matcher }
export async function addServerRoutes(array) { resetRouter(); for (const {id, path, component} of array) { if (component !== null) { router.addRoute('c', { path: path, name: id, component: () => import(`@/views/example14/container/${component}`) }) } } }
|