前端路由概念
通过改变 URL,在不重新请求页面的情况下,更新页面视图。更新视图但不重新请求页面,是前端路由原理的核心之一,目前在浏览器环境中这一功能的实现主要有2种方式:
Hash
和history
如何设置路由模式
const router=new VueRouter({
mode:'history / hash',
routes:[...]
})
# mode:'hash' 默认
地址栏会多一个#符号:
http://localhost:8080/#/login
# mode:'history'
http://localhost:8080/home
Hash模式
hash模式:在浏览器中符号’#’,以及’#'后面的字符称为hash
特点:
1. hash 不会被包括在 http 请求中,对服务器端完全无用,因此,改变 hash 不会重新加载页面。
2. 可以为 hash 的改变添加监听事件:window.addEventListener("hashchange",funcRef,false)
3. 每一次改变 hash(window.localtion.hash),都会在浏览器访问历史中增加一个记录。
HashHistory 拥有两个方法
两个方法:HashHistory.push() 和 HashHistory.replace()
HashHistory.push():将新路由添加到浏览器访问历史的栈顶
HashHistory.replace():与push()不同的是,它会替换掉当前的路由
history模式
history模式:利用了 HTML5 History api 在浏览器中没有’#’,有浏览器兼容问题
特点
提供了两个新方法:pushState(), replaceState()可以对浏览器历史记录栈进行修改,
以及popState事件的监听到状态变更
window.onpopstate = function(event) {
console.log(event.state);
console.log(window.history.state;);
};
注意:popstate
事件会在点击后退、前进按钮时触发,是在由history.pushState()
或者history.replaceState()
形成的历史节点中前进后退。
用history.pushState()或者history.replaceState(),以及页面第一次加载的时候,不会触发popstate事件。
路由跳转
方法一:声明式
<router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>
使用router-link标签套在要点击的内容外面,to指定跳转的路径
方法二:编程式
this.$router.push({ name: 'xxx',params: { id:xxx }})
this.$router.push({ path: '/xxx',query: { id:xxx }})
const userId = '123';
this.$router.push({ name: 'user', params: { userId }}) // -> /user/123
this.$router.push({ path: `/user/${userId}` }) // -> /user/123
此外:
replace() go()
replace和push很像,唯一不同的是,它不会向history添加新的记录,而是替换当前的history记录。
<router-link :to="..." replace>
this.$router.replace()
this.$router.go(-1) // 后退1
this.$router.go(0) // 刷新
this.$router.go(1) // 前进1
三者区别:
this.$router.push
跳转到指定url路径,并想history栈中添加一个记录,点击后退会返回到上一个页面
this.$router.replace
跳转到指定url路径,但是history栈中不会有记录,点击返回会跳转到上上个页面 (就是直接替换了当前页面)
this.$router.go(n)
向前或者向后跳转n个页面,n可为正整数或负整数
路由传参
在路由跳转的时候 携带一个数据 传到要跳转的页面 这种情况叫做路由的传参
例如有一个场景: 点击列表跳转到对应的详情页,携带id,便于详情页获取数据
第一种传参:
query 传参:
goDetail(id) {
this.$router.push({path:'/detail',query:{id:id}})
}
到了跳转到的页面 接收:
this.$route.query.id
第二种传参:
params传参
goDetail(id) {
this.$router.push({name:'detail',params:{id:id}})
}
到了跳转到的页面 接收:
this.$route.params.id
第三种传参:
动态路由传参:
goDetail(id) {
this.$router.push({path:`/detail/${id}`})
}
需要对应路由配置:
{
path:'/detail/:id',
name:'detail',
}
到了跳转到的页面 接收:
this.$route.params.id
区别:
- query传参的参数会带url后面展示在地址栏,params传参的参数不会展示;
- query传参配置的是
path或name
,params传参配置的是name
; - params传参刷新后会无效,query会保存传递过来的值,刷新不变;
- params可以和动态路由一起使用,query不可以
router 和 route 区别
router为路由实例,$route
为当前router跳转对象,里面可以获取name,path,query,params
路由嵌套
子路由 又叫嵌套路由。
除了app.vue
是必须的自带之外我们也可以自己写一个坑用来展示页面
是谁的子路由 就会在谁的坑里展示 默认的最外层是app
的子路由
const routes = [
{
path: "/index",
name: "index",
component: () => import("../views/Index.vue"),
children: [
{
path: "/shopcar",
name: "shopcar",
component: () => import("../views/Shopcar.vue"),
},
],
},
];
路由守卫
详细请看vue路由守卫