一、路由的跳转原理(哈希模式)
1.单页应用的路由模式有两种
哈希模式(利用hashchange 事件监听 url的hash 的改变)
history模式(使用此模式需要后台配合把接口都打到我们打包后的index.html上)
2.哈希模式原理
window.addEventListener(‘hashchange’, function(e) {
console.log(e)
})
3.核心是锚点值的改变,我们监听到锚点值改变了就去局部改变页面数据,不做跳转。跟传统开发模式url改变后 立刻发起请求,响应整个页面,渲染整个页面比路由的跳转用户体验更好
实例
<body>
<a href="#/login">登录</a>
<a href="#/register">注册</a>
<div id="app"></div>
<script type="text/javascript">
var appdiv=document.getElementById('app')
window.addEventListener('hashchange',function(e){
console.log(location.hash)
switch(location.hash){
case '#/login':
appdiv.innerHTML='我是登录页面';
break;
case '#/register':
appdiv.innerHTML='我是注册页面';
break;
}
})
</script>
</body>
二、 安装和使用路由
路由是以插件的形式引入到我们的vue项目中来的
vue-router是vue的核心插件
1:下载 npm i vue-router -S
2:安装插件Vue.use(VueRouter);
3:创建路由对象 var router = new VueRouter();
4:配置路由规则 router.addRoutes([路由对象]);
路由对象{path:‘锚点值’,component:要(填坑)显示的组件}
5:将配置好的路由对象交给Vue
在options中传递-> key叫做 router
6:留坑(使用组件)
三、 路由的跳转
1.路由的跳转方式有:
通过标签:
通过js控制跳转this.$router.push({path:’/login’})
2.区别:
this.$router.push() 跳转到指定的url,会向history插入新记录
this.$router.replace() 同样是跳转到指定的url,但是这个方法不会向history里面添加新的记录,点击返回,会跳转到上上一个页面。上一个记录是不存在的。
this.$router.go(-1) 常用来做返回,读history里面的记录后退一个
vue-router中的对象:
$route 路由信息对象,只读对象
$router 路由操作对象,只写对象
实例
<body>
<div id="app"></div>
<script type='text/javascript' src="vue.js"></script>
<script type='text/javascript' src="vue-router.js"></script>
<script type='text/javascript' >
var Login={
template:`
<div>Login.....</div>
`
}
var Register={
template:`
<div>Register....</div>
`
}
//安装路由插件
Vue.use(VueRouter);
//创建路由对象
var router=new VueRouter({
//配置路由对象
routes:[
{path:'/login',
name:'login',
component:Login
},
{path:'/register',
name:'register',
component:Register
}
]
})
new Vue({
el:'#app',
router,
template:`
<div>
<router-link to='/login'>登录</router-link>
<router-link to='/register'>注册</router-link>
<div>
<button @click='gologin'>去登录</button>
<button @click='goregister'>去注册</button>
<button @click='back'>返回上一页</button>
</div>
<router-view></router-view>
</div>
`,
data(){
return{
}
},
methods:{
gologin(){
this.$router.replace({path:'/register'})
},
goregister(){
this.$router.push({path:'/register'})
//push与replace可以达到同样效果,但是replace不会向history插入数据
// this.$router.replace({path:'/register'})
},
back(){
this.$router.go(-1)
}
}
})
</script>
</body>
四、路由的传参和取参
1.查询参
配置(传参) :to="{name:‘login’,query:{id:loginid}}"
获取(取参) this.$route.query.id
2.路由参数
配置(传参) :to="{name:‘register’,params:{id:registerid} }"
配置路由的规则 { name:‘detail’,path:’/detail/:id’}
获取 this.$route.params.id
3.总结:
:to传参的属性里 params是和name配对的 query和name或path都可以
使用路由参数必须要配置路由规则里面配置好参数名,否则刷新页面参数会丢失
实例
<body>
<div id="app"></div>
<script type="text/javascript" src="vue.js"></script>
<script type="text/javascript" src="vue-router.js"></script>
<script type="text/javascript">
var Login={
template:`
<div>Login...
<span>获取到的参数:{{msg}}</span>
</div>
`,
data(){
return{
msg:''
}
},
created(){
//获取参数
this.msg=this.$route.query.id
}
}
// var Register={
// template:`
// <div>Register...
// <span>获取到的参数:{{registerfoo}}</span>
// </div>
// `,
// data(){
// return{
// registerfoo:''
// }
// },
// created(){
// this.registerfoo=this.$route.params.foo
// }
// }
//另一种获取参数方法
// <span>获取到的参数:{{registerfoo}}</span>
var Register={
template:`
<div>Register...
<span>获取到的参数:{{foo}}</span>
</div>
`,
props:['foo']
// data(){
// return{
// registerfoo:''
// }
// },
// created(){
// this.registerfoo=this.$route.params.foo
// }
}
Vue.use(VueRouter);
var router=new VueRouter({
routes:[
{
path:'/login',
name:'login',
component:Login
},
{
path:'/register/:foo',
name:'register',
props:true,
component:Register
}
]
})
new Vue({
el:'#app',
router,
template:`
<div>
<router-link :to="{name:'login',query:{id:'123'}}">去登录</router-link>
<router-link :to="{name:'register',params:{foo:'bar'}}">去注册</router-link>
<button @click='jslink'>js跳转去登录</button>
<router-view :key="$route.fullPath"></router-view>
</div>
`,
data(){
return{
}
},
methods:{
//js跳转传参
//<router-view :key="$route.fullPath">解决js跳转路由传参和标签传参,路由相同而参数不同时页面不刷新页面的问题
jslink(){
this.$router.push({name:'login',query:{id:'456'}})
}
}
})
</script>
</body>
五、嵌套路由和路由守卫
嵌套路由
代码思想
1:router-view的细分
router-view第一层中,包含一个router-view
2:每一个坑挖好了,要对应单独的组件
路由配置
routes: [
{
path:’/nav’,
name:‘nav’,
component:Nav,
//路由嵌套增加此属性
children:[
//在这里配置嵌套的子路由
]
}
]
路由守卫
const router = new VueRouter({ … }
//前置的钩子函数 最后要执行next()才会跳转
router.beforeEach((to, from, next) => {
// …
})
//后置的钩子函数 已经跳转了不需要next
router.afterEach((to, from) => {
// …
})
实例
<body>
<div id="app"></div>
<script type="text/javascript" src="vue.js"></script>
<script type="text/javascript" src="vue-router.js"></script>
<script type="text/javascript">
var Nav={
template:`
<div>
<router-view></router-view>
<router-link :to="{name:'login'}">登录</router-link>
<router-link :to="{name:'register'}">注册</router-link>
</div>
`
}
var Login={
template:`
<div>Login</div>
`
}
var Register={
template:`
<div>Register</div>
`
}
Vue.use(VueRouter);
var router=new VueRouter({
routes:[
{
path:'/nav',
name:'nav',
component:Nav,
children:[
{
path:'login',
name:'login',
component:Login,
},
{
path:'register',
name:'register',
component:Register,
},
{
//重定向
path:'',
redirect:'/nav/register'
}
]
}
]
})
new Vue({
el:'#app',
template:`
<div>
<router-view></router-view>
</div>
`,
router,
data(){
return{}
},
mounted(){
router.beforeEach((to,from,next)=>{
console.log(to)
if(to.path=='/nav/login'){
next()
}else{
setTimeout(function(){
next()
},2000)
}
})
}
})
</script>
</body>