vue-router的核心概念

一,两种路由模式

1.1 hash模式(对应HashHistory)

特点:

  • 页面监听#号后面的url变化,这种路由模式所有的变化都在前端执行不会像服务器发送请求
  • 每次hash值变化都会在浏览器的访问历史中增加一个记录。
  • hash不会造成404的问题,因为所有的解析都在前端完成

1.2 history模式(对应HTML5History)

特点:

  • 是HTML5新推出的功能,比hash url更美观,在浏览器刷新页面时,会真实按照路径发送请求
  • 如果发送请求的路径nginx没有匹配到,就会出现404页面
  • 改变url:history提供了pushStatereplaceState两种方法来记录路由状态,这两种方法只会改变url,不会刷新页面
  • 监听url变化:通过onpopstate事件监听history的变化,在点击浏览器的前进或者后退时触发,根据状态信息加载对应的页面内容。

二,router-link

router-link组件的本质就是a标签,他绑定了click事件,然后通过执行对应的VueRouter实例的push()实现的。他使Vue Router可以在不重新加载页面的情况下更改URL,处理URL的生成以及编码。

使用示例:

<router-link :to="{ name: 'detail', params: { appId: '12345' }}">

this.$router.push({ name: 'detail', params: { appId: '12345' }})

二者实现效果一致

三,router-view

router-view组件是一个函数式组件(没有data,没有组件实例),他的主要作用就是路由变化时渲染指定url的组件。他可以放在任何地方,来适应项目中的布局。

使用示例:

支持使用name进行命名

<router-view class="left" name="left"></router-view>
<router-view class="home"></router-view>


  routes: [
    {
      path: '/',
      components: {
        default: Home,
        // left: left的缩写。与 `<router-view>` 上的 `name` 属性匹配
        left,
      },
    },
  ],

四,$route

概念:当前路由信息的对象。获取和当前路由相关的信息,route是只读的属性,可以通过watch来监听路由的变化。

常用属性:

  • fullPath: ""  // 当前路由完整路径(包含查询参数和hash)
  • hash: "" // 当前路由的 hash 值 (锚点)
  • meta: {} // 路由文件中自赋值的meta信息
  • name: "" // 当前路由名称
  • path: ""  // 当前路由路径
  • params: {}  // 包含了动态片段和全匹配片段就是一个空对象。
  • query: {}  // 表示 URL 查询参数。跟随在路径后用'?'带的参数

五,$router

概念:vueRouter的实例对象。他是一个全局路由对象,可以通过this.$router访问路由或路由提供的方法。

常用属性/方法:

  • router.push - 路由跳转
  • router.replace - 替换当前路由页面(这样跳转不会产生历史记录)
  • router.go - 跳转到具体某个历史记录
  • router.back - 历史记录向回退
  • router.forward - 历史记录向前进
  • router.hasRoute() - 判断路由是否存在
  • router.getRoutes() - 获取所有路由组成的数组
  • router.addRoute($options) - 添加路由
  • router.removeRoute($name) - 删除路由
  • router.beforeEach((to, from, next) - 全局路由前置守卫
  • router.beforeResolve((to, from, next)  - 全局路由解析守卫
  • router.afterEach((to, from) - 全局路由后置守卫
  • ... ...

六,路由守卫

6.1 全局守卫

  • router.beforeEach(to, from, next)- 全局前置守卫。在路由跳转前触发类似于拦截器,主要用来做登陆验证
  • router.afterEach(to, from)- 全局后置守卫。在路由跳转完成后触发(因此没有next
  • router.beforeResolve(to, from, next)- 全局解析守卫。每次导航都会触发,他是在所有组件内守卫beforeEach和组件内beforeRouteEnter之后、afterEach之前调用。可以用来获取数据和执行操作等。

6.2 独享路由守卫

理解:直接在路由配置上定义,但是它只在进入路由时触发不会在 params、query 或 hash 改变时触发

示例:

const routes = [
  {
    path: '/detail/:id',
    component: appDetail,
    // 直接在路由配置中定义守卫
    beforeEnter: (to, from, next) => {
      next()
    },
  },
]

beforeEnter可以接受一个函数数组,用于路由守卫重用,例如:

const routes = [
  {
    path: '/detail/:id',
    component: appDetail,
    beforeEnter: [removeQueryParams, removeHash],
  }
]

// 守卫函数1
function removeQueryParams(to) {
  if (Object.keys(to.query).length)
    return { path: to.path, query: {}, hash: to.hash }
}

// 守卫函数2
function removeHash(to) {
  if (to.hash) return { path: to.path, query: to.query, hash: '' }
}

6.3 组件内的守卫

概念:组件内的路由守卫就像组件各个生命周期的钩子函数。

  • beforeRouteEnter(to,from, next) -- 进入之前。在渲染该组件的对应路由被验证前调用此时组件实例还没有被创建,不能访问this
  • beforeRouteUpdate(to,from, next) -- 路由变化时。在当前路由改变,但是该组件被复用时调用(触发这个的时候,组件已经挂载好了,可以访问this
  • beforeRouteLeave(to,from, next) -- 离开后。在导航离开渲染该组件的对应路由时调用(可以访问this

6.4 路由守卫触发顺序

页面加载时

1,全局前置守卫 - beforeEach

2,A组件独享守卫 - beforeEnter

3,A组件路由守卫 - beforeRouteEnter

4,全局解析守卫 - beforeResolve

5,全局后置守卫 - afterEach

[6,组件的挂载:beforeCreate => created => beforeMount]

7,A组件路由守卫 beforeRouteEnter 中的 next回调(此时能够获取到组件实例 vm

[8,A组件完成挂载:mounted]

点击切换路由时

1,A组件守卫 - beforeRouteLeave

2,全局前置守卫 - beforeEach

[3,在重用的组件里调用 beforeRouteUpdate ]

4,B组件独享守卫 - beforeEnter

5,B组件路由守卫 - beforeRouteEnter

6,全局解析守卫 - beforeResolve

7,全局后置守卫 - afterEach

[8,B组件挂载:beforeMount]

9,B组件路由守卫 beforeRouteEnter 中的 next回调

10,A组件beforeDestory

11,A组件destory

12,[B组件完成挂载mounted]

路由更新时

触发beforeRouteUpdate

七,异步获取数据

异步调用接口获取数据,通常有两种情况:

1,在导航完成之后调用接口(通过created或mounted

2,在导航完成之前调用接口,然后调用导航的next(vm => vm.setData())(通过beforeRouteEnter

示例:

// 导航完成之后
created() {
    const id = this.$route.params.id; // 从路由获取参数
    getList().then((response) => {
        if (response.code === 10000) {
            // ...
        }
    })
},

// 导航完成之前
beforeRouteEnter(to, from, next) {
    const id = to.params.id; // 从路由参数获取参数
    getList(id, (err, post) => { // 成功的回调
      next(vm => vm.setData(err, post)); // next方法接受的vm参数调setData传数据
    })
},

八,滚动scrollBehavior

概念:vue-router支持页面滚动效果实现,仅需提供一个scrollBehavior方法即可(在创建VueRoute对象时)。

使用方式scrollBehavior(to, from, savedPosition) { return 期望滚动到的位置 }

注意

  • 返回falsy空对象则不滚动。
  • savedPosition是在按下浏览器的前进、后退按钮时触发,返回一个位置对象

示例

const router = createRouter({
    history: createWebHashHistory(),
    routes: [...],
    scrollBehavior (to, from, savedPosition) {
        // 方式1:指定位置信息。滚动到顶部
        return { top: 0 };

        // 方式2:相对指定CSS选择器的偏移位置
        return { el: "#main", top: 10 };

        // 方式3:相对指定DOM元素的偏移位置
        let dom = document.getElementById('main');
        return { el: dom, left: 10 };

        // 方式4:滚动到锚点
        if (to.hash) {
            return { el: to.hash };
        }

        // 方式5:延迟滚动 - 返回一个promise对象,在resolve中传参位置信息
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve({ top: 10, left: 20});
            }, 500)
        })
    }
})
const router = createRouter({
  scrollBehavior(to, from, savedPosition) {
    if (savedPosition) {
      return savedPosition
    } else {
      return { top: 0 }
    }
  },
})

九,keep-alive

概念:keep-alive是vue的一个内置组件,主要作用是缓存组件在内存中,防止重复渲染dom。

常用属性

  • include - 字符串或正则。匹配到的name会被缓存
  • exclude - 字符串或正则。匹配到的name不会被缓存
  • max - 数字。最多可以缓存多少个组件实例

路由搭配应用

可以在路由的元信息meta中设置keepAlive属性,来判断是否需要缓存,例如:

{
  path: 'list',
  name: 'itemList',
  component: () => import '@/pages/item/list',
  meta: {
    keepAlive: true, // 保存当前路由是否需要缓存
    title: '列表页'
   }
}

<!-- 需要被缓存的组件 -->
<keep-alive>
    <router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
<!-- 不需要缓存的组件 -->
<router-view v-if="!$route.meta.keepAlive"></router-view>

删除keep-alive中的缓存:

1,首先对router-view标签设置ref属性(例如:<router-view ref="routerView"></router-view>)

2,通过delete删除ref.$vnode.parent.componentInstance.cache属性(例如:

delete this.$refs.routerView.$vnode.parent.componentInstance.cache)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

妍思码匠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值