2.1前端路由与后端路由区别
- 后端路由:类似 jsp(java)/node.js 后端来判断跳转到哪个页面
- 前端每个页面都已经写好1.html 2.html
- 后端按照逻辑进行重定向跳转
- 前端路由:类似vue-router
- 同一个链接
- 例如 localhost:8080
- localhost:8080/home
- localhost:8080/me
会按照后面的 "/" "/home" "/me"进行解析,从而从打包好的js中获取需要的js/css等资源
- 脚手架会将所有的代码进行压缩打包到一个js中,按照不同的路径进行选择所对应的资源(js/css等)
2.2 hash与history区别
- hash实现【可回退/难看】
- 前端的路由和后端的路由在实现技术上不一样,但是原理都是一样的。在 HTML5 的 history API 出现之前,前端的路由都是通过 hash 来实现的,hash 能兼容低版本的浏览器。如果我们把上面例子中提到的 3 个页面用 hash 来实现的话,它的 URI 规则中需要带上 #。
- hash值的改变,都会在浏览器的访问历史中增加一个记录。因此我们能通过浏览器的回退、前进按钮控制hash的切换。
1 http://10.0.0.1/ 2 http://10.0.0.1/#/about 3 http://10.0.0.1/#/concat
- history API实现
- 主要的两个API history.pushState()和history.repalceState()
- 其中push可回退
- replace不可回退
- 相比hash更美观
1 http://10.0.0.1/ 2 http://10.0.0.1/about 3 http://10.0.0.1/concat
2.3路由基本配置
- 安装Vue-router
1 npm install vue-router
- 导入vue和router模块 并使用
1 import Vue from 'vue' 2 import VueRouter from 'vue-router' 3 4 Vue.use(VueRouter)
- 创建路由对象【新建router实例对象】
- 懒加载:当打包构建应用时,JavaScript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了。
1 //路由懒加载 2 const Home = () => import('../views/home/Home.vue') 3 const Category = () => import('../views/category/Category.vue') 4 const Me = () => import('../views/me/Me.vue') 5 6 7 //2.创建路由对象 8 const routes = [ 9 { 10 path:'', 11 redirect:'/home' 12 }, 13 { 14 path:'/home', 15 component:Home 16 }, 17 { 18 path:'/me', 19 component:Me 20 }, 21 { 22 path:'/category', 23 component:Category 24 } 25 26 ] 27 const router = new VueRouter({ 28 routes : routes, 29 mode : 'history' 30 })
- 导出路由
1 //导出路由 2 export default router
- 在需要使用路由的页面 使用router-view
- 此处取app.vue文件作为示例 当加入<router-view></router-view>即代表前端路由生效
1 <template> 2 <div id="app"> 3 <router-view></router-view> 4 <maintabbar></maintabbar> 5 </div> 6 </template> 7 8 <script> 9 10 import maintabbar from './components/tabbar/maintabbar.vue' 11 export default { 12 name: 'App', 13 components: { 14 maintabbar: maintabbar 15 } 16 } 17 </script> 18 <style> 19 @import url("assets/css/base.css"); 20 </style>
注意点:
- 当操作默认路由时 即直接访问localhost:8080/ 应用 redirect重定向
- 创建实例时mode:history即可使用history【上方有和hash区别】
2.4动态路由(传参)
- 可只传单参 /user/:id 接收单个参数
- 也可传递多个参数 接收对象参数
1 //修改路由配置 2 { 3 path: '/describe/:id', 4 name: 'Describe', 5 component: Describe 6 }
在目标路径下接收参数
this.$route.params.id
在目标路径下接受多个对象
1 this.$route.query
2.5嵌套路由
- 路由配置修改【children关键词】
const router = new VueRouter({ routes: [ { path: '/user/:id', component: User, children: [ { // 当 /user/:id/profile 匹配成功, // UserProfile 会被渲染在 User 的 <router-view> 中 path: 'profile', component: UserProfile }, { // 当 /user/:id/posts 匹配成功 // UserPosts 会被渲染在 User 的 <router-view> 中 path: 'posts', component: UserPosts } ] } ] })
2.6导航守卫
- 全局首位
- 全局前置守卫
1 const router = new VueRouter({ ... }) 2 3 router.beforeEach((to, from, next) => { 4 //。。 5 next() 6 })
- 全局后置守卫(无next)
1 router.afterEach((to, from) => { 2 // ... 3 })
- 全局前置守卫
-
- 每个守卫方法接收三个参数:
-
to: Route
: 即将要进入的目标 路由对象 -
from: Route
: 当前导航正要离开的路由 -
next: Function
: 一定要调用该方法来 resolve 这个钩子。执行效果依赖next
方法的调用参数。
-
- 每个守卫方法接收三个参数:
***确保要调用 next
方法,否则钩子就不会被 resolved
- 路由独享守卫【用法类似 声明在routes中】
1 const router = new VueRouter({ 2 routes: [ 3 { 4 path: '/foo', 5 component: Foo, 6 beforeEnter: (to, from, next) => { 7 // ... 8 } 9 } 10 ] 11 })
- 组件守卫【用法类似 声明在组件中】
1 const Foo = { 2 template: `...`, 3 beforeRouteEnter (to, from, next) { 4 // 在渲染该组件的对应路由被 confirm 前调用 5 // 不!能!获取组件实例 `this` 6 // 因为当守卫执行前,组件实例还没被创建 7 }, 8 beforeRouteUpdate (to, from, next) { 9 // 在当前路由改变,但是该组件被复用时调用 10 // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候, 11 // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。 12 // 可以访问组件实例 `this` 13 }, 14 beforeRouteLeave (to, from, next) { 15 // 导航离开该组件的对应路由时调用 16 // 可以访问组件实例 `this` 17 } 18 }