Vue中路由 (Vue Router)
一、 vue中路由 Router
路由:根据请求的路径按照一定的路由规则进行请求的转发从而帮助我们实现统一请求的管理
概念:它和vue.js的核心深度集成,让构成单页面应用变得易如反掌
理解:让组件使用变得更加灵活,路由可以根据用户访问的url不同动态切换当前使用的组件
1、作用
用来在vue中实现组件之间的动态切换
路由核心功能:根据用户访问的url动态切换组件
路由是配合组件一起使用的
路由使用步骤
1. 创建组件 2.创建路由( 1.管理组件 2.制定路由规则) 3.将路由交由vue管理 在vue中注册路由 4.在vue实例范围内指定位置,使用路由选中组件
2、使用路由
(1)引入路由
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script> //vue 路由js
(2)创建组件对象
//声明组件模板 const login = { template:'<h1>登录</h1>' }; const register = { template:'<h1>注册</h1>' };
(3)定义路由对象的规则
//创建路由对象 const router = new VueRouter({ routes:[ {path:'/login',component:login}, //path: 路由的路径 component:路径对应的组件 {path:'/register',component:register} ] });
(4)将路由对象注册到vue实例
const app = new Vue({ el: "#app", data: { username:"小陈", }, methods: {}, router:router //设置路由对象 });
(5)在页面中显示路由的组件
<!--显示路由的组件--> <router-view></router-view>
(6)根据连接切换路由
<a href="#/login">点我登录</a> <a href="#/register">点我注册</a>
3、vue中路由 Router案例
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>route的基本使用</title> </head> <body> <div id="app"> {{msg}} <!--4、路由选中的组件展示--> <div><router-view></router-view></div> </div> </body> </html> <script src="../js/vue-min.js"></script> <script src="../js/vue-router.js"></script> <script> const login={ template:`<div><h2>登录组件</h2></div>` } const reg={ template:`<div><h2>注册组件</h2></div>` } //创建路由 1、管理组件 2、配置路由规则 const router=new VueRouter({ // 指定路由规则 routes:[ {path:"/login",component:login}, {path:"/register",component:reg} ] }); new Vue({ el:"#app", data:{ msg:"route的基本使用" }, // 3.将路由对象注册给vue实例 router }) </script>
二、通过超链接切换路由的方式
1、链接切换路由
<!-- 使用链接切换路径--> <a href="#/login">登录组件</a> <a href="#/register">注册组件</a>
案例
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>route的基本使用</title> </head> <body> <div id="app"> {{msg}} <!--4、路由选中的组件展示--> <div><router-view></router-view></div> <!-- 使用链接切换路径--> <a href="#/login">登录组件</a> <a href="#/register">注册组件</a> </div> </body> </html> <script src="../js/vue-min.js"></script> <script src="../js/vue-router.js"></script> <script> const login={ template:`<div><h2>登录组件</h2></div>` } const reg={ template:`<div><h2>注册组件</h2></div>` } //路由错误时的提示组件 const notFound={ template:`<div><h2>你访问的路径有误,请重新输入</h2></div>` } //创建路由 1、管理组件 2、配置路由规则 const router=new VueRouter({ // 指定路由规则 routes:[ {path:"/",redirect:"/login"},//配置根路由 切换方式为:重定向到指定路径 {path:"/login",component:login}, {path:"/register",component:reg}, {path:"*",component:notFound} //路径错误时的提示 ] }); new Vue({ el:"#app", data:{ msg:"route的基本使用" }, // 3.将路由对象注册给vue实例 router }) </script>
2、router-link使用
作用:用来替换我们在切换路由时使用a标签切换路由
好处:就是可以自动给路由路径加入#不需要手动加入
(1)使用router-link切换路由
<router-view></router-view> <!-- 使用链接切换路径--> <a href="#/login">登录组件</a> <a href="#/register">注册组件</a> <!--使用router-link切换路由--> <hr/> <router-link to="/login">登录组件</router-link> <router-link to="/register">注册组件</router-link>
(2)根据路径去切换路由
<router-view></router-view> <!-- 使用链接切换路径--> <a href="#/login">登录组件</a> <a href="#/register">注册组件</a> <!--使用router-link切换路由--> <hr/> <router-link to="/login">登录组件</router-link> <router-link to="/register">注册组件</router-link> <hr/> <!--根据路径去切换路由 --> <router-link :to="{path:'/login'}">登录组件</router-link> <router-link :to="{path:'/register'}">注册组件</router-link>
(3)根据名称去切换路由 官方推荐 解耦合
官方建议使用名称切换,可以和当前路由配置的path解耦合 修改path属性不会影响到路由切换
<router-view></router-view> <!-- 使用链接切换路径--> <a href="#/login">登录组件</a> <a href="#/register">注册组件</a> <!--使用router-link切换路由--> <hr/> <router-link to="/login">登录组件</router-link> <router-link to="/register">注册组件</router-link> <hr/> <!--根据路径去切换路由--> <router-link :to="{path:'/login'}">登录组件</router-link> <router-link :to="{path:'/register'}">注册组件</router-link> <hr/> <!--根据名称去切换路由 官方推荐--> <hr/> <router-link :to="{name:'login'}">登录组件</router-link> <router-link :to="{name:'register'}">注册组件</router-link>
# 总结: 1.router-link 用来替换使用a标签实现路由切换 好处是不需要书写#号直接书写路由路径 2.router-link to属性用来书写路由路径 tag属性:用来将router-link渲染成指定的标签
三、通过js切换路由的方式
当前vue实例中 存在两个路由相关的对象
$router 当前路由对象 | $router路由管理器对象
切换路由使用时 路由管理器对象 $router
语法:this.$router.push({name:"目标路由的name属性值"})
2、通过js切换路由的方式
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>路由的切换</title> </head> <body> <div id="app"> <router-view></router-view> <!--根据名称去切换路由 官方推荐--> <hr/> <router-link :to="{name:'login'}">登录组件</router-link> <router-link :to="{name:'register'}">注册组件</router-link> <hr/> <button @click="toLogin()">切换到登录</button> </div> </body> </html> <script src="../js/vue-min.js"></script> <script src="../js/vue-router.js"></script> <script> const login = { template: `<div><h2>登录组件</h2></div>` } const reg = { template: `<div><h2>注册组件</h2></div>` } //路由错误时的提示组件 const notFound = { template: `<div><h2>你访问的路径有误,请重新输入</h2></div>` } //2、创建路由 1、管理组件 2、配置路由规则 const router = new VueRouter({ // 指定路由规则 routes: [ {path: "/", redirect: "/login"},//配置根路由 切换方式为:重定向到指定路径 {path: "/login", component: login, name: "login"}, {path: "/register", component: reg, name: "register"}, {path: "*", component: notFound} //路径错误时的提示 ] }); new Vue({ el: "#app", data: { msg: "route的基本使用" }, methods: { toLogin() { // 发送请求 // axios.get("url").then(()=>{}) // 正确响应时切换到登录页面 当前路由 routrt VueRouter路由管理对象 console.log(this); //使用路由管理器对象 推入新的路由对象 替换原有的路由 this.$router.push({name:"login"}); } }, // 3.将路由对象注册给vue实例 router: router }) </script>
2、切换到同一路由报错
通过js程序切换路由时 存在的一个错误提示
原因:反复切换同一路由组件出现错误提示:
vue-router.js:2071 Uncaught (in promise) NavigationDuplicated: Avoided redundant navigation to current location: "/login".
解决方案:
(1)通过程序去切换路由时,添加一个判断,如果要切换的是对应的路由,使用的路由组件不切换
methods: { toLogin() { console.log(this); //使用路由管理器对象 推入新的路由对象 替换原有的路由 if(this.$route.name!="login"){ //判断 当前的路由对象是否要切换的路由 this.$router.push({name:"login"}); } }, toRegister() { //使用路由管理器对象 推入新的路由对象 替换原有的路由 if(this.$route.name!="register") this.$router.push({name:"register"}); } }
(2)通过配置的形式
反复切换同一个路由出现问题的解决方案 (配置信息)
const VueRouterPush = VueRouter.prototype.push VueRouter.prototype.push = function push (to) { return VueRouterPush.call(this, to).catch(err => err) }
四、默认路由
作用:用来在第一次进入界面是显示一个默认的组件
//2、创建路由 1、管理组件 2、配置路由规则 const router = new VueRouter({ // 指定路由规则 routes: [ {path: "/", redirect: "/login"},//配置根路由 切换方式为:重定向到指定路径 {path: "/login", component: login,name:"login"}, {path: "/register", component: reg,name:"register"}, {path: "*", component: notFound} //路径错误时的提示 ] });
五、路由中参数传递
1、第一种方式传递参数 传统方式
(1)通过?号形式拼接参数
<router-link to="/login?id=21&name=zhangsan">我要登录</router-link>
(2)组件中获取参数
const login = { template:'<h1>用户登录</h1>', data(){return {}}, methods:{}, created(){ console.log("=============>"+this.$route.query.id+"======>"+this.$route.query.name); } };
2、第二种方式传递参数 restful风格
指定动词: get post put delete
(1)通过使用路径方式传递参数
<router-link to="/register/24/张三">我要注册</router-link> var router = new VueRouter({ routes:[ {path:'/register/:id/:name',component:register} //定义路径中获取对应参数 ] });
(2)组件中获取参数
const register = { template:'<h1>用户注册{{ $route.params.name }}</h1>', created(){ console.log("注册组件中id: "+this.$route.params.id+this.$route.params.name); } };
六、 嵌套路由
1、声明最外层和内层路由
<template id="product"> <div> <h1>商品管理</h1> <router-link to="/product/add">商品添加</router-link> <router-link to="/product/edit">商品编辑</router-link> <router-view></router-view> </div> </template> //声明组件模板 const product={ template:'#product' }; const add = { template:'<h4>商品添加</h4>' }; const edit = { template:'<h4>商品编辑</h4>' };
2、创建路由对象含有嵌套路由
const router = new VueRouter({ routes:[ { path:'/product', component:product, children:[ {path:'add',component: add}, {path:'edit',component: edit}, ] }, ] });
3、注册路由对象
const app = new Vue({ el: "#app", data: {}, methods: {}, router,//定义路由对象 });
4、测试路由
<router-link to="/product">商品管理</router-link> <router-view></router-view>
七、综合案例
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>router</title> </head> <body> <div id="app"> {{msg}} <a href="#/users">点击切换展示所有</a> <router-link to="/users">点击切换展示所有</router-link> <router-link :to="{path:'/users'}">点击切换展示所有</router-link> <router-link :to="{name:'Users'}">点击切换展示所有</router-link> <hr/> <a href="#/users/userAdd">添加</a> <!--4、在vue实例范围内使用路由选中组件--> <router-view/> </div> </body> </html> <!--展示所有用户组件模板template--> <template id="users"> <div> <table border="1"> <tr> <td>编号</td> <td>名称</td> <td>年龄</td> <td>薪资</td> <td>操作</td> </tr> <tr v-for="(user,index) in users" :key="user.id"> <td>{{user.id}}</td> <td>{{user.name}}</td> <td v-text="user.age"></td> <td v-html="user.salary"></td> <td><a href="">删除</a> | <router-link :to="{name:'UserUpdate',query:{id:user.id}}">修改</router-link></td> </tr> </table> <!--展示子路由选中的组件--> <router-view/> </div> </template> <script src="../js/vue-min.js"></script> <script src="../js/vue-router.js"></script> <script> //1、创建组件 //展示所有用户组件 const users = { template:"#users", data(){ return{ users:[] } }, created(){ //发送异步请求 接收数据交给当前组件管理 /* axios.get("url").then(response=>{ this.users = response.data }).catch(erro=>{ })*/ this.users = [{id:1 , name:"王恒杰",age:18,salary:18},{id:2 , name:"杨福君",age:58,salary:58}] } } const userAdd = { template:`<div>名称:<input type="text" v-model="user.name"/> <br/> 年龄:<input type="text" v-model="user.age"/><br/> 薪资:<input type="text" v-model="user.salary"/><br/> <button @click="addUser">添加</button></div>` , data(){ return{ user:{} } }, methods:{ addUser(){ //发送异步请求 完成数据添加 用户数据接收 /*axios.post("url", this.user).then(response=>{ }).catch(error=>{ })*/ //2 切换路由 this $route 当前路由对象 Object | $router 当前路由管理器对象 VueRouter this.$router.push({name:"Users"}) } } } const userUpdate = { template:`<div>编号:<input type="text" v-model="user.id"/> <br/>名称:<input type="text" v-model="user.name"/> <br/> 年龄:<input type="text" v-model="user.age"/><br/> 薪资:<input type="text" v-model="user.salary"/><br/><button @click="updateUser">修改</button></div>` , data(){ return{ user:{} } }, methods:{ updateUser(){ //切换路由 切换到展示所有路由 this.$router.push({name:"Users"}) } }, created(){ let id = this.$route.query.id; //发送异步请求查询数据 数据回显 /*axios.get("url?id="+id).then(response=>{ this.user= response.data }).catch(error=>{})*/ this.user = {id,name:"liuh",age:18,salary:18} } } //2、创建路由 a、管理组件 b、配置路由规则 [/users - 组件] const router = new VueRouter({ routes:[ {path:"/users" , component:users , name:"Users" , /*配置路由的子路由 注意: path属性中不能以/开头 切换子路由:/users/userAdd */ children:[ {path:"userAdd" , component:userAdd , name:"UserAdd"}, {path:"userUpdate" , component:userUpdate , name:"UserUpdate"} ] } , /*{path:"/userAdd" , component:userAdd , name:"UserAdd"}*/ ] }); new Vue({ el:"#app" , data:{ msg:"路由嵌套!" }, //3、将路由交由vue实例管理 router }) </script>