1.前端路由1.1为什么做单页面应用

(1)传统的开发方式 url改变后,立马发送请求,响应整个页面,有可能资源过多,传统开发会让前端的页面出现 “白屏” 用户体验不好(2)SPA 单页面应用 : 锚点值的改变后,不会立刻发送请求,而是在某个合适的时机,发送ajax请求,局部改变页面中的数据,页面不立刻跳转用户体验好1.2前端路由的原理

<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title></title></head><body> <!-- SPA : Single Page Application 前端路由 1.锚点值 监视 2.ajax获取动态的数据 3.核心点是锚点值的改变 前端中 vue|react|angular 都很适合做单页面应用 --> <a href="#/login">登录页面</a> <a href="#/register">注册页面</a> <div id="app"> </div> <script type="text/javascript"> // onhashchange 事件 url上的锚点数据(#/xxx改变) var oDiv = document.getElementById('app'); window.onhashchange = function(){ console.log(location.hash); // 根据不同的锚点值,对页面不同的切换。 switch (location.hash) { case '#/login': oDiv.innerHTML = '<h3>登录页面</h3>'; break; case '#/register': oDiv.innerHTML = '<h3>注册页面</h3>'; break; default: // statements_def break; } } </script></body></html>

1.3vue-router的基本使用

npm init --yesnpm install vue-router --save


1.4vue-router集成

它是vue中核心插件1. 下载vue-router npm init --yes npm install vue-router --save - 引入vue-router的模块 默认会抛出一个VueRouter对象 另外还有两个全局的组件router-link 和router-view2. Vue.use(VueRouter)3. 创建路由对象

<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title></title></head><body> <div id="app"></div> <script type="text/javascript" src="./node_modules/vue/dist/vue.min.js"></script> <!-- 1.引入 vue-router的对象 --> <script type="text/javascript" src="./node_modules/vue-router/dist/vue-router.js"></script> <!-- 全局的VueRouter对象 vue-router 还给咱们提供了两个全局的组件 router-link router-view--> <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({ // 配置路由对象 routes:[ { path:'/login', component:Login }, { path:'/register', component:Register } ] }); 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> ` }; new Vue({ el:'#app', components:{ App }, router, template:`<App />` }); </script></body></html>


1.5命名路由

给当前的配置路由信息对象设置name:'login'属性:to = "{name:'login'}"

<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title></title></head><body> <div id="app"></div> <script type="text/javascript" src="./node_modules/vue/dist/vue.min.js"></script> <!-- 1.引入 vue-router的对象 --> <script type="text/javascript" src="./node_modules/vue-router/dist/vue-router.js"></script> <!-- 全局的VueRouter对象 vue-router 还给咱们提供了两个全局的组件 router-link router-view--> <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({ // 配置路由对象 routes:[ { path:'/login', name:'login', component:Login }, { path:'/register', name:'register', component:Register } ] }); 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> ` }; new Vue({ el:'#app', components:{ App }, router, template:`<App />` }); </script></body></html>

1.6路由范式----路由参数之params,query

(1)xxxx.html#/user/1 配置路由对象中 { path:'/user/:id', component:User } <router-link :to = "{name:'user',params:{id:1}}"></router-link> (2)xxxx.html#/user?userId = 1 { path:'/user' } <router-link :to = "{name:'user',query:{id:1}}"></router-link> 在组件内部通过this.$route 获取路由信息对象

<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title></title></head><body> <div id="app"></div> <script type="text/javascript" src="./node_modules/vue/dist/vue.min.js"></script> <!-- 1.引入 vue-router的对象 --> <script type="text/javascript" src="./node_modules/vue-router/dist/vue-router.js"></script> <!-- 全局的VueRouter对象 vue-router 还给咱们提供了两个全局的组件 router-link router-view--> <script type="text/javascript"> // 路由范式 // (1)xxxx.html#/user/1 params // (2)xxxx.html#/user?userId = 2 query // 2.让Vue使用该VueRouter创建 Vue.use(VueRouter); var UserParams = { template:` <div>我是用户1</div> `, created(){ console.log("用户1this.$route--------",this.$route); console.log("用户1this.$route.params.userId--------",this.$route.params.userId); // 发送ajax请求 console.log("this.$router--------",this.$router); } }; var UserQuery = { template:` <div>我是用户2</div> `, created(){ console.log("用户2this.$route--------",this.$route); // 发送ajax请求 console.log("用户2this.$router--------",this.$router); } }; // 3.创建一个路由对象 var router = new VueRouter({ // 配置路由对象 routes:[ { // 动态的路由参数 以冒号开头 path:'/user/:userId', name:'userp', component:UserParams }, { path:'/user', name:'userq', component:UserQuery } ] }); var App = { template:` <div> <!--router-link默认会被渲染成a标签 to属性默认会被渲染成href属性--> <router-link :to="{name:'userp',params:{userId:1}}">用户1</router-link> <router-link :to="{name:'userq',query:{userId:2}}">用户2</router-link> <!--路由组件的出口--> <router-view></router-view> </div> ` }; new Vue({ el:'#app', components:{ App }, router, template:`<App />` }); </script></body></html>

1.7编程式导航

<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title></title></head><body> <div id="app"></div> <script type="text/javascript" src="./node_modules/vue/dist/vue.min.js"></script> <!-- 1.引入 vue-router的对象 --> <script type="text/javascript" src="./node_modules/vue-router/dist/vue-router.js"></script> <!-- 全局的VueRouter对象 vue-router 还给咱们提供了两个全局的组件 router-link router-view--> <script type="text/javascript"> // 路由范式 // (1)xxxx.html#/user/1 params // (2)xxxx.html#/user?userId = 2 query // 2.让Vue使用该VueRouter创建 Vue.use(VueRouter); var UserParams = { template:` <div>我是用户1</div> `, created(){ console.log("用户1this.$route--------",this.$route); console.log("用户1this.$route.params.userId--------",this.$route.params.userId); // 发送ajax请求 console.log("this.$router--------",this.$router); } }; var UserQuery = { template:` <div>我是用户2</div> `, created(){ console.log("用户2this.$route--------",this.$route); // 发送ajax请求 console.log("用户2this.$router--------",this.$router); } }; // 3.创建一个路由对象 var router = new VueRouter({ // 配置路由对象 routes:[ { // 动态的路由参数 以冒号开头 path:'/user/:userId', name:'userp', component:UserParams }, { path:'/user', name:'userq', component:UserQuery } ] }); var App = { template:` <div> <button @click = 'paramsHandler'>用户1</button> <button @click = 'queryHandler'>用户2</button> <!--路由组件的出口--> <router-view></router-view> </div> `, methods:{ paramsHandler(){ // 编程式导航 this.$router.push({ name: 'userp', params: { userId: 123 }}) }, queryHandler(){ this.$router.push({ name: 'userq', query: { userId: 321 }}) } } }; new Vue({ el:'#app', components:{ App }, router, template:`<App />` }); </script></body></html>

1.8嵌套路由

一个router-view 嵌套另外一个router-view

<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title></title></head><body> <div id="app"></div> <script type="text/javascript" src="./node_modules/vue/dist/vue.min.js"></script> <!-- 1.引入 vue-router的对象 --> <script type="text/javascript" src="./node_modules/vue-router/dist/vue-router.js"></script> <!-- 全局的VueRouter对象 vue-router 还给咱们提供了两个全局的组件 router-link router-view--> <script type="text/javascript"> // 嵌套路由: // 需求:进入首页之后 点击 音乐 /home/music 电影 /home/movie Vue.use(VueRouter); var Home = { template: ` <div> <br /> <router-link to = '/home/music'>音乐</router-link> <router-link to = '/home/movie'>电影</router-link> <!--子路由组件的出口--> <router-view></router-view> </div> ` }; var Music = { template: ` <div>我是音乐</div> ` }; var Movie = { template: ` <div>我是电影</div> ` }; // 3.创建一个路由对象 var router = new VueRouter({ // 配置路由对象 routes: [{ path: '/', // redirect:{name:'home'} redirect: '/home' }, { // 动态的路由参数 以冒号开头 path: '/home', //这里不能使用别名,会报警告 // name:'home', component: Home, children: [ // 动态路由匹配 表示你的子组件中的结构是不同的 // 当访问/home时,Home组件的出口是不会渲染任何内容,这是因为没有匹配到合适的子路由 { path: '', component: Music }, { path: 'music', component: Music, }, { path: 'movie', component: Movie } ] } ] }); var App = { template: ` <div> <router-link to = "/home">首页</router-link> <!--路由组件的出口--> <router-view></router-view> </div> ` }; new Vue({ el: '#app', components: { App }, router, template: `<App />` }); </script></body></html>

1.9动态路由匹配

// 共同的子组件 var ComDesc = { data() { return { msg: '' } }, template: ` <div> 我是{{msg}} </div> `, created() { // alert(1); this.msg = 'andorid'; }, watch: {// 提醒一下,当使用路由参数时,例如从 /user/foo 导航到 /user/bar,原来的组件实例会被复用。//因为两个路由都渲染同个组件,比起销毁再创建,复用则显得更加高效。不过,这也意味着组件的生命周期钩子不会再被调用。 '$route' (to, from) { // 对路由变化作出响应... console.log("to------------------", to); console.log("from------------------", from); this.msg = to.params.id; } } }

<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title></title></head><body> <div id="app"></div> <script type="text/javascript" src="./node_modules/vue/dist/vue.min.js"></script> <!-- 1.引入 vue-router的对象 --> <script type="text/javascript" src="./node_modules/vue-router/dist/vue-router.js"></script> <!-- 全局的VueRouter对象 vue-router 还给咱们提供了两个全局的组件 router-link router-view--> <script type="text/javascript"> // 嵌套路由: // 需求:进入首页之后 点击 音乐 /home/music 电影 /home/movie Vue.use(VueRouter); var Timeline = { template: ` <div> <router-link :to = "{name:'comDesc',params:{id:'android'}}">Android</router-link> <router-link :to = "{name:'comDesc',params:{id:'frontend'}}">前端</router-link> <router-view></router-view> </div> ` }; var Pins = { template: ` <div> 我是沸点 </div> ` }; // 共同的子组件 var ComDesc = { data() { return { msg: '' } }, template: ` <div> 我是{{msg}} </div> `, created() { // alert(1); this.msg = 'andorid'; }, watch: {// 提醒一下,当使用路由参数时,例如从 /user/foo 导航到 /user/bar,原来的组件实例会被复用。//因为两个路由都渲染同个组件,比起销毁再创建,复用则显得更加高效。不过,这也意味着组件的生命周期钩子不会再被调用。 '$route' (to, from) { // 对路由变化作出响应... console.log("to------------------", to); console.log("from------------------", from); this.msg = to.params.id; } } } // 3.创建一个路由对象 var router = new VueRouter({ // 配置路由对象 routes: [{ // 动态的路由参数 以冒号开头 path: '/timeline', component: Timeline, children: [{ path: "", component: ComDesc }, { path: '/timelin/:id', name: 'comDesc', component: ComDesc } ] }, { // 动态的路由参数 以冒号开头 path: '/pins', name: 'pins', component: Pins, } ] }); var App = { template: ` <div> <router-link to = "/timeline">首页</router-link> <router-link to = "/pins">沸点</router-link> <!--路由组件的出口--> <router-view></router-view> </div> ` }; new Vue({ el: '#app', components: { App }, router, template: `<App />` }); </script></body></html>

1.10keep-alive

<keep-alive> <router-view></router-view></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="./node_modules/vue/dist/vue.min.js"></script> <!-- 1.引入 vue-router的对象 --> <script type="text/javascript" src="./node_modules/vue-router/dist/vue-router.js"></script> <!-- 全局的VueRouter对象 vue-router 还给咱们提供了两个全局的组件 router-link router-view--> <script type="text/javascript"> // 嵌套路由: // 需求:进入首页之后 点击 音乐 /home/music 电影 /home/movie Vue.use(VueRouter); var Timeline = { template: ` <div> 我是首页 </div> `, created() { console.log('首页组件创建了'); }, mounted() { console.log('首页组件DOM加载了') }, destroyed() { console.log('首页销毁了'); } }; var Pins = { template: ` <div> <h4 @click = 'clickHandler'> 我是沸点</h4> </div> `, methods: { clickHandler(e) { e.target.style.color = 'red'; } }, created() { console.log('沸点组件创建了'); }, mounted() { console.log('沸点组件DOM加载了') }, destroyed() { console.log('沸点销毁了'); } }; // 3.创建一个路由对象 var router = new VueRouter({ // 配置路由对象 routes: [{ // 动态的路由参数 以冒号开头 path: '/timeline', component: Timeline }, { // 动态的路由参数 以冒号开头 path: '/pins', name: 'pins', component: Pins, } ] }); var App = { template: ` <div> <router-link to = "/timeline">首页</router-link> <router-link to = "/pins">沸点</router-link> <!--路由组件的出口--> <keep-alive> <router-view></router-view> </keep-alive> </div> ` }; new Vue({ el: '#app', components: { App }, router, template: `<App />` }); </script></body></html>


1.11路由meta实现权限控制

<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title></title></head><body> <div id="app"></div> <script type="text/javascript" src="./node_modules/vue/dist/vue.min.js"></script> <!-- 1.引入 vue-router的对象 --> <script type="text/javascript" src="./node_modules/vue-router/dist/vue-router.js"></script> <!-- 全局的VueRouter对象 vue-router 还给咱们提供了两个全局的组件 router-link router-view--> <script type="text/javascript"> // 嵌套路由: // 需求:进入首页之后 点击 音乐 /home/music 电影 /home/movie Vue.use(VueRouter); // 导航栏上 有首页 智能题库 登录退出 四个按钮 // 用户访问首页时 看到的是首页的内容 // 1.当用户访问智能题库时,此时我们检测用户是否有权限访问该智能题库的内容, // 如果没有 检测用户是否登录过,如果没有,则跳转登录页面,登录完成之后。 // 在localStroage中通存储该用户的用户名和密码,并且立刻跳转到智能题库页面 // 2.当用户点击黜退,该用户直接删除 var Home = { template: ` <div> 我是首页 </div> ` }; var Questionbank = { template: ` <div> 我是题库 </div> ` }; // 登录组件 var Login = { data(){ return { name:'', pwd:'' } }, template:` <div> <input type="text" v-model = 'name' /> <input type="text" v-model = 'pwd' /> <input type="button" value = '登录' @click = 'loginHandler'/> </div> `, methods:{ loginHandler(){ alert(1); // 要登录了 // 存储用户名会被密码 保存到 localStorage 然后跳转相应的路由(智能题库) localStorage.setItem('user', {name:this.name,pwd:this.pwd}); // 编程式导航 this.$router.push({name:'questionbank'}); } } }; // 3.创建一个路由对象 var router = new VueRouter({ // 配置路由对象 routes: [{ // 动态的路由参数 以冒号开头 path: '/home', component: Home }, { // 动态的路由参数 以冒号开头 path: '/questionbank', name: 'questionbank', component: Questionbank, // 给未来的路由 做权限控制 meta:{ // 表明访问该组件时需要登录 auth: true } }, { path:'/login', component:Login } ] }); // 全局的导航守卫 router.beforeEach(function(to,from,next){ console.log(to.meta.auth); console.log(from); // 如果不调用next 那么页面会卡主 if(to.meta.auth){ // 用户点击了智能题库的导航 该用户未登录,需要登录判断 if (localStorage.getItem('user')) { // 不为空 放行 next() }else{ // 为空 进入登录页面 next({path:'/login'}); } }else{ // 直接放行 next(); } }); var App = { template: ` <div> <router-link to = "/home">首页</router-link> <router-link to = "/questionbank">智能题库</router-link> <router-link to = '/login'>登录</router-link> <a href="javascript:void(0)" @click = 'clear'>退出</a> <!--路由组件的出口--> <keep-alive> <router-view></router-view> </keep-alive> </div> `, methods:{ clear(){ // 退出 localStorage.removeItem('user'); this.$router.push('/login'); } } }; new Vue({ el: '#app', components: { App }, router, template: `<App />` }); </script></body></html>