路由
1、概念:
-
SPA SPA 是一种特殊的 Web 应用,是加载单个 HTML 页面并在用户与应用程序交互时动态更新该页面的。它将所有的活动局限于一个 Web 页面中,仅在该 Web 页面初始化时加载相应的 HTML 、 JavaScript 、 CSS 。一旦页面加载完成, SPA 不会因为用户的操作而进行页面的重新加载或跳转,而是利用 JavaScript 动态的变换 HTML(采用的是 div 切换显示和隐藏),从而实现UI与用户的交互。在 SPA 应用中,应用加载之后就不会再有整页刷新。相反,展示逻辑预先加载,并有赖于内容Region(区域)中的视图切换来展示内容。 -
后端路由:对于前端的网络请求,不同的pathname,去执行后端的不同业务 前端路由:不同的网址对应各自的页面 vue的前端路由:SPA应用要做出路由效果,就得判断当前网址,然后切换组件 vue-router就是专门做切换组件的功能,它是一个单独的技术,依赖vue 就像jQuery和dom操作一样
2、前端路由的工作方式:
- 用户点击了页面上的路由链接;
- 导致了URL地址栏中的Hash值发生了变化;
- 前端路由键听到了Hash地址的变化;
- 前端路由把当前Hash地址对应的组件渲染到浏览器中。
3、环境配置
1、最常用的方法:
cli安装,不会出错
- vue create init 回车之后,
- 按空格键选择router然后回车,官方直接搭建路由。
2、npm 下载引入使用 (不推荐,打包之后容易出问题)
-
npm i vue-router --save或者 npm i vue-router --S -
在main.js入口文件中引入 import Vue from "vue"
import VueRouter from "vue-router"
import App from "./App.vue"
Vue.use(VueRouter)
const router=new VueRouter({
routes:[{path:"/home",component:()=>import("./home.vue")},
{path:"/about",component:()=>import("./about.vue")}]
})
new Vue({
router,
render(h){return h(App)}
}).$mount("#app")
-
在App.vue中写 <router-view></router-view>
4、基本用法
5、(路由导航)跳转页面的几种方法
1、声明式导航:在浏览器中,点击链接实现导航的方式。
-
router-view:相当于占位符, 路由网址匹配到的组件 会渲染到当前组件的这个标签上
<router-view></router-view>
<a href="/home">首页</a>
<a href="/pengyou">朋友</a>
<a href="/pengyouquan">朋友圈</a>
<a href="/shezhi">设置</a>
import Home from '@/components/Home.vue'
const router=new VueRouter({
{path:'/home',component:Home},
})
-
router-link:相当于a标签,给我们提供跳转到某个路由的功能,如果没有匹配到路由就会跳转失败,只是局部刷新,比a链接跳转更优化:
<router-view></router-view>
<router-link to="/home">首页</router-link>
<router-link to="/pengyou">朋友</router-link>
<router-link to="/pengyouquan">朋友圈</router-link>
<router-link to="/shezhi">设置</router-link>
import Home from '@/components/Home.vue'
const router=new VueRouter({
{path:'/home',component:Home},
})
-
a标签跳转 <a href='/login'>去登陆</a>
2、编程式跳转: 在浏览器中,调用API方法实现导航的方式。
-
this.$router.push(‘hash地址’);//跳转到指定的hash地址,并增加一条历史记录 -
this.$router.replace(‘hash地址’); //跳转到指定的hash地址,并替换掉以前的历史记录 -
this.$router.go(数值n);//在浏览器历史中前进或者后退n步 this.$router.go(1)
this.$router.go(-1)
this.$router.go(3)
this.$router.go(-100)
3、router-link和a标签的区别:
<!-- <router-link to="/login">Login</router-link> -->
<!-- 渲染到页面底层也是a标签,但是只是改变了地址栏的网址并没有重新加载页面 -->
<router-view/>
<a href='/login'>去登陆</a>
<!-- 两种跳转页面的区别:a标签会请求服务器 然后刷新网页,因此用在链接外部网站 -->
6、传参 两种
-
this.$router.push(‘路径’) 传递的参数都在路由信息对象中: 路由对应的组件中获取 this.$route methods:{
fn(){
this.$router.push('register')
}
}
-
query传参
<router-link to="/xx?name=karen&pwd=123">go</router-link>
this.$router.push({path:"/xx",query:{name:"karen",pwd:123}})
mounted(){let queryObj=this.$route.query}
-
动态路由传参
const router=new VueRouter({
routes:[
{path:"/home/:id",component:()=>import("./home.vue")},
{path:"/about",component:()=>import("./about.vue")}]
})
<router-link to="/home/123">go</router-link>
this.$router.push({path:"/home",params:{id:123}})
mounted(){let paramsObj=this.$route.params}
动态添加路由
addRoute( 路由信息)
总结:
-
在hash地址中,/后面的参数项,叫做“路径参数”;在路由“参数对象”中,需要使用this.$route.params来访问路径参数; -
在hash地址中,?后面的参数项,叫做“查询参数”;在路由“参数对象”中,需要使用this.$route.query来访问查询参数; -
在this.$route中,path只是路径部分,fullpath是完整的地址 例如: /movie/2?name=zs&age=18
/movie/2
7、嵌套
添加children对象,里面注册path(路由匹配的路径) component(匹配路径时对应渲染的组件) redirect(匹配路径时重新匹配另外的路径) children(子路由们的数组) name(路由的名字,方便直接通过名字来匹配路由):
const routes = [{
path: '/',
component: () => import("../views/root.vue"),
redirect:"/a",
children: [{
name:"a",
path: "a",
component: () => import("../views/a.vue"),
children: [{
redirect:"/a/a1",
name:"a1",
path: "a1",
component: () => import("../views/a/a1.vue")
},
{
name:"a2",
path: "a2",
component: () => import("../views/a/a2.vue")
},
{
name:"a3",
path: "a3",
component: () => import("../views/a/a3.vue")
},
{
path: "*",
component: () => import("../views/a/error.vue")
}
]
},
{
path: "b",
name:"b",
component: () => import("../views/b.vue")
},
{
path: "c",
name:"c",
component: () => import("../views/c.vue")
},
{
path: "d",
name:"d",
component: () => import("../views/d.vue")
}
]
}]
8、模式
history模式:mode:history,底层切换组件的方式是使用的H5的window.history的技术,当地址栏的history状态发生变化时,切换了router-view渲染的组件,来“欺骗”用户,达到切换新网页的效果
hash模式:mode:hash,底层切换组件的方式是使用的老技术hash值,当地址栏的hash状态发生变化时,切换了router-view渲染的组件,来“欺骗”用户,达到切换新网页的效果,hash值是不会发送给后端的。
9、关于this.$router.xx和补充
补充:
this.$router.push({path:"/home"})
this.$router.replace({path:"/home"})
this.$router.go(1)
this.$router.go(-1)
this.$router.go(3)
this.$router.go(-100)
VueRouter是一个nodejs识别的模块包
route是路由匹配时,携带了一些信息的对象,包括path,params,hash,query等等信息
router是路由实例对象,包含了路由的跳转方法,钩子函数等等
10、路由守卫
-
全局前置守卫 每次发生路由的导航跳转时,都会触发全局前置守卫。因此,在全局前置守卫中,我们可以对每个路由进行访问权限的控制:
const router=new VueRouter({})
router.beforeEach(fn)
router.beforeEach((to,from,next)=>{
})
router.beforeEach((to, from, next) => {
if (to.path == "/" || to.path == "/login" || to.path == "/register") {
next();
} else {
let flag = window.localStorage.getItem("email");
if (flag) {
next()
} else {
Message({
message: '您尚未登录哦,请先登录!',
type: 'warning',
duration: 1500
});
next("/");
}
}
})
- 当前用户拥有后台主页的访问权限,直接放行:next()
- 当前用户没有后台主页的访问权限:强制其跳转到登录页面:next(‘/login’)
- 当前用户没有后台主页的访问权限:不允许跳转到后台主页:next(false)
-
全局解析钩子router.beforeResolve(fn),组件初始化 router.beforeResove((to,from)=>{
console.log('路由匹配完毕',to,from);
})
-
全局后置守卫 afterEach() router.afterEach((to,from,next)=>{
console.log('组件渲染了);
})
-
独享守卫 beforeEnter() 路由初始化(组件未初始化)
routes:[{
path:"/test",
component:()=>import("../components/Test.vue"),
beforeEnter(to,from,next){
if(to.path==="/test"){
alert("请登录");
next(false);
}else{
next()
}
}
}]
5、组件内部生命周期守卫
- beforeRouteLeave() //组件要离开了,记录用户行为和一些计时器 操作;
- beforeRouteEnter(to,from,next),//组件被激活,使用不了this,故构造指定该next 可以接收一个回调函数接收当前vm 实例----路由传参获取参数,得到初始化数据
- beforeRouteUpdate(to,from,next), //组件重用时被调用----路由传参获取参数,避免增添watch 开销
执行时的顺序: beforeRouteLeave < beforeEach < beforeRouteUpdate < beforeEnter < beforeRouteEnter < beforeResolve < afterEach
浏览器中存缓存:window.localStorage.setItem(‘key’,‘value’)
浏览器中取缓存:window.localStorage.getItem(‘key’)
|