浅尝辄止vue-router,待更新

一、路由的简单使用

1. 理解

  • 一个路由(route)就是一组映射关系(key-value),多个路由需要由路由器(router)进行管理
  • 前端路由:key是路径path,value是路由组件xxx.Vue
  • vue-router是官方提供的用来实现SPAVue插件

2. 基本使用

2.1 安装vue-router插件

npm i vue-router@3 vue2记得指定版本!

2.2 引入并使用插件
import VueRouter from 'vue-router'
Vue.use(VueRouter)
2.3 创建路由组件

在src下创建viewspages文件夹,专门用于放置路由组件

2.4 编写router配置项

在src下创建router文件夹,创建index.js用于配置路由器
在index.js模块下,引入相关的路由组件
实例化VueRouter,new VueRouter({}) 配置路由器
每个路由是一个对象,path是路径、name是路由名、component是对应的路由组件、meta是路由元信息、mode是路由工作模式…

2.5 注册路由

在入口文件main.js中引入注册路由器router,注意,注册完路由器后,Vue组件实例(包括非路由组件)身上都有了$router$route属性

new Vue({
    el: '#app',
    render: h => h(App),
    router
})
2.6 实现路由跳转(两种方式)
  • 声明式导航
    • 通过使用<router-link to=""><router-link/>自定义组件实现路由的跳转
    • 可以添加class类名
    • 可以添加active-class="active"路由高亮即激活状态
    • 这个自定义组件默认会渲染成带有正确链接的a标签
  • 编程式导航
    • 通过给节点添加事件
    • 配置对应的method,利用组件实例身上的$router属性的push()以及replace()方法实现路由的跳转
2.7 指定路由组件展示位置

<router-view></router-view>

3. 总结与几个注意点

3.1 路由的简单使用步骤
  • 创建路由组件
  • 配置路由器
  • 注册路由器
3.2 几个注意点
  • 路由组件通常存放在 pages 文件夹,一般组件通常存放在 components 文件夹。
  • 通过切换,“隐藏”了的路由组件,默认是被销毁掉的,需要的时候再去挂载;当然也可以缓存路由组件,使得路由组件保持挂载只是失活。
  • 每个组件都有自己的 $route 属性,里面存储着自己的路由信息。
  • 整个应用只有一个 router ,可以通过组件的 $router 属性获取到。

二、多级路由(嵌套路由)

1. 配置路由规则

  • children配置项,配置子级路由
  • 注意:子级路由的path不需要/
routes:[
	{
		path:'/about',
		component:About,
	}{
		path:'/home',
		component:Home,
		children:[ 		//通过children配置子级路由
			{
	    		path:'news', //此处不要写:/news
				component:News
			}{
	    		path:'message',
				component:Message
			}]
	}
]

2. 实现路由跳转(要写完整路径)

命名路由则不需要,看后续三补充
<router-link to="/home/news">News</router-link>

3. 指定路由组件展示位置

<router-view></router-view>

三、直接路由与命名路由

1. 作用

简化路由的跳转

2. 使用方式

在router文件夹下的index.js模块配置路由器是给其中需要命名的路由加入name属性

{
    path:'/demo',
	component:Demo,
	children:[
		{
			path:'test'
			component:Test,
			children:[
				{ //三级路由
					name:'hello' //给路由命名
					path:'welcome',
					component:Hello,
    			}
			]
		}
	]
}

3. 命名路由简化跳转的实现

<!--简化前,需要写完整的路径 -->
<router-link to="/demo/test/welcome">跳转</router-link>
<!--简化后,直接通过名字跳转 -->
<router-link :to="{name:'hello'}">跳转</router-link>

四、向路由组件传递数据(三种方式)

1. 路由路径携带query参数

1.1 声明式导航的to的值
  • to的值可以是字符串型的路径
// 通过这种方式传递的数据是写死的
<router-link to="/home/message/detail?id=666&title=你好">
    {{ m.title }}
</router-link>
// 通过v-bind+模板字符串
<router-link :to="`/home/message/detail?id=${m.id}&title=${m.title}`">
    {{ m.title }}
</router-link>
  • to的值也可以是一个描述地址的对象,这个对象有path、query、name、params等属性,其中query和params是Object,注意此时需要结合v-bind使用,引号内的内容需要被解析为js
<router-link
:to="{ //直接路由,地址栏变为/home/message/detail?id=m.id&title=m.title
	path: '/home/message/detail',
    query: { id: m.id, title: m.title }, 
}"
>
    {{ m.title }}
</router-link>
  • 传递的query参数被 r o u t e 接 收 , 可 以 在 另 一 个 组 件 内 通 过 ‘ t h i s . route接收,可以在另一个组件内通过`this. routethis.route.query.xxx获取
  • 消息标题:{{ $route.query.title }}
  • `

2. 路由路径携带params参数

2.1 携带params参数,在配置路由时需要使用占位符

query则不需要!

{
    path: '/home', //1
        component: Home,
            children: [
                {
                	path: 'news',
                	component: News //2
            	},
                {
                    path: 'message',
                    component: Message, //2
                    children: [
                        {
                               // 给路由命名
                               name: 'xiangqing',
                               // params写法需要写 (占位)
                               path: 'detail/:id/:title',
                               component: Detail //3
                        }
                    ]
                }
            ]
},
2.2 传递params参数的两种写法(to)
  • 字符串写法(字符串/模板字符串)
<!-- 跳转并携带params参数,to的字符串写法 -->
<router-link :to="`/home/message/detail/${m.id}/${m.title}`">跳转</router-link>
  • 对象写法 注意必须配合name配置项使用,不能配合path配置项!
<router-link
	:to="{
	name: 'xiangqing',
    params: { id: m.id, title: m.title },
	}"
>
	{{ m.title }}
</router-link> -->
  • 传递的params参数被$route接收,可以在另一个组件内通过this.$route.params.xxx获取
  • 如:<li>消息标题:{{ $route.params.title }}</li>

3. 路由的props配置传递数据

3.1 作用

让路由组件更方便的收到参数

3.2 实现
3.2.1 在配置路由器时,给需要接收数据的路由加入props配置项

写在router文件夹的index.js!!!和配置项name、path同级,注意和组件传值props不是一个捏。

  • props配置项的第一种写法:对象(该对象中所有的key-value都会以props形式传给对应的路由组件)
props: {
    a: '1',
    b: 'hello',
},
  • props第二种写法:值为布尔值(若布尔值为真,则会把该路由收到的所有params参数,以props的形式传给对应的路由组件),结合2.2
props: true
  • props第三种写法:值为函数(该函数返回的对象中每一组key-value都会以props的形式传给对应的路由组件)
props($route) { // 可以接收参数?????
    return {
        id: $route.query.id,
        title: $route.query.title
    }
}
3.2.2在路由组件,使用props配置项接收数据
  • 第一种,路由组件需要配置props配置项接收路由props配置项传的值
    props: ["a", "b"],
  • 第二种和第三种,于是路由组件接收到id和title
    props: ["id", "title"],

router-link的replace属性同及编程式to和replace区别

1. 作用

控制路由跳转时操作浏览器历史记录的模式

2. 浏览器的历史记录的两种写入方式

  • push是追加历史记录,所以可以后退。
  • replace 是替换当前记录,因此不可以后退。
  • 路由跳转时候默认为 push

3. 理解

两种的区别是:push是压栈,replace是替换栈顶

4. 开启replace模式

<router-link replace>News</router-link> <router-link :replace="true">News</router-link>

五、编程式路由导航

1. 作用

不使用<router-link></router-link>自定义组件,且在路由跳转前可以实现一些业务

2. 实现

  • 通过点击事件配置methods,结合push和replace方法
    • push和replace方法来自于VueRouter这个构造函数的原型对象 VueRouter.prototype.push VueRouter.prototype.push
    • 根据原型链,实例对象可以使用其构造函数的原型对象上的方法
    • 此处的this是组件实例Vc,具有$router属性 需要再看一下原型链/项目的视频/Vc和Vm的区别
  • 这两种方法都可以传入对象作为参数,从而设置name/path跳转到哪个路由以及传递query/params参数,类似于to的值的对象形式
methods: {
    pushShow(m) {
        // push查看detail
        // console.log(this.$router);
        this.$router.push({
            name: "xiangqing",
            query: { id: m.id, title: m.title },
        });
    },
    replaceShow(m) {
        // replace查看detail
        this.$router.replace({
            name: "xiangqing",
            query: { id: m.id, title: m.title },
         });
    },
},

3. 前进后退的api

  • this.$router.forward()//前进
  • this.$router.back()//后退
  • this.$router.go()//可前进也可后退,负数后退正数前进

六、缓存路由组件

1. 作用

让不展示的路由组件保持挂载,不被销毁;即切换回来只是重新激活

2. 实现

<!-- include写需要缓存的组件 应该写组件的组件名即name配置项 -->
<!-- 不写include的话 在此处展示的组件全部缓存 多个组件 :include="[xx,xx]" -->
<keep-alive include="News">
	<router-view></router-view>
</keep-alive>

3. 应用场景

如,Home组件可以跳转到News和Message路由组件,News组件内有input输入框,在从News组件切换到Message组件时,News组件被销毁,切换回来时会重新挂载。因此,输入框内的内容就没有了。

4. 两个新的生命周期钩子

1. 作用

路由组件所独有的两个钩子,用于捕获路由组件的激活状态

2. 函数名
  • activated在路由组件被激活时触发
  • deactivated在路由组件失活时触发
3. 与mounted钩子的区别

activated钩子不受缓存的影响,每次重新切换回某个路由组件都会执行。
mounted钩子在挂载时执行一次,如果没有缓存的话,再次切回,mounted还会执行,从而导致ajax反复获取数据????? 不是说路由改变不向后端发送请求捏??

七、路由守卫

1.作用

在组件加载前或加载后执行方法,可以加判断拦截

2. 类别

  • 全局守卫
  • 独享守卫
  • 组件内守卫
2.1 全局守卫
2.1.1 全局前置路由守卫
const router = new VueRouter({routes:[...]})
// 在index.js创建路由器时,配置全局前置路由守卫
// 在初始化和每一次路由切换之前,都会帮你调用一次这里面的函数
// 这个函数会接收三个参数
router.beforeEach((to, from, next) => {
    console.log('@');
    console.log('前置', to, from);
    // 不应该在前置路由守卫里改标题
    // document.title = to.meta.title || '银灰'
    // 判断去哪儿
    // path和name都可以判断
    // meta配置项:路由元信息 可以在里面自定义属性 是否需要鉴权
    // 这样就不要一个个判断path/name了
    if (to.meta.isAuth) { //是否需要鉴定权限
        // 是否放行
        if (localStorage.getItem('school') === 'atguigu') {
            next()
        } else {
            alert('无权查看')
        }
    } else { //不需要鉴权
        next()
    }
})
export defalut router
2.1.2 全局后置路由守卫
const router = new VueRouter({routes:[...]})
// 全局后置路由守卫
// 后置路由守卫是切换后才调用的,没有next,因为已经切换完啦
router.afterEach((to, from) => {
    console.log('后置', to, from);
    document.title = to.meta.title || '银灰'
})
export default router
2.2 独享守卫
2.2.1 作用

某个路由组件独享的,某个路由的配置项

{
    name: 'xinwen',
    path: 'news',
    component: News,
    meta: { isAuth: true, title: '新闻' },
    // 独享路由守卫 (可以配合全局路由守卫一起使用)
    beforeEnter: (to, from, next) => {
         console.log(to, from, next);
         if (to.meta.isAuth) {
               // 是否放行
               if (localStorage.getItem('school') === 'atguigu') { 
               		next()
               } else {
                    alert('学校名不对,无权查看')
               }
         } else { //不需要鉴权
               next()
     }
}
2.3 组件内守卫
2.3.1 作用
  • 通过路由规则后进入离开该组件时被调用
  • 不符合路由规则,则不会被调用,和独享守卫的区别所在
  • 也可以配合其他守卫使用
2.3.2 实现
export default {
  name: "About",
  // 通过路由规则,【进入】该组件时被调用
  beforeRouteEnter(to, from, next) {
    console.log("About-beforeRouterEnter", to, from);
    if (to.meta.isAuth) {
      // 是否放行
      if (localStorage.getItem("school") === "atguigu") {
        next();
      } else {
        alert("学校名不对,无权查看");
      }
    } else {
      next();
    }
  },
  // 通过路由规则,【离开】该组件时被调用
  beforeRouteLeave(to, from, next) {
    console.log("About-beforeRouterLeave", to, from);
    next();
  },
};

八、路由的两种工作模式

1. 前情提要

  • 对于一个URL来说,#及其后面的内容就是hash值
  • hash虽然出现在URL中,但不会包含在 HTTP 请求中,即:hash值不会带给服务器
  • 因此改变hash不会重新加载页面,也就不会发起ajax请求???

2. 路由的两种工作模式

  • hash模式
  • history模式
2.1 hash模式(默认)
  • 地址栏中URL永远带着#号,不美观
  • 若以后将地址通过第三方手机app分享,若app校验严格,则地址会被标记为不合法
  • 兼容性较好
2.2 history模式
  • 利用了HTML5 History Interface 中新增的pushState() 和replaceState() 方法(需要特定浏览器支持)
  • 地址干净,美观
  • 兼容性和hash模式相比略差
  • 应用部署上线时需要后端人员支持,解决刷新页面服务端404的问题

3. 如何切换两种模式

在创建路由时,加入mode配置项(不加默认是hash)
mode: 'history',

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值