020.Axios与Vue中的几个问题

Posted Ruovan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了020.Axios与Vue中的几个问题相关的知识,希望对你有一定的参考价值。


01. Axios 封装

(1)引入Axios

import axios from 'axios'

(2)创建实例

const request = axios.create({
    // 配置项
})

(a)关于配置项:

  • baseURL:请求地址前缀,将自动添加在URL前面

    • 通常,对于开发环境和生产环境有这不一样的baseURL
    • 因此,需要根据不同环境来切换不同的bseURL
    baseURL: process.env.NODE_ENV === 'production' ? '/production' : '/development'
    
  • timeout:设置默认的请求超时时间,单位为毫秒,超过这个时间就会请求失败

    timeout: 10000
    

(3)请求拦截

  • 在发送请求之前,对请求进行拦截,在这里对数据进行一些处理
    • 一般用于在请求头中添加Token,判断登录状态
// 请求拦截器 request
request.interceptors.request.use(    
    config => {
        // 拦截之后做一些处理。如:判断是否有token
        const token = localStorage.getItem('token')
        if(token){
            // 如果有token,则在请求头中添加token
            config.headers['X-Token'] = token
        }
        // 处理完后必须返回 config
        return config
    },    
    error => {
        return Promise.reject(error)
    })
}

(4)响应拦截

  • 对服务器返回给我们的数据进行拦截,在获取到这个数据之前,对这个数据进行一些处理判断
    • 主要用于对错误进行统一处理
// 响应拦截器 response
request.interceptors.response.use(
    // 请求成功
    response => {
        if (response.status === 200) {  
            // 如果返回的状态码为200,说明接口请求成功,可以正常拿到数据
            return Promise.resolve(response);        
        } else {  
            // 否则的话抛出错误
            return Promise.reject(response);        
        }
    },
    // 请求失败
    error => {
        // 对其它返回错误做操作。如401、403、404等
        return Promise.reject(error)
    }
)

(5) 请求

  • 可以对getpost请求进行封装,不过我个人习惯以下写法
// api.js
import request from '@/utils/request'

export default getList(params){
    return request({
        url: '/',
        method: 'get',
        params
    })
}

export default postList(data){
    return request({
        url: '/',
        method: 'post',
        data
    })
}

(6)使用

  • 直接引入API文件进行使用,可以全局引入,也可以按需引入
import { getList, postList } from '@/api/api.js'

getList(params).then(res => {
    // ...
}).catch(error => {
    // ...
})

(7)终

// request.js
import axios from 'axios'

const request = axios.create({
    baseURL: process.env.NODE_ENV === 'production' ? `/` : '/apis', // 配置基准地址
    headers: {
        get: {
            'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'
        },
        post: {
            'Content-Type': 'application/json;charset=utf-8'
        }
    },
    timeout: 30000, // 配置超时时间
})

// 请求拦截器
request.interceptors.request.use(
    config => {
        return config
    }, 
    error => {
        // 错误抛到业务代码
        error.data = {}
        error.data.msg = '服务器异常,请联系管理员!'
        return Promise.resolve(error)
    }
)

// 响应拦截器
request.interceptors.response.use(
    // 请求成功
    response => {
        const status = response.status // 获取状态码
        let msg = ''
        if (status < 200 || status >= 300) {
            // 处理http错误,抛到业务代码
            msg = showStatus(status)
            if (typeof response.data === 'string') {
                response.data = { msg }
            } else {
                response.data.msg = msg
            }
        }
        return response
    }, 
    // 请求
    error => {
        console.log('err' + error)
        Message({
            message: error.message,
            type: 'error',
            duration: 5 * 1000
        })
        return Promise.reject(error)
    }
)

const showStatus = status => {
    let message = ''
    switch (status) {
        case 400:
            message = '400:请求错误'
            break
        case 401:
            message = '401:未授权,请重新登录'
            break
        case 403:
            message = '403:拒绝访问'
            break
        case 404:
            message = '404:请求资源不存在'
            break
        case 405:
            message = '405:请求方法不允许'
        case 408:
            message = '408::请求超时'
            break
        case 500:
            message = '500:内部服务器错误'
            break
        case 501:
            message = '501:服务未实现'
            break
        case 502:
            message = '502:网络错误'
            break
        case 503:
            message = '503:服务不可用'
            break
        case 504:
            message = '504:网络超时'
            break
        case 505:
            message = 'HTTP版本不受支持(505)'
            break
        default:
            message = `连接错误,错误代码:(${status})!`
    }
    return `${message},请检查网络或联系管理员!`
}

export default request

02. 如何重置Vue中的data?

  • 使用:Object.assign(newObj, oldObj)

    • this.$data:获取当前状态下的data
    • this.$options.data():获取该组件初始状态下的data
    Object.assign(this.$data, this.$options.data())
    
    // 如果只是重置某一个属性
    this.id = this.$options.data().id;
    

03. 组件中的data为什么是函数?

  • 因为JavaScript的特性所导致,在组件中,data必须以函数的形式存在,不可以是对象

    • 函数返回值的形式定义,每次复用组件的时候,都会返回一份新的data
    • 而以对象形式定义,所有的组件实例将共用一个data,因为对象是引用类型
  • 因此,为了保证组件不同的实例之间的数据不冲突,data必须是一个函数

04. 【vue-loader】的作用是什么?

  • 作用:一个基于Webpack的loader,可以解析和转换.vue文件

    • 提取templatescriptstyle标签中代码,并分别把他们交给对应的loader处理,转换为JS模块

05. 【keep-alive】的作用是什么?

  • keep-alive 是 Vue 内置的一个组件,可以使被包含的组件保留状态、进入缓存,避免重新渲染

06. Vue.use是什么?

  • vue.use 是用来使用插件的,我们可以在插件中扩展全局组件、指令、原型方法等

  • Vue.js 的插件应该暴露一个 install 方法。这个方法的第一个参数是 Vue 构造器,第二个参数是一个可选的选项对象,用于传入插件的配置

  MyPlugin.install = function (Vue, options) {
      // 1. 添加全局方法或属性
      Vue.myGlobalMethod = function () {
          // 逻辑...
      }
      // 2. 添加全局资源
      Vue.directive('my-directive', {
          bind (el, binding, vnode, oldVnode) {
              // 逻辑...
          }
          ...
      })
      // 3. 注入组件选项
      Vue.mixin({
          created: function () {
              // 逻辑...
          }
          ...
      })
      // 4. 添加实例方法
      Vue.prototype.$myMethod = function (methodOptions) {
          // 逻辑...
      }
      // 5. 注册全局组件
      Vue.component('myButton',{
          // ...组件选项
      })
  }
  
  // --------------
  Vue.use(MyPlugin, {
      // 参数
  })
  

在使用Vue.use()的时候,就会调用插件内部的install方法

  • 插件传入的如果是一个对象,则执行其install方法
  • 如果是一个函数,则执行它自身,并bind thisnull,然后传入额外的参数

07. 如何在Vue实例上挂载一个属性/方法?

  • 使用Vue.prototype.$xx在Vue的原型上添加一个属性/方法,这样可以在任意实例上读取

08. SPA 单⻚⾯的优缺点是什么?

  • 概念:SPA即 single-page application ,仅在⻚⾯初始化时加载相应的 htmljavascript 和 CSS
    • ⼀旦⻚⾯加载完成,SPA 不会因为⽤户的操作⽽进⾏⻚⾯的重新加载或跳转
    • 取⽽代之的是利⽤路由机制实现 HTML 内容的变换,UI 与⽤户的交互,避免⻚⾯的重新加载
  • 优点:
    • 1)⽤户体验好、快,内容的改变不需要重新加载整个⻚⾯,避免了不必要的跳转和重复渲染
    • 2)SPA 相对服务器压⼒⼩
    • 3)前后端职责分离,架构清晰,前端进⾏交互逻辑,后端负责数据处理
  • 缺点:
    • 1)⾸屏(初次)加载慢:为实现单⻚ Web 应⽤功能及显示效果,需要在加载⻚⾯的时候将JavaScript、CSS 统⼀加载,部分⻚⾯按需加载
    • 2)不利于 SEO:由于所有的内容都在⼀个⻚⾯中动态替换显示,所以在 SEO 上其有着天然的弱势

以上是关于020.Axios与Vue中的几个问题的主要内容,如果未能解决你的问题,请参考以下文章

回归 | js实用代码片段的封装与总结(持续更新中...)

VSCode自定义代码片段1——vue主模板

VSCode自定义代码片段——.vue文件的模板

VSCode自定义代码片段(vue主模板)

vue中的组件

VSCode自定义代码片段11——vue路由的配置