如今的应用都流行SPA应用(single page application)html
传统的项目大多使用多页面结构,须要切换内容的时候咱们每每会进行单个HTML文件的跳转,这个时候网络、性能影响,浏览器会出现不定时间的空白界面,用户体验很差前端
单页面应用就是用户经过某些操做地址栏url以后,动态的进行不一样模板内容的无刷新切换,用户体验好。vue
Vue中会使用官方提供的vue-router插件来使用单页面,原理就是经过检测地址栏变化后对应的路由组件进行切换(卸载和安装)webpack
cnpm install vue-router -S or yarn add vue-routerweb
在Vue中,$router指向的是大路由,routes是路由配置数组, $route指向的是当前活跃的路由。vue-router
1.引入vue-router,若是是在脚手架中,引入VueRouter以后,须要经过Vue.use来注册插件npm
router/index.js文件编程
import Vue from 'vue'后端
import Router from 'vue-router'api
Vue.use(Router)
2.建立router路由器
new Router({
routes:[
{path:"/home",component:Home}
]
})
3.建立路由表并配置在路由器中
var routes =[
{path,component}//path为路径,component为路劲对应的路由组件
]
var router = new Router({
routes
})
export default router
4.在根实例里注入router,目的是为了让全部的组件里都能经过this.$router、this.$route来使用路由的相关功能api
import router from "./router"
new Vue({
el:"#app",
router, //注册一下 让组件能够经过this.$router or this.$route 使用路由相关的api属性或方法
template:"
components:{App}
})
5. 利用router-view来指定路由切换的位置
6. 时候router-link来建立切换的工具,会渲染成a标签,添加to属性来设置更改的path信息,且会根据当前路由的变化为a标签添加对应的router-link-active/router-link-exact-active(彻底匹配成功)类名
.router-link-active{
color:red;
}
懒加载也叫延迟加载,即在须要的时候进行加载,随用随载。在单页应用中,若是没有应用懒加载,运用webpack打包后的文件将会异常的大,形成进入首页时,须要加载的内容过多,延时过长,不利于用户体验,而运用懒加载则能够将页面进行划分,须要的时候加载页面,能够有效的分担首页所承担的加载压力,坚守首页加载用时。
非按需加载则会把全部的路由组件块的js打包在一块儿。当业务包很大的时候建议用路由的按需加载(懒加载)。
按需加载会在页面第一次请求的时候,把相关路由组件块的js添加上:
{
path:'/about',
name:'about',
component:()=>import('@/views/About') //采用了路由懒加载方式
}
在建立路由表的时候,能够为每个路由对象建立children属性,值为数组,在这个里面又能够配置一些路由对象来使用多极路由,注意:一级路由path前加“/"
const routes =[
{path:"/main",component:AppMain},
{path:"/news",component:AppNews,children:[
{path:'inside',component:AppNewsInside},
{path:'outside',component:AppNewsOutside}
]},
]
二级路由组件的切换位置依然由router-view来指定(指定在父级路由组件的模板中)
当咱们进入应用,默认想显示某一个路由组件,或者当咱们进入某一级路由组件的时候其某一个子路由组件,咱们能够配置路由:
{path:'',component:Main}
当咱们须要进入以后进行重定向到其余路由的时候,或者url与路由表不匹配的时候:
{path:'/',redirect:'/main'}
///...放在最下面
{path:'*',redirect:'/main'}
咱们能够给路由对象配置name属性,这样的话,咱们在跳转的时候直接写name:main就会快速的找到此name属性对应的路由,不须要写大量的url path路径了
<router-link
v-for="nav in navs"
:key="nav.id"
:to="{name:nav.name}"
>
{{nav.title}}
//router/index.js的配置
var router= new VueRouter({
routes:[
{
path:"xxx",
component:xxx,
children:[
{path:"guonei",component:()=>import("@/views/Guonei"),name:"guonei"},
{path:"guoji",component:()=>import("@/views/guoji"),name:"guoji"},
]
}
]
})
有时候咱们须要在路由跳转的时候跟上参数,路由传参的参数主要有两种:路由参数、queryString参数。
路由参数须要在路由表里设置
{path:'/user/:id',component:User}
上面的代码就是给User路由配置接收id的参数,多个参数继续在后面设置
在组件中能够经过this.$route.params来使用
queryString参数不须要在路由表设置接收,直接设置 ? 后面的内容,在路由组件中经过this.$route.query接收
正在热映...
<router-link
v-for="data in datalist"
:key="data"
:to="{
name:'detail',
params:{id:data},
query:{title:'文章二'}
}"
tag="li"
>
{{data}}
router.js
{
name:"detail",
path:"/detail/:id",
component:Detail
}
在组件中接收路由参数须要this.$route.params.id代码冗余,如今能够在路由表里配置props:true
{path:'detail/:id',component:AppNewsDetail,name:'detail',props:true}
在路由本身中能够经过props接收id参数去使用了
props:['id']
router-link的to属性,默认写的是path(路由的路径),能够经过设置一个对象,来匹配更多
:to='{name:"detail",params:{id:_new.id},query:{content:_new.content}}'
name是要跳转的路由的名字,也能够写path来指定路径,可是path的时候就不能使用params传参,params是传路由参数query传queryString参数
replace属性能够控制router-link的跳转不被记录
active-class属性能够控制路径切换的时候对应的router-link渲染的dom添加的类名
有的时候须要在跳转前进行一些动做,router-link直接跳转,须要在方法里面使用$router的方法
this.$router.push()
#### 路由模式
为了构建SPA(单页面应用),须要引入前端路由系统,这也就是Vue-router存在的意义。前端路由的核心,就在于---改变视图的同时不会向后端发出请求。
路由有两种模式:hash、history,默认会使用hash模式,可是若是url里面不想出现丑陋hash值,在new VueRouter的时候配置mode值为history来改变路由模式,本质使用H5的history.pushState方法来更改url,不会引发刷新。
history模式,会出现404的状况,须要后台配置
由于咱们的应用是个单页客户端应用,若是后台没有正确的配置当用户浏览器直接访问 http://oursite.com/user/id 就会返回 404,这就很差看了。
因此要在服务端增长一个覆盖全部状况的候选资源:若是URL匹配不到任何静态资源,则应该返回同一个index.html页面,这个页面就是你app的依赖页面
路由原理:
hash路由 ====> window.onhashchange监听路径的切换
history路由 ====> window.onpopstate监听路径的切换
#### 路由守卫
在某些状况下,当路由跳转前或跳转后、进入、离开某一个路由前、后,须要作某些操做,就可使用路由钩子来监听路由的变换
//进入到某个路由组件以前
router.beforeEach((to,from,next)=>{
//会在任意路由跳转前执行,next必定要记着执行,否则路由不能跳转了
console.log('beforeEach')
console.log(to,from)
next()
})
//进入到某个路由组件以后
router.afterEach((to,from)=>{
//会在任意路由跳转后执行
console.log('afterEach')
})
只有beforeEnter,在进入前执行,to参数就是当前路由
routes:[
{
path:'/foo',
component:Foo,
//当进入到foo路由以前,就会触发
beforeEnter:(to,from,next)=>{
//...
next()//必须执行next以后,对应的Foo组件才能够正常显示出来
}
}
]
//进入到某个组件以前的拦截,获取不到组件内部的this
beforeRouteEnter(to,from,next){
//在渲染该组件的对应路由被 confirm前调用
//不能获取组件实例`this`
//由于当守卫执行前,组件实例尚未被建立
},
beforeRouteUpdate(to,from,next){
//在当前路由改变,可是该组件被复用时调用
//举例来讲,对于一个带有动态参数的路径/foo/:id,在/foo/1和/foo/2之间跳转的时候,
//因为会渲染一样的Foo组件,所以组件实例会被复用,而这个钩子就会在这个状况下被调用。
//能够访问组件实例`this`
},
//离开某个组件前的拦截,获取到组件内部的this
beforeRouteLeave(to,from,next){
//导航离开该组件的对应路由时调用
//能够访问实例`this`
}