根据用户给出的url地址,导航到不同组件中;
SPA:单一页面应用程序
,只有一个完整的页面,它在加载页面时,不会加载整个界面,而是只更新某个指定的容器中的内容。单页面应用(SPA)的核心之一是:更新视图而不是更新请求页面
。Vue Router在实现单页面前端路由时,提供了两种方式:hash模式和history模式,默认使用的是hash模式。
这种#后面hsah值的变化,并不会导致浏览器向服务器发出请求,浏览器不发出请求,也就不会刷新页面。而每次hash值的变化,还会触发hashchange事件,通过这个时间我们就可以知道hash值发生了哪些变化。我们便可以监听hashchange来实现更新页面部分的内容的操作。因此改变hash不会重新加载页面
function matchAndUpdate(){
}
window.addEventListener("hashchange",matchAndUpdate)
因为HTML5标准发布,多了两个API, pushState 和replaceState,通过这两个API可以改变url地址且不会发送请求。同时还有popstate事件。通过这些就能用另一种方式来实现前端路由了,但原理都是跟hash实现相同的。用了HTML5的实现,单页路由的url就不会多出一个#
,变得更加美观。但因为没有#号,所以当用户刷新页面之类的操作时,浏览器还是会给服务器发送请求。为了避免出现这种情况,所以这个实现需要服务器的支持,需要把所有路由都重定向到根页面。
function matchAndUpdate(){
}
window.addEventListener("popstate",matchAndUpdate)
const router = new VueRouter({
路由列表:是一个数组
routes:[
单个路由
path:表示路由路径字符串,在path中需要/开头,目的使全局路由对象能够监听到某个用户请求的路径;
component:组件,如果path与用户访问的路径匹配,则去查找相应的组件,让组件渲染页面
{
path:/login,
component:Login
}
]
})
<router-link>标签,进行路由导航,它会被Vue解析为一个超链接;
to属性:配置路由路径;
<router-link to="/login">登录</router-link>(声明式导航)
通过router-link标签导航之后,组件如何渲染到页面中?
<router-view/>:渲染某个路由路径对应的组件,称为路由出口
我们经常需要把某种模式匹配到的所有路由,全都映射到同个组件。例如,我们有一个User组件,对于所有ID各不相同的用户,都要使用这个组件来渲染。那么,我们可以在vue-router的路由路径中使用动态路径参数”来达到这个效果:当我们在地址后面直接添加任意字符,我们会发现文档内容随着我们的更改而改变。
{
path:/user/:id,//通过$route.params.id可以获取到这个值,如果使用path:/user-* 通配符,是无法获取的
component:Login
}
<router-link to="/user/1001">登录</router-link>
<router-link to="/user/1002">登录</router-link>
//传递多个参数
{
path:/user/:id/:uerName,//通过$route.params.id可以获取到这个值,如果使用path:/user-* 通配符,是无法获取的
component:Login
}
this.$router.push(`/user/${id}/${name}`)
//侦听器:侦听当前路由的变化
watch: {
//to:导航之后(跳转之后)的路由对象
//from:旧值,跳转前的路由对象
"$route":(to, from)=> {
console.log("导航之后",to);
console.log("前",from);
}
},
官网上是这样写的
created() {
//侦听器:侦听当前路由的变化
this.$watch(() => this.$route.params,
(toParams, previousParams) => {
// 对路由变化做出响应...
console.log(toParams);
console.log(previousParams);
})
},
路由路径通配符*。
路由列表的匹配模式是自上而下的逐个路由匹配,带有通配符的路由一定放在路由列表最后。
{
path: "/*",
component: Error
}
{
path: '/about',
component:About,
children: [{
//嵌套路由列表
// path:"list",//相对路径是上级路由作为前缀路径 to="/about/list"
path:"/list",//绝对路径不能以上级路由作为前缀路径 to="/list"
component:Child
}]
},
//字符串形式
this.$router.push('/vuex');
//对象形式
this.$router.push({path:'/vuex'})
路由在导航之后会形成历史记录history
;
push:在历史列表中追加一个
replace:在历史列表中替换上一个记录
,不可以后退到上一个页面;
在声明式导航中的应用:
<router-link to="xxxx" replace>xxx</router-link>
编程式导航:
this.$router.replace('/vuex')
一般可以用在登录后,跳转到主页,就用replace,防止用户回退时回退到登录页面。
历史前进或后退多少步;
this.$router.go(-3)
为每个路由的配置添加一个name属性,且必须唯一;
{
path: "/login",
name:"login",//路由名称
component: Login
}
根据路由名称进行导航
//声明式
<router-link :to="{name:'vuex'}" replace>xxx</router-link>
//编程式导航(对象形式,不能是字符串形式)
this.$router.push({name:'vuex'})
通过重定向redirect
是实现组件的复用;
{
path: "/",
redirect:"/home",
//redirect: {name: "vuex"}也可以通过组件名称进行重定向
},
{
path: '/home',
name: 'home',
component: HomeView
}
{
path: '/home',
name: 'home',
component: HomeView,
alias:"/hm"//路由别名
},
export default new Router({
mode: 'history', //路由模式,取值为history与hash
base: '/', //打包路径,默认为/,可以修改
routes: [
{
path: string, //路径
ccomponent: Component; //页面组件
name: string; // 命名路由-路由名称
components: { [name: string]: Component }; // 命名视图组件
redirect: string | Location | Function; // 重定向
props: boolean | string | Function; // 路由组件传递参数
alias: string | Array<string>; // 路由别名
children: Array<RouteConfig>; // 嵌套子路由
// 路由单独钩子
beforeEnter?: (to: Route, from: Route, next: Function) => void;
meta: any; // 自定义标签属性,比如:是否需要登录
icon: any; // 图标
// 2.6.0+
caseSensitive: boolean; // 匹配规则是否大小写敏感?(默认值:false)
pathToRegexpOptions: Object; // 编译正则的选项
}
]
})
两个组件之间的数据传递;
<router-link to="/VModel?name=user&pwd=123"></router-link>
//接收参数
this.$route.query
//传递的是一个对象,也可以拼接为字符串形式
this.$router.push({path:'/vuex',query:{name:'111',age:18}})
//接收参数
this.$route.query
{
path: '/vuex/:ids/:name',
name: 'vuex',
component: VueXStudy,
}
<router-link to="/vuex/1/xiao">xxxx</router-link>
//接收参数
this.$route.params
this.$router.push({name:'vuex',params:{name:'张三',age:18}})
//接收参数
this.$route.params
<router-link :to="{name:'vuex',params:{name:'李四'}}">xxxx</router-link>
//接收参数
this.$route.params
在组件中使用$route会使之与其对应路由形成高度耦合,从而使组件只能在某些特定的url使用,限制了其灵活性。
解耦
{
//路由路径中的占位符名称必须与组件props变量名称一致
path: '/vuex/:id/:userName',
name: 'vuex',
component:VueXStudy,
//在路径配置中开启props传参
props: true
}
<router-link to="/vuex/1001/王麻子">xxxx</router-link>
//定义props对象接收路由参数
props:{
id:String,
userName:String
}
params只能使用name
;刷新后可以保存
,params不会保存;显示在url地址中
,params不会显示;动态路由匹配
一起使用,而使用params接收参数
;“导航”表示路由正在发生变化;
类似于javaweb里面的过滤器,拦截器
router.beforeEach()一般用来做一些进入页面的限制。比如没有登录,就不能进入某些页面,只有登录了之后才有权限查看某些页面。说白了就是路由跳转前根据业务逻辑判断是否拦截。
router.beforeEach(回调函数),回调函数中的三个参数
next():无参数调用就是对导航的放行;
next(阻止导航,阻止导航后跳转的路径):阻止导航,阻止路由跳转
//有参数时编写的形式:
next( '/login')
next({path: '/login'})
next({name: 'login'})
//前置守卫
//模拟身份认证:判断用户是否登录,如果没有登录,跳转至登录页面
router.beforeEach((to, from, next) => {//路由跳转中
if (to.path == "/") {//"/"默认进入登录页面
next();
} else {
if (sessionStorage.getItem("userInfo")) {
next()
} else {
next({path: '/'})
}
}
})
守卫范围:当前路由以及当前路由下的所有嵌套路由;
{
path: '/vuex',
name: 'vuex',
component: () => import( '../components/vuex/VueXStudy.vue'),
beforeEnter: (to, from, next) => {
console.log("to", to);
console.log("from", from);
next();
}
}
未使用懒加载
import Vue from 'vue'
import VueRouter from 'vue-router'
import HomeView from '../views/HomeView.vue'
Vue.use(VueRouter)
export default new VueRouter({
routes:[
{
path: '/home',
name: 'home',
component: HomeView,
}
]
})
方法如下:component:resolve=>(require(['需要加载的路由的地址']),resolve)
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
export default new VueRouter({
routes:[
{
path: '/home',
name: 'home',
component: resolve=>(require(["../views/HomeView.vue"],resolve)),
}
]
})
方法如下: component: () =>import('需要加载的模块地址')
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
export default new VueRouter({
routes:[
{
path: '/home',
name: 'home',
component: () => import( '../views/HomeView.vue')
}
]
})
动态添加根路由:router.addRoute({path:xxx,name:xx....})
动态添加子路由:router.addRoute(parentName,{path:xxx,name:xx....})
,其中parentName为父级路由定义的name字段。