Vue router
-
目前前端流行的三大框架,都有自己的路由实现:Angular的ngRouter, React的ReactRouter , Vue的vue-router
vue-router
是Vue.js
官方的路由插件,它和vue.js是深度集成的,适合用于构建单页面应用。我们可以访问其官方网站对其进行学习: https://router.vuejs.org/zh/ -
vue-router是基于路由和组件的
路由用于设定访问路径,将路径和组件映射起来.
在vue-router的单页面应用中,页面的路径的改变就是组件的切换.
Vue router 的安装
-
因为我们已经学习了webpack,后续开发中我们主要是通过工程化的方式进行开发的所以在后续,我们直接使用npm来安装路由即可.
-
步骤一:安装vue-router
npm install vue-router --save
-
步骤二:在模块化工程中使用它(因为是一个插件,所以可以通过Vue.use()来安装路由功能)
1. :
index.js
文件种导入路由对象,并且调用Vue.use(VueRouter)// index.js // 配置相关信息 import Vue from 'vue' import Router from 'vue-router' // 通过Vue.use(插件) 来安装router Vue.use(Router)
2. :创建路由实例
// index.js const routes = [ ] // 创建路由对象 export default new Router({ //配置路由和组件的, 映射关系 routes })
3. :在Vue实例中挂载创建的路由实例
// main.js文件 import Vue from 'vue' import App from './App' import router from './router' // 如果导入的是文件夹 , 默认寻找index文件 Vue.config.productionTip = false /* eslint-disable no-new */ new Vue({ el: '#app', router, // 挂载router render: h => h(App) })
-
目录结构
相比Vue项目 , 安装路由后在src下多了一个
router
文件夹 , 并且下面有一个index.js
文件 , 这个文件是用来配置路由的相关信息的
Vue router的使用
-
1. 创建路由组件(模板template)
about.vue
<template> <div> <h1>about</h1> <h2>I am about file</h2> </div> </template> <script> export default { name: "home" } </script> <style scoped> </style>
home.vue
<template> <div> <h1>home</h1> <h2>I am home file</h2> </div> </template> <script> export default { name: "home" } </script> <style scoped> </style>
-
2. 配置路由映射 (组件和路由关系)
router/index.js
const routes = [ { path: "/", // 缺省值 redirect: "/home" // 重定向到/home }, { path: '/home', component: home }, { path: '/about', component: about } ] // 创建路由对象 export default new Router({ // 使用history模式 mode: 'history', //配置路由和组件的, 映射关系 routes })
-
3. 通过
<vue-router>
和<vue-view>
来使用app.vue
<template> <div id="app"> <!--router-link默认会渲染成 a 标签 , 可以用tag属性来修改--> <router-link tag="button" to="/home">home</router-link> <router-link to="/about">about</router-link> <!--用于承载home或about组件--> <router-view></router-view> </div> </template>
<router-link>
该标签是一个vue-router中已经内置的组件,它会被渲染成一个<a>
标签.<router-view>
该标签会根据当前的路径,动态渲染出不同的组件.网页的其他内容,比如顶部的标题/导航,或者底部的一些版权信息等会和
<router-view>
处于同一个等级.在路由切换时,切换的是
<router-view>
挂载的组件,其他内容不会发生改变.属性
tag : 可以用tag属性来修改最终渲染成什么组件
<router-link tag="button" to="/home">home</router-link>
渲染为button组件replace : replace不会留下history记录,所以指定replace的情况下,后退键返回不能返回到上一个页面中
router-link-active : 当组件被点击时 , vue会给它添加一个class属性
router-link-active
我们可以用来做焦点事件.router-link-active{ color: red; }
自定义router-link
通过
vue-router
给我们提供的this.$router
来修改<template> <div id="app"> <!-- <router-link tag="button" to="/home">home</router-link> <router-link to="/about">about</router-link>--> <!--自定义router-link--> <button @click="goHome">home</button> <button @click="goAbout">about</button> <!--承载--> <router-view></router-view> </div> </template> <script> export default { methods: { goHome(){ // push -> pushState 会有历史记录 //this.$router.push("/home") this.$router.replace("/home") }, goAbout(){ this.$router.replace("/about") } } } </script>
动态路由
-
我们经常需要把某种模式匹配到的所有路由,全都映射到同个组件。例如,我们有一个
User
组件,对于所有 ID 各不相同的用户,都要使用这个组件来渲染。那么,我们可以在vue-router
的路由路径中使用“动态路径参数”(dynamic segment) 来达到这个效果: -
index.js 路由配置
import user from "../components/user" // 通过Vue.use(插件) 来安装router Vue.use(Router) const routes = [ ... { path: "/user/:userId", component: user } ]
-
app.vue 参数传递
<!--router-link的方式--> <router-link :to="'/user/' + userId">user</router-link> <!--自定义router-link的方式--> <button @click="goUser">user</button> <script> export default { data() { return { userId: "renyi" } }, methods: { goUser(){ this.$router.replace("/user/" + this.userId) } } } </script>
-
user.vue 组件
<template> <div> <h1>{{message}}</h1> <h3>{{description}}</h3> <h4>{{userId}}</h4> </div> </template> <script> export default { name: "user", data() { return { message: "user", description: "I am user interface", } }, computed: { userId(){ return this.$route.params.userId // 注意 这里是$route 不是router 这里的userId是根据 "路由配置" 中的 path: "/user/:userId", 决定的 } } } </script> <style scoped> </style>
路由的懒加载
-
当打包构建应用时,Javascript包会变得非常大,影响页面加载。
-
如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了
// 配置相关信息 import Vue from 'vue' import Router from 'vue-router' /* 不能再导入组件了 import home from "../components/home" import about from "../components/about" import user from "../components/user" */ // 通过Vue.use(插件) 来安装router Vue.use(Router) // 定义 const Home = () => import("../components/home"); const About = () => import("../components/about") const User = () => import("../components/user") const routes = [ { path: "/", // 缺省值 redirect: "/home" // 重定向到home }, // 路由懒加载的写法 { path: '/home', component: Home }, { path: '/about', component: About }, { path: "/user/:userId", component: User } /* 以前的写法 { path: '/home', component: home }, { path: '/about', component: about }, { path: "/user/:userId", component: user }*/ ] // 创建路由对象 export default new Router({ mode: 'history', //配置路由和组件的, 映射关系 routes })
路由的嵌套
-
比如在home页面中,我们希望通过
/home/news
和/home/message
访问一些内容.一个路径映射一个组件,访问这两个路径也会分别渲染两个组件. -
类似于
@RequestMapping
作用再类上和方法上的区别 -
1. 定义
HomeNew.vue
文件这是
Home.vue
的二级路径 , 会显示在Home.vue
下<template> <div> <ul> <li>消息1</li> <li>消息2</li> <li>消息3</li> <li>消息4</li> <li>消息5</li> </ul> </div> </template> <script> export default { name: "homenew" } </script> <style scoped> </style>
-
2.
Home.vue
文件我们需要在父组件中定义一个
router-view
用于承载HomeNew.vue
组件<template> <div> <h1>home</h1> <h2>I am home file</h2> <!--跳转homenew.vue--> <button @click="goHomeNew()">HomeNew</button> <router-link tag="button" to="/home/new">homenew</router-link> <router-view></router-view> </div> </template> <script> export default { name: "home", methods: { goHomeNew() { this.$router.replace("/home/new") } } } </script> <style scoped> </style>
-
3.
index.js
路由配置文件在父组件下 , 通过
children: [{},{}]
, 来定义二级路径 , 在二级路径 ,path
标签是不需要/
的.... // 通过Vue.use(插件) 来安装router Vue.use(Router) const Home = () => import('../components/home'); const Homenew = () => import('../components/homenew'); const routes = [ { path: "/", // 缺省值 redirect: "/home" // 重定向到home }, // 路由懒加载的方式 { path: '/home', component: Home, children: [ //默认就是Homenew { path: '', redirect: 'new' }, { path: 'new', component: Homenew } ] }, ... ] // 创建路由对象 export default new Router({ mode: 'history', //配置路由和组件的, 映射关系 routes })
Vue-router 参数传递
-
之前的动态路由也是以重传递参数的方式 , 还有另一种方式可以进行参数传递
-
1. 在
index.js
文件中进行配置最简单的方式配置即可
{ path: "/notice", component: Notice }
-
2. 在
App.vue
中跳转通过
:to
来定义路径和传递的参数 , 最终参数传递格式如下http://localhost:8080/notice?username=renyi&address=chengdu
<!--router-link--> <router-link :to="{path: '/notice' , query: {username:'renyi' , address: 'chengdu'}}">notice</router-link> <!--自定义 router-link--> <button @click="goNotice">notice</button> <script> export default { data() { return { user: { username:'renyi' , address: 'chengdu' } } }, methods: { goNotice(){ this.$router.replace( { path: "/notice", query: { user : this.user //如果以这样的方式进行传递 , 在取的时候需要先取到user对象<h2>{{$route.query.user.username}}</h2> } } ) } } } </script>
-
3. 定义
notice.vue
组件通过
$route.query
可以获取到传递的参数<template> <div> <h2>notice</h2> <h2>{{$route.query.username}}</h2> <h2>{{$route.query.address}}</h2> <h2 v-for="user in $route.query">{{user}}</h2> </div> </template>