82344699 2019-12-15
之前有个小伙伴面试被问到:
面试官:不用vue能不能写单页面应用?
答:用angular啊(咳咳,开个玩笑),答案确实是可以的,原生js中有个事件叫做onhashchange,可以在window对象上监听这个事件,通过触发事件动态加载js,实现了没有向服务器发起请求却能通过url和页面关联,这就是所谓的前端路由了。
路由反映了url和页面的映射关系
言归正传,说说vue-router做路由。
先来个简单的demo:npm i vue-router --save-dev
先通过js手动引入vue-router
12345678910111213141516171819202122232425262728293031323334353637383940414243444546 | import Vue from 'vue'import Router from './router5.js'// router.js中代码import Vue from 'vue'import VueRouter from 'vue-router'Vue.use(VueRouter)const home = { template:` <div> <h1>首页路由</h1> </div> `}const details = { template:`<h1>详情路由</h1>`}const router = new VueRouter({ mode: 'history', base: __dirname, routes: [ { path: '/', component: home }, { path: '/details', component:details } ]})new Vue({ router:router, template:` <div> <router-link to="/">首页</router-link> <router-link to="/details">详情</router-link> <router-view></router-view> </div> `}).$mount('#app'); |
大体步骤:1.引入 ==> 2.定义路由组件 ==> 3.创建vue-router实例并配置 ==> 4.注入vue实例
1.引入
import vue和vue-router
Vue.use(VueRouter)
2.定义路由组件
前两步没什么说的
3.路由配置:主要三个内容mode,base,routes
mode主要有两种:
扯远了,第二个base,
4.注入vue实例
这里注意一下经常有这种写法:new Vue({ router, template:<div></div>
}),这里的router写法是ES6写法
1234567891011121314151617181920212223242526272829303132333435363738394041 | <div id="app"> <router-link to="/animals">动物园</router-link> <router-link to="/animals/lion">狮子</router-link> <router-link to="/animals/cat">猫</router-link> <!--第一级路径对应的组件会应用到这里--> <router-view></router-view></div><script> var tempZoo = { template:`<div> 这里是动物园<br> <!--第二级路径对应的组件会应用到这里--> <router-view></router-view> </div>` }; var tempLion = { template:`<img src="lion.png">` } var tempCat = { template:`<img src="cat.png">` } var myRouter = new VueRouter({ routes:[大专栏 [VUE]关于路由哪些事儿an class="line"> {path:"/animals",component:tempZoo, //子层路由规则配置,不能配置默认跳转 children:[ //path地址不能以/开头{path:"lion",component:tempLion},{path:"cat",component:tempCat} ] }, {path:"/*",redirect:"/animals"} ] }); var main = new Vue({ el:"#app", router:myRouter });</script> |
当跳转到某个路由视图时,Vue会为对应的<router-link></router-link>
自动添加class。在添加时按照如下规则:
如果路径 部分匹配 (当前url为/a/b/c,则路由中路径为/a,/a/b,/a/b/c的均为部分匹配),则添加class=”router-link-active”。 如果路径 绝对匹配 (当前url为/a/b/c,则路由中只有路径为/a/b/c的才为绝对匹配),则添加class=”router-link-exact-active”。
注意:绝对匹配也符合部分匹配的规则,因此当一个路由和当前url绝对匹配时,会被同时加入两种class。
<router-link></router-link>
自动添加的class也可以在创建路由对象时自定义。
123456789 | var myRouter = new VueRouter({ routes:[ {},{}... ], //部分匹配时class linkActiveClass:"active", //绝对匹配时class linkExactActiveClass:"exact-active"}); |
<router-link></router-link>
在页面上会默认形成<a></a>
标签。我们可以通过向其转入属性来决定生成什么样的标签,这不影响其监听点击事件来进行路由跳转。
12345 | <!--使用tag属性来指定形成的标签--><router-link to="/r1" tag="div">路由1</router-link><!--在页面上的渲染结果:--><div>路由1</div> |
路由配置:
123456 | var myRouter = new VueRouter({ routes:[ //用:参数名形式书写path {path:"/r1/:name/:age",component:"template1"} ]}); |
链接传参:
<router-link to="/r1/lins/24"></router-link>
注意:当通过JS传递参数时,接受参数的路由刷新页面会导致参数失效。
路由配置:
123456 | var myRouter = new VueRouter({ routes:[ //使用name给路由起一个名字 {name:"rou1",path:"/r1",component:"template1"} ]}); |
链接传参:
12 | // 注意这里to前面的冒号<router-link :to="{name:'rou1',params:{name:'lins',age:24}}"></router-link> |
组件模板(HTML部分)收参:
组件中JS部分收参(比如created中):this.$route.params.name;
this.$route.params.age;
1234567891011 | //以下所有的的myRouter是使用new VueRouter()创建的对象//不携带参数myRouter.push("/r1");//等价于myRouter.push({path:"/r1"});//通过url携带参数myRouter.push("/r1/lins/24");//等价于myRouter.push({path:"/r1/lins/24"});//通过JS携带参数myRouter.push({name:'rou1',params:{name:'lins',age:24}}); |
1./router/:params1/:params2
这种路由传参,由于路由规则改变了,定义的子级路由会失效
2.{name:”rou1”,path:”/r1”,component:”template1”}
这种方式接受参数的路由刷新页面会导致参数失效。
background-color: blue;background-color: yellow;<input type="button" value="变蓝" @click="changeColorT