Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面 SPA(Single Page Application)应用变得易如反掌。
什么是路由?
请看下面这个例子:通过 ajax 请求,更新页面局部内容
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <a href="#/login">登录页面</a> <a href="#/register">注册页面</a> <div id="app"> </div> <script type="text/javascript"> var oDiv = document.getElementById(‘app‘); window.onhashchange = function() { console.log(location.hash); switch (location.hash) { case ‘#/login‘: oDiv.innerHTML = ‘<h2>我是登录页面</h2>‘ break; case ‘#/register‘: oDiv.innerHTML = ‘<h2>我是注册页面</h2>‘ break; default: // statements_def break; } } </script> </body> </html>
那 Vue Router 能干什么?
它能使获取请求更新页面的过程更可配置,也就是简化上面的代码,提供更丰富的配置
看下面这个例子
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <div id="app"></div> <!-- 1.引入vue.js --> <script type="text/javascript" src="../js/vue.min.js"></script> <!-- 2.引入核心的插件vue-router --> <script type="text/javascript" src="../js/node_modules/vue-router/dist/vue-router.min.js"></script> <script type="text/javascript"> // 2.让vue使用该VueRouter创建 Vue.use(VueRouter); //声明组件 var Login = { template: `<div>我是登录页面</div>` }; var Register = { template: `<div>我是注册页面</div>` }; // 3.创建路由对象 var router = new VueRouter({ // 4.配置路由对象 routes: [ // 路由匹配的规则 { path: ‘/login‘, component: Login }, { path: ‘/register‘, component: Register } ] }); // 4.使用两个全局的组件 router-link router-view var App = { template: ` <div> <!--router-link默认会被渲染成a标签,to默认会被渲染成href属性--> <router-link to = ‘/login‘>登录</router-link> <router-link to = ‘/register‘>注册</router-link> <!--路由组件的出口--> <router-view></router-view> </div> ` } // Cannot read property ‘matched‘ of undefined // 5.将配置好的路由对象关联到vue实例化对象中 new Vue({ el: ‘#app‘, router: router, template: `<App />`, components: { App } }); </script> </body> </html>
如果 path 非常长的话,可以给路由的匹配规则起个别名,代码如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <div id="app"></div> <!-- 1.引入vue.js --> <script type="text/javascript" src="../js/vue.min.js"></script> <!-- 2.引入核心的插件vue-router --> <script type="text/javascript" src="../js/node_modules/vue-router/dist/vue-router.min.js"></script> <script type="text/javascript"> // 2.让vue使用该VueRouter创建 如果vue是一个局部作用域的对象 那么必须Vue.use(VueRouter); // Vue.use(VueRouter); //声明组件 var Login = { template: `<div>我是登录页面</div>` }; var Register = { template: `<div>我是注册页面</div>` }; // 3.创建路由对象 var router = new VueRouter({ // 4.配置路由对象 routes: [ // 路由匹配的规则 { path: ‘/login‘, name: ‘login‘, component: Login }, { path: ‘/register‘, name: ‘register‘, component: Register } ] }); // 4.抛出两个全局的组件 router-link router-view var App = { template: ` <div> <!--router-link默认会被渲染成a标签,to默认会被渲染成href属性--> <router-link :to = "{name:‘login‘}">登录</router-link> <router-link :to = "{name:‘register‘}">注册</router-link> <!--路由组件的出口--> <router-view></router-view> </div> ` } // Cannot read property ‘matched‘ of undefined // 5.将配置好的路由对象关联到vue实例化对象中 new Vue({ el: ‘#app‘, router: router, template: `<App />`, components: { App } }); </script> </body> </html>
可以给路由绑定参数
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <div id="app"></div> <!-- 1.先引入vue.js --> <script type="text/javascript" src="../js/vue.min.js"></script> <!-- 2.引入核心的插件vue-router --> <script type="text/javascript" src="../js/node_modules/vue-router/dist/vue-router.min.js"></script> <script type="text/javascript"> // 地址栏 路由范式 //(1)xxxxx.html#/user/1 params 动态路由参数 //(2)ooooo.html#/user?userId = 1 query // Vue.use(VueRouter); //声明组件 $router $route (路由信息对象) var UserParams = { template: `<div>我是用户1</div>`, created() { console.log(this.$router); console.log(this.$route); } }; var UserQuery = { template: `<div>我是用户2</div>`, created() { console.log(this.$route); } }; // 3.创建路由对象 var router = new VueRouter({ // 4.配置路由对象 routes: [ // 路由匹配的规则 { //动态路由参数 以冒号开头 path: ‘/user/:id‘, name: ‘userP‘, component: UserParams }, { path: ‘/user‘, name: ‘userQ‘, component: UserQuery } ] }); // 使用两个全局的组件 router-link router-view var App = { template: ` <div> <!--router-link默认会被渲染成a标签,to默认会被渲染成href属性--> <router-link :to = "{name:‘userP‘,params:{id:1}}">用户1</router-link> <router-link :to = "{name:‘userQ‘,query:{userId:2}}">用户2</router-link> <!--路由组件的出口--> <router-view></router-view> </div> ` } // Cannot read property ‘matched‘ of undefined // 5.将配置好的路由对象关联到vue实例化对象中 new Vue({ el: ‘#app‘, router: router, template: `<App />`, components: { App } }); </script> </body> </html>
路由也可以嵌套使用
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <div id="app"></div> <!-- 1.先引入vue.js --> <script type="text/javascript" src="../js/vue.min.js"></script> <!-- 2.引入核心的插件vue-router --> <script type="text/javascript" src="../js/node_modules/vue-router/dist/vue-router.min.js"></script> <script type="text/javascript"> // 地址栏 路由范式 //(1)xxxxx.html#/user/1 params 动态路由参数 //(2)ooooo.html#/user?userId = 1 query // Vue.use(VueRouter); //声明组件 var Song = { template: `<div>我是歌曲组件</div>`, created() { console.log(this.$router); console.log(this.$route); } }; var Movie = { template: `<div>电影组件</div>`, created() { console.log(this.$route); } }; // 3.创建路由对象 // /home/song // /home/movie var Home = { template: ` <div> 首页内容 <br /> <router-link to = ‘/home/song‘>歌曲</router-link> <router-link to = ‘/home/movie‘>电影</router-link> <router-view></router-view> </div> ` }; var router = new VueRouter({ // 4.配置路由对象 routes: [ // 路由匹配的规则 { //动态路由参数 以冒号开头 path: ‘/home‘, name: ‘home‘, component: Home, children: [{ path: ‘song‘, component: Song }, { path: ‘movie‘, component: Movie }, ] } ] }); // 使用两个全局的组件 router-link router-view var App = { template: ` <div> <!--router-link默认会被渲染成a标签,to默认会被渲染成href属性--> <router-link :to = "{name:‘home‘}">首页</router-link> <!--路由组件的出口--> <router-view></router-view> </div> ` } // Cannot read property ‘matched‘ of undefined // 5.将配置好的路由对象关联到vue实例化对象中 new Vue({ el: ‘#app‘, router: router, template: `<App />`, components: { App } }); </script> </body> </html>
动态路由匹配(地址栏中参数的变化和watch的使用)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <div id="app"></div> <!-- 1.先引入vue.js --> <script type="text/javascript" src="../js/vue.min.js"></script> <!-- 2.引入核心的插件vue-router --> <script type="text/javascript" src="../js/node_modules/vue-router/dist/vue-router.min.js"></script> <script type="text/javascript"> // 地址栏 路由范式 //(1)xxxxx.html#/user/1 params 动态路由参数 //(2)ooooo.html#/user?userId = 1 query // Vue.use(VueRouter); var ComDesc = { data() { return { msg: ‘‘ } }, template: ` <div> {{ msg }} </div> `, created() { this.msg = ‘andorid‘; console.log(1); }, watch: { ‘$route‘(to, from) { // 对路由变化作出响应... console.log(to); console.log(from); this.msg = to.params.id; } } } // 3.创建路由对象 // /timeline/andorid // /timeline/frontend var Timeline = { template: ` <div id = ‘timeline‘> <router-link :to ="{name:‘comDesc‘,params:{id:‘andorid‘}}" >安卓</router-link> <router-link :to ="{name:‘comDesc‘,params:{id:‘frontend‘}}">前端</router-link> <router-view></router-view> </div> ` }; var Pins = { template: ` <div>我是沸点</div> ` } var router = new VueRouter({ // 4.配置路由对象 routes: [ // 路由匹配的规则 { //动态路由参数 以冒号开头 path: ‘/timeline‘, name: ‘timeline‘, component: Timeline, children: [{ name: ‘comDesc‘, path: ‘/timeline/:id‘, component: ComDesc } ] }, { path: ‘/pins‘, component: Pins } ] }); // 使用两个全局的组件 router-link router-view var App = { template: ` <div> <!--router-link默认会被渲染成a标签,to默认会被渲染成href属性--> <router-link to = ‘/timeline‘>首页</router-link> <router-link to = ‘/pins‘>沸点</router-link> <!--路由组件的出口--> <router-view></router-view> </div> ` } // Cannot read property ‘matched‘ of undefined // 5.将配置好的路由对象关联到vue实例化对象中 new Vue({ el: ‘#app‘, router: router, template: `<App />`, components: { App } }); </script> </body> </html>
meta和全局路由的渲染前配置
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <div id="app"> <!-- 声明式的导航 --> <router-link to=‘/home‘>首页</router-link> <router-link to=‘/blog‘>我的博客</router-link> <router-link to=‘/login‘>登录</router-link> <a href="javascript:void(0);" @click=‘clear‘>退出</a> <router-view></router-view> </div> <script type="text/javascript" src="../js/vue.min.js"></script> <script type="text/javascript" src="../js/node_modules/vue-router/dist/vue-router.min.js"></script> <script type="text/javascript"> Vue.use(VueRouter); var Home = { template: ` <div> 我是首页 </div> ` }; var Blog = { template: ` <div> 我是博客 </div> ` }; var Login = { data() { return { name: ‘‘, pwd: ‘‘ } }, template: ` <div> <input type="text" v-model =‘name‘/> <input type="text" v-mode = ‘pwd‘/> <input type="button" value =‘登录‘ @click = ‘login‘/> </div> `, methods: { login() { localStorage.setItem(‘user‘, { name: this.name, pwd: this.pwd }); // 编程式导航 this.$router.push({ name: ‘blog‘ }); } } }; var router = new VueRouter({ routes: [{ path: ‘/‘, redirect: ‘/home‘ }, { path: ‘/home‘, component: Home }, { name: ‘blog‘, path: ‘/blog‘, component: Blog, // 给未来路由 做权限控制 全局路由守卫 来做参照条件 meta: { // 表明用户访问该组件是需要登录,auth是自定义的参数 auth: true } }, { path: ‘/login‘, component: Login } ] }); router.beforeEach((to, from, next) => { console.log(to); console.log(from); if (to.meta.auth) { //用户点击了博客链接 该用户未登录 需要登录判断 准备跳转登录页面 if (localStorage.getItem(‘user‘)) { // alert(1); // 不为空 放行 next(); } else { // alert(2); // 用户需要登录 next({ path: ‘/login‘ }); } } else { // 直接放行 next(); //如果不调用next 就会卡住 } }); new Vue({ el: ‘#app‘, router, methods: { clear() { localStorage.removeItem(‘user‘); this.$router.push(‘/login‘); } } }); </script> </body> </html>
keep-alive在路由中的使用
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <div id="app"> </div> <script type="text/javascript" src="../js/vue.min.js"></script> <script type="text/javascript" src="../js/node_modules/vue-router/dist/vue-router.min.js"></script> <script type="text/javascript"> Vue.use(VueRouter); var Series = { template: ` <div>付费栏目</div> `, created() { console.log(‘付费栏目组件created‘); }, mounted() { console.log(‘付费栏目组件mounted‘); }, destroyed() { console.log(‘付费栏目组件被销毁了‘) } }; var Topics = { template: ` <div> <h3 @click = ‘clickHandler‘>我是专题广场</h3> </div> `, methods: { clickHandler(e) { e.target.style.color = ‘red‘; } }, created() { console.log(‘专题广场组件created‘); }, mounted() { console.log(‘专题广场组件mounted‘); }, destroyed() { console.log(‘专题广场组件被销毁了‘) } }; var router = new VueRouter({ routes: [{ path: ‘/series‘, component: Series }, { path: ‘/topics‘, component: Topics }, ] }); var App = { template: ` <div> <router-link to = ‘/series‘>付费栏目</router-link> <router-link to = ‘/topics‘>专题广场</router-link> <keep-alive> <router-view></router-view> </keep-alive> </div> ` } new Vue({ el: ‘#app‘, template: `<App />`, components: { App }, router }); </script> </body> </html>
原文:https://www.cnblogs.com/jwen1994/p/10988481.html