美文网首页
前端理论面试-router+axios

前端理论面试-router+axios

作者: Smallbore | 来源:发表于2019-05-10 11:24 被阅读0次

    Vue Router

    Vue Router 是 Vue.js 官方的路由管理器。

    包含的功能有:

    嵌套的路由/视图表
    模块化的、基于组件的路由配置
    路由参数、查询、通配符
    基于 Vue.js 过渡系统的视图过渡效果
    细粒度的导航控制
    带有自动激活的 CSS class 的链接
    HTML5 历史模式或 hash 模式,在 IE9 中自动降级
    自定义的滚动条行为

    1.vue-router实现原理

    vue-router 提供了三种运行模式:
    ● hash: 使用 URL hash 值来作路由。默认模式。
    ● history: 依赖 HTML5 History API 和服务器配置。查看 HTML5 History 模式。
    ● abstract: 支持所有 JavaScript 运行环境,如 Node.js 服务器端

    1. hash 模式
      随着 ajax 的流行,异步数据请求交互运行在不刷新浏览器的情况下进行。而异步交互体验的更高级版本就是 SPA —— 单页应用。单页应用不仅仅是在页面交互是无刷新的,连页面跳转都是无刷新的,为了实现单页应用,所以就有了前端路由。
      类似于服务端路由,前端路由实现起来其实也很简单,就是匹配不同的 url 路径,进行解析,然后动态的渲染出区域 html 内容。但是这样存在一个问题,就是 url 每次变化的时候,都会造成页面的刷新。那解决问题的思路便是在改变 url 的情况下,保证页面的不刷新。在 2014 年之前,大家是通过 hash 来实现路由,url hash 就是类似于:
    http://www.xxx.com/#/login
    

    这种 #。后面 hash 值的变化,并不会导致浏览器向服务器发出请求,浏览器不发出请求,也就不会刷新页面。另外每次 hash 值的变化,还会触发hashchange 这个事件,通过这个事件我们就可以知道 hash 值发生了哪些变化。然后我们便可以监听hashchange来实现更新页面部分内容的操作:

    function matchAndUpdate () {
       // todo 匹配 hash 做 dom 更新操作
    }
    
    window.addEventListener('hashchange', matchAndUpdate)
    
    1. history 模式
      14年后,因为HTML5标准发布。多了两个 API,pushState 和 replaceState,通过这两个 API 可以改变 url 地址且不会发送请求。同时还有 popstate 事件。通过这些就能用另一种方式来实现前端路由了,但原理都是跟 hash 实现相同的。用了 HTML5 的实现,单页路由的 url 就不会多出一个#,变得更加美观。但因为没有 # 号,所以当用户刷新页面之类的操作时,浏览器还是会给服务器发送请求。为了避免出现这种情况,所以这个实现需要服务器的支持,需要把所有路由都重定向到根页面。
    function matchAndUpdate () {
       // todo 匹配路径 做 dom 更新操作
    }
    
    window.addEventListener('popstate', matchAndUpdate)
    

    3.abstract模式
    abstract模式是使用一个不依赖于浏览器的浏览历史虚拟管理后端。
    根据平台差异可以看出,在 Weex 环境中只支持使用 abstract 模式。 不过,vue-router 自身会对环境做校验,如果发现没有浏览器的 API,vue-router 会自动强制进入 abstract 模式,所以 在使用 vue-router 时只要不写 mode 配置即可,默认会在浏览器环境中使用 hash 模式,在移动端原生环境中使用 abstract 模式。 (当然,你也可以明确指定在所有情况下都使用 abstract 模式)。

    2.路由钩子

    vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。有多种机会植入路由导航过程中:全局的, 单个路由独享的, 或者组件级的。

    全局前置守卫

    const router = new VueRouter({ ... })
    
    router.beforeEach((to, from, next) => {
      // ...
    })
    

    当一个导航触发时,全局前置守卫按照创建顺序调用。守卫是异步解析执行,此时导航在所有守卫 resolve 完之前一直处于 等待中。
    确保要调用 next 方法,否则钩子就不会被 resolved。


    全局解析守卫
    在 2.5.0+ 你可以用 router.beforeResolve 注册一个全局守卫。这和 router.beforeEach 类似,区别是在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被调用。


    全局后置钩子

    router.afterEach((to, from) => {
      // ...
    })
    

    你也可以注册全局后置钩子,然而和守卫不同的是,这些钩子不会接受 next 函数也不会改变导航本身:

    路由独享的守卫

    const router = new VueRouter({
      routes: [
        {
          path: '/foo',
          component: Foo,
          beforeEnter: (to, from, next) => {
            // ...
          }
        }
      ]
    })
    

    你可以在路由配置上直接定义 beforeEnter 守卫:
    这些守卫与全局前置守卫的方法参数是一样的


    组件内的守卫

    const Foo = {
      template: `...`,
      beforeRouteEnter (to, from, next) {
        // 在渲染该组件的对应路由被 confirm 前调用
        // 不!能!获取组件实例 `this`
        // 因为当守卫执行前,组件实例还没被创建
      },
      beforeRouteUpdate (to, from, next) {
        // 在当前路由改变,但是该组件被复用时调用
        // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
        // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
        // 可以访问组件实例 `this`
      },
      beforeRouteLeave (to, from, next) {
        // 导航离开该组件的对应路由时调用
        // 可以访问组件实例 `this`
      }
    }
    

    完整的导航解析流程

    导航被触发。
    在失活的组件里调用离开守卫。
    调用全局的 beforeEach 守卫。
    在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+)。
    在路由配置里调用 beforeEnter。
    解析异步路由组件。
    在被激活的组件里调用 beforeRouteEnter。
    调用全局的 beforeResolve 守卫 (2.5+)。
    导航被确认。
    调用全局的 afterEach 钩子。
    触发 DOM 更新。
    用创建好的实例调用 beforeRouteEnter 守卫中传给 next 的回调函数。

    Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。
    • 从浏览器中创建 XMLHttpRequests
    • 从 node.js 创建 http 请求
    • 支持 Promise API
    • 拦截请求和响应
    • 转换请求数据和响应数据
    • 取消请求
    • 自动转换 JSON 数据
    • 客户端支持防御 XSRF

    拦截器

    // 添加请求拦截器
    axios.interceptors.request.use(function (config) {
        // 在发送请求之前做些什么
        return config;
      }, function (error) {
        // 对请求错误做些什么
        return Promise.reject(error);
      });
    
    // 添加响应拦截器
    axios.interceptors.response.use(function (response) {
        // 对响应数据做点什么
        return response;
      }, function (error) {
        // 对响应错误做点什么
        return Promise.reject(error);
      });
    

    如果你想在稍后移除拦截器,可以这样:

    var myInterceptor = axios.interceptors.request.use(function () {/*...*/});
    axios.interceptors.request.eject(myInterceptor);
    

    与ajax区别
    Ajax:

    Ajax 即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML),是指一种创建交互式网页应用的网页开发技术。
      Ajax = 异步 JavaScript 和 XML(标准通用标记语言的子集)。
      Ajax 是一种用于创建快速动态网页的技术。
      Ajax 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。
      通过在后台与服务器进行少量数据交换,Ajax 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
      传统的网页(不使用 Ajax)如果需要更新内容,必须重载整个网页页面。

    // 理论无技巧,想过全靠死记。

    相关文章

      网友评论

          本文标题:前端理论面试-router+axios

          本文链接:https://www.haomeiwen.com/subject/omjooqtx.html