IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 我的第一个项目复盘 -> 正文阅读

[JavaScript知识库]我的第一个项目复盘

前言

来公司实习这段时间,算是自己正真的做了一个项目(内容洞察),虽说是老项目的新需求吧,但是我还是用了自己学习的很多技术,比如说对axios的二次封装、对环境变量的封装、对工具函数的封装等等,也遇到了很多的问题,比如用element的uplod组件对文件进行上传时,回显图片的问题(以前写项目的时候都是上传图片后台会返回给我一个地址,然后我回显到当前文件列表中,但是这个项目要求的是上传图片后不立刻调用接口,而是要等用户点击确定后才上传,那么回显图片就成了问题),调用接口的时候请求头是multiparty/formData格式的问题等等

技术总结

axios的封装

感悟:

在封装axios的时候也遇到了一个问题,因为后端的接口会用到application/json application/x-www-form-urlencoded application/multipart/formdata这三种格式的请求头,我的想法是创建3个单独的实例,然后单独的设置请求头,(至于3个js文件的公公共部分我想抽离的,但是试了好久,都以失败告终,然后就暂时放弃,),这种方法我在自己的demo中测试过是可行的,但是到了这个项目,却发现全局的axios都被影响了,弄了好久,查官方文档,百度都被我翻烂了,都无济于事,在第二天我突然想到,会不会是axios版本的问题,果然,是版本的问题,老的版本虽然可以单独创建实例,但是修改请求头的类型会影响全局的axios请求,至于开始为什么不往这方面想呢,想着这个项目应该不算很老,单独创建实例也生效,没想到啊~~

总结

下次遇到类似问题,先去官网、网上查看一下当前版是否支持该种写法

代码

这里只是罗列了一个文件,其他的2个文件都一样只不过请求头变了一下(个人感觉这样的写法还是冗余,等找到好的方法再来分享)

/**
 * @author Jack
 * axios的二次封装
 */
import axios from 'axios'
import config from '../config/index'
// 要单独下载qs包
import Qs from 'qs'
import { getToken } from '@/utils/auth'

let instance = axios.create({
  baseURL: config.baseApi,
  timeout: 8000
})


instance.defaults.headers['Content-Type'] = 'application/x-www-form-urlencoded'

// 当请求是urlencode时用qs转换
instance.defaults.transformRequest = (data, headers) => {
  console.log(data)
  console.log(headers)
  const contentType = headers['Content-Type']
  if (contentType === 'application/x-www-form-urlencoded') {
    return Qs.stringify(data)
  }
}
// 请求拦截
instance.interceptors.request.use((request) => {
  // 添加token
  const headers = request.headers
  if (!headers.Authorization) headers.Authorization = getToken()
  return request
})
// 响应拦截
instance.interceptors.response.use(
  (response) => {
    console.log(response, '===>response')
    return response.data
  },
  (resaon) => {
    return Promise.reject(resaon)
  }
)

/**
 * 请求核心函数
 * @param {*} options 请求配置
 * @returns
 */

function request(options) {
  // 没有写method 就是默认get
  options.method = options.method || 'get'
  // 将get请求的参数转换成 params
  if (options.method.toLowerCase() === 'get') {
    options.params = options.data
  }
  // 判断私有mock
  // 如果当前options有mock 那么就将config的mock变成当前的
  // 覆盖了下面mock
  console.log(options.mock)
  if (typeof options.mock !== 'undefined') {
    config.mock = options.mock
  }

  // 判断环境
  if (config.env === 'production') {
    instance.defaults.baseURL = config.baseApi
  } else {
    instance.defaults.baseURL = config.mock ? config.mockApi : config.baseApi
  }
  console.log(options, 'options')
  return instance(options)
}

/**
 * 这种方式外界可以通过
 * this.$request.get('url',data,options)的方式发送请求
 */
;['get', 'post', 'put', 'delete', 'patch'].forEach((item) => {
  request[item] = (url, data, options) => {
    return request({
      url,
      data,
      method: item,
      ...options
    })
  }
})

export default request

环境的封装

感悟

这里要说一下,用到了mock数据,这个我以前也是不了解的,来了这个公司也听别人说过,但是还是模棱两可,主要原因是没接触过。直到在课上的项目老师讲了,并且项目中用了才有所了解。所谓mock,就是自己模拟后端接口做的假数据,当实际开发的时候前后端是分离的,后端会先将api文档给前端,然后前端在根据文档mock数据,到最后联调的时候只需要将mock接口换成后端接口即可

/**
 * @author Jack
 * 环境配置
 */

// vue项目中获取环境变量 
const env = process.env.NODE_ENV || 'production'
const baseApi = process.env.VUE_APP_BASE_API
console.log(process.env, 'env')

const EnvConfig = {
  development: {
    baseApi: baseApi,
    mockApi:
      'https://console-mock.apipost.cn/app/mock/project/d4a9c329-67d4-4f51-8237-414b7d5234ee'
  },
  test: {
    baseApi: '/',
    mockApi: ''
  },
  production: {
    baseApi: baseApi,
    mockApi: ''
  }
}

export default {
  env,
  mock: false,
  ...EnvConfig[env]
}

调用接口的封装

感悟

最开始的时候就是想将请求单独拎出来(学习的课上就是这么写的),然年跟师傅讨论了一下,师傅说,这是老项目到时候遇到了问题不好调试,然后我就没这么写,直到项目第一次上线遇到了前面axios封装的问题,组长说你想要代码清爽点可以使用这种方法,然后就换回来了,每个页面的请求都单独放到了一个js文件中,直接在需要的页面引入即可。

/**
 * @author Jack
 * app管理的请求
 */
import request from '@/views/newDMP/mediaAnalyse/utils/request'
import requestJson from '@/views/newDMP/mediaAnalyse/utils/requestJson'

export default {
  initDataApp(data) {
    return requestJson({
      method: 'post',
      url: '/app/manage/queryAppListByPage',
      data,
      mock: false
    })
  },

  confirmMonitor(data) {
    return requestJson({
      method: 'post',
      url: '/app/manage/batchMonit',
      data,
      mock: false
    })
  },

  cancelMonitor(data) {
    return requestJson({
      method: 'post',
      url: '/app/manage/batchCancelMonit',
      data,
      mock: false
    })
  },

问题总结

图片回显

感悟

基于element的upload上传文件的时候,以前写项目的时候,当上传图片后,会立刻调用action的地址,然后返回给我一个地址,然后我回显到当前文件列表中,但是这个项目要求的是上传图片后不立刻调用接口,而是要等用户点击确定后才上传,那么回显图片就成了问题,

解决

在el-upload的钩子中拿到当前上传的文件流,然后用函数将file文件流转换成url地址,本来是将文件流转换成base64格式的但是file-list不支持,然后后端要求在用户编辑的时候没有修改图片就随便传一个文件流,于是我将一个图片用import的方式引入,这种方式引入的文件是base64格式的,然后我用一个函数将base64文件转化成file流

代码

<!--部分代码-->
<el-upload
   ref="productImgRef"
    action="action"
    list-type="picture-card"
    :before-upload="beforeUpload"
    :file-list="imgFileList"
    >
      </el-upload>


// 图片上传前的钩子
    beforeUpload(file) {
      console.log(file)
      // 判断文件类型
      if (this.imgType.indexOf(file.type) === -1) {
        this.$message.info('请上传jpeg、jpg、png类型的图片')
        return
      }
      // 判断文件大小
      if (file.size > this.fileSize) {
        this.$message.info('图片大小需在1M以内')
        return
      }
      console.log(getfilesize(file.size))
      this.dataForm.image = file
      this.dataForm.type = 1

      const url = getObjectURL(file)
      console.log(getObjectURL(file))

      this.imgFileList = [{ name: 'imagePath', url }]
      return false
    },

// 工具函数

// 获取file文件流的url
export function getObjectURL(data) {
  var url = null
  if (window.createObjectURL !== undefined) {
    // basic
    url = window.createObjectURL(data)
  } else if (window.webkitURL !== undefined) {
    // webkit or chrome
    try {
      url = window.webkitURL.createObjectURL(data)
    } catch (error) {
      console.log(error)
    }
  } else if (window.URL !== undefined) {
    // mozilla(firefox)
    try {
      url = window.URL.createObjectURL(data)
    } catch (error) {
      console.log(error)
    }
  }
  return url
}

// 将base64文件转为File文件流
export function base64toFile(dataurl, filename = 'file') {
  let arr = dataurl.split(',')
  let mime = arr[0].match(/:(.*?);/)[1]
  let suffix = mime.split('/')[1]
  let bstr = atob(arr[1])
  let n = bstr.length
  let u8arr = new Uint8Array(n)
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n)
  }
  return new File([u8arr], `${filename}.${suffix}`, {
    type: mime
  })
}

上传formData类型的文件

感悟

以前的项目很少用到这个请求的类型,虽说学过,但是也没想起来。当上传图片的时候需要将请求头设置为multiparty/form-data。然后我就按照常规的请求给数据了,结果就是后端报错。

解决

单独配置请求头为multiparty/form-data, 要new一个formData实例,使用formData.append()添加字段,请求的时候将创建的formData做为请求体传入即可

代码

api文件

 handelConfirm(data) {
    return requestJson({
      method: 'post',
      url: 'app/manage/informationConfig',
      data,
      mock: false,
      headers: {
        'Content-Type': 'multipart/form-data'
      }
    })
  }

页面文件

 async handelConfirm() {
      const { id, type, image, introduction } = this.dataForm

      const formData = new FormData()
      formData.append('image', image)

      formData.append('id', id)
      formData.append('type', type)
      formData.append('introduction', introduction)

      const { code, msg } = await http.handelConfirm(formData)
      if (code === 0) {
        this.$message.success('配置信息成功')
        this.configDialogClosed()
        console.log(this.$parent)
        this.$nextTick(() => {
          this.$parent.initData()
        })
        t
      } else {
        this.$message.error(msg)
      }
    }

-----------------------未完待续-----------------------------------

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-04-28 11:44:26  更:2022-04-28 11:45:53 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 0:53:14-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码