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

本人前端小菜鸡,如有不对请谅解

(0)
上一篇 2021年5月26日 下午9:00
下一篇 2021年5月26日 下午9:15

相关推荐

发表回复

登录后才能评论