ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

vue项目(通用方法+axios自定义+http请求统一管理绑定+vue.config.js别名alias配置)

2021-03-16 16:57:34  阅读:107  来源: 互联网

标签:vue const 自定义 com js api import message config


目录

1、vue.config.js别名配置与使用

2、通用方法全局使用(自定义插件)

3、axios自定义

4、http请求统一管理绑定


1、vue.config.js别名配置与使用

新建vue-cli3项目中默认是没有vue.config.js,自己在根目录新建。项目默认会定义 @ 代表 src目录

下面是个人项目中部分配置,还包括svg使用类名与组件引入类似于element-ui的icon引入设置,文件压缩等配置,可以参照vue-admin-template,后面项目空了再发一下一下配置,包括npm包与组件使用,代码eslint统一规范

//根目录 vue.config.js
'use strict'
const path = require('path')
// 完整绝对路径
 let resolve = (dir)=> path.join(__dirname, dir)
const defaultSettings = require('./src/config/settings.js')
module.exports = {
  runtimeCompiler: true,
  productionSourceMap: false,
  // assetsDir 随便定义,为public即打包之后除了index.html其他资源存在public目录中
  // assetsDir: 'public',
  configureWebpack: config => {
    // 项目名称,不同页面的名称在路由守卫设置即可
    config.name = defaultSettings.title || '通行管理系统'
    // 生产环境清除开发打印与debugger
    if (process.env.NODE_ENV === 'production') {
      config.optimization.minimizer[0].options.terserOptions.compress.warnings = false
      config.optimization.minimizer[0].options.terserOptions.compress.drop_console = true
      config.optimization.minimizer[0].options.terserOptions.compress.drop_debugger = true
      config.optimization.minimizer[0].options.terserOptions.compress.pure_funcs = [
        'console.log'
      ]
    }
  },
// 别名设置  自定义
  chainWebpack(config) {
    config.resolve.alias
      .set('@', resolve('src'))
      .set('style', resolve('src/assets/scss'))
      .set('com', resolve('src/comJs'))
      .set('@img', resolve('src/assets/image'))
  },
// 开发配置
  devServer: {
    port: process.env.VUE_APP_PORT || '9527',
    open: true,
// eslint 配置,觉得问题多直接设置成false,重新run即可
    overlay: {
      warnings: true,
      errors: true
    },
// 代理
    proxy: {
      '^/disease': {
        target: 'https://view.inews.qq.com/',
        changeOrigin: true,
        ws: true,
        pathRewrite: {
          '^/disease': '' //路径重写
        }
      }
    }
  }
}

 上面配置中设置了  style  ===  src/assets/scss; @img === src/assets/image,相信这两个目录是项目中最常用到的部分,以前项目未重视,页面充斥着大量的 ../../../等等,尤其是在scss文件 import或者设置图片背景时候最容易出现路径问题,并且使用相对路径引入还显得比较low,在这里设置了别名再也不用担心路径带来的额外工作量,下面说下使用

1、script中直接 使用  import * as com from 'com/com' 这里com就指代src目录下的comJs的路径

2、style使用  scss中引入 @import '~style/app.scss';等于引入src/assets/scss/app.scss的资源;css中引入背景:background: url(~@img/m.jpg);

3、template中使用 <img src="~@img/m.jpg" alt="" hidden ref="imgs" />

避免出现一些问题 除了JS引入之外最好前面添加  ~

2、通用方法全局使用(自定义插件)

主要是将一些通用方法或者正则校验规则与http请求统一批量挂载到Vue.prototype,组件中可以直接this.直接调用,避免了大量的import {} from '..'引入操作,尤其是配置eslint之后出现变动会有大量报错之类

 1.直接在src目录中新建plugin目录 创建index.js文件,作为作为项目公共方法与请求的入口,统一管理

如上一篇文章message重写了message.js,多数操作是将message.js引入main.js,再挂到prototype上面,如果此类方法增多就会显得很臃肿,因此单独plugin模块管理还是有必要的,下面呢直接上代码;

// plugn/index.js
// 路径com就是上面的别名设置
import { message } from 'com/resetMessage'
const install = Vue => {
  if (install.installed) return false
  // 添加到Vue的原型链上
  Object.defineProperties(Vue.prototype, {
    $message: { value: message }
  })
  install.installed = true
}

export default install

// main.js

// 导入自定义插件
import plugin from '@/plugin'
Vue.use(plugin)

// 此时所有组件均可直接使用 this.$message.success()

 上面代码中既然能引入message.js,其他公共类方法亦可直接引入挂载,如项目中一般会用到大量公共方法,一般存放在 com.js中,类似于下面的方法

// com.js

import moment from 'moment'
/**
 * @description:使用moment将任意时间转化为标准格式
 * @param {参数需要格式化时间,必传} time
 * @param {格式化标准,'YYYY-DD-MM HH:mm:ss'} format
 * @return {*}
 */
export const formatTime = (time, format) => {
  if (!arguments.length) return ''
  if (!format) format = 'YYYY-DD-MM HH:mm:ss'
  const timer = moment(time).format(format)
  return timer
}

一般公共类的方法在组件中常规用法就是 import {formatTime} from ;;;;;用一次引入一次较为繁琐,参照上面message.js,也可以直接引入

// plugin/index.js
import * as com from 'com/com'
.....
const install = Vue => {
  .....
  Object.defineProperties(Vue.prototype, {
    .....
    $com: { value: com }
  })
  install.installed = true
}

export default install

// 组件内就能直接使用 this.$com.formatTime() 进行调用,dom中直接 $com.xxx;但是其他JS文件中无this,只能使用import引入之后单个使用,当然这种情况极少

稍微补充点,不仅仅是公共类方法,后台管理类项目中有大量的表单填写与修改,字段不多但是界面与弹窗较多,表单正则也就十几条,也可以考虑单独存放一个JS文件中统一管理

 无论是element-ui还是vue-ant或者是iview之类UI框架都能直接使用,代码如下:

// com/verify.js
/**
 * 验证手机号码是否正确
 * @param tel
 * @returns {boolean}
 */
export const isTel = tel => /^1[3|4|5|8][0-9]\d{4,8}$/.test(tel)
export const regTel =  /^1[3|4|5|8][0-9]\d{4,8}$/

// 如上校验结果与正则regTel

// plugin/index.js
import * as verify from 'com/verify'
......
const install = Vue => {
.....
  Object.defineProperties(Vue.prototype, {
    $valid: { value: verify },
   .....
  })
  install.installed = true
}

export default install

// 组件内使用 
console.log(this.$valid.isTel('1000'))  返回false
// 以element-ui为例,一般表单中会有rules,可如下使用
 rules: {
        phoneNumber: [
          { required: true, message: '手机号码不能为空', trigger: 'blur,change' },
          { pattern: this.$valid.regTel, message: '请输入正确手机号码' }
        ],
        genderCode: [
          { required: true, message: '性别不能为空', trigger: 'blur,change' }
        ]
    }
// 此前项目没考虑这个,这次新的考虑添加,简单测试下
// data:{ return(){ isBool:this.$valid.isTel('1000') } }能正常使用,有问题欢迎交流

3、axios自定义

// com/api.js
import axios from 'axios'
import { message } from 'com/resetMessage'
// import store from '@/store'
export const localIp = process.env.VUE_APP_BASE_API
// .env.development中配置开发环境的IP, baseUrl为获取当前web部署环境的ip,端口不变不需要额外配置
export const baseUrl = port => {
  if (!port) {
    port =  '9527'
  }
  let hostname = window.location.hostname
  let origin = 'http://' + hostname + ':' + port
  let url = ''
  url =
    process.env.NODE_ENV === 'development'
      ? 'http://' + localIp + ':' + port
      : origin
  return url
}
const service = axios.create({
  baseURL: baseUrl(),
  // withCredentials: true, // send cookies when cross-domain requests
  timeout: 5000 // request timeout
})
let Authorization = getToken('Authorization')
service.interceptors.request.use(
  config => {
    if (Authorization) {
      config.headers['Authorization'] = Authorization
      return config
    } else {
      return false
    }
  },
  error => {
    Promise.reject(error)
  }
)
service.interceptors.response.use(
  response => {
    const res = response.data
    if (!res.success) {
      message({
        message: res.msg || 'Error',
        type: 'error',
        duration: 1000
      })
      Promise.reject(res)
    } else {
      if (res.msg !== 'fail') {
        return res
      } else {
        // 若是token过期即
        // message.error(data2.msg, 1, () => {
        //   router.push('/login')
        // })
        return res
      }
    }
  },
  error => {
    message({
      message: error,
      type: 'error' || '网络错误',
      duration: 1000,
      onClose: () => {
        Promise.reject(error)
      }
    })
  }
)

export default service

使用:import request from 'comjs/api' 

request({ url: userUrl.login, data, method: 'post' }).then(res=>{}).catch(e=>{})

或者直接在main.js中引入挂载到prototype上面,全局使用 this.$request()调用。在上面能看到无论是公共类方法或者校验都能直接在 plugin/index.js中挂载,作为统一入口,当然http请求也不例外,统一管理

4、http请求统一管理绑定

下面先看一下个人项目定义的目录

如上图所示,项目中将http请求分两个部分:constant中存放不同模块的静态url,modules中分别引入对应模块的静态url,定义使用request方法;src/api/index.js 则是读取modules目录下的所有js文件(统一批量注册vue全局公共组件此处方法类似,看过的话应该能更好理解),批量引入并在plugin/index.js中挂载,任意组件均可使用

下面分别看下各个文件代码

// api/constant/user.js
// 存放静态url,方便管理
export const login = '/UserController/login' // 登录
export const handleObj = '/ImgObjController/obj' // 操作


// api/modules/user.js
// 一般存放登录、登出、个人信息或者权限之类公共接口
import request from 'comJs/api'
import * as userUrl from '@/api/constant/user'
// 登录
export const login = data => {
  return request({ url: userUrl.login, data, method: 'post' })
}

modules中包含多个文件,多人开发互不干扰(明天有时间就分享一下多人开发代码格式问题),个人感觉分块维护较为方便;下面看下  api/index.js文件

// api/index.js
// 文件夹下嵌套js文件,进行驼峰命名转换
let _result = {}
const camelCaseChange = (str, separator = '/') =>
  str.replace(new RegExp(`${separator}(\\w)`, 'g'), str =>
    str.slice(1).toUpperCase()
  )
// 读取modules中的http请求
const context = require.context('./modules', true, /\.js$/)
context.keys().map(item => {
  const k = camelCaseChange(item.match(/\.\/(\S*)\.js$/)[1])
  // console.log('获取数据', item.match(/\.\/(\S*)\.js$/))
  _result[k] = context(item)
})
export default _result

最后一步就是将 api/index.js文件读取到module对象 {blog: Module, user: Module}  挂载到vue.prototype上面方便全局调用

// plugs/index.js
// 下面api 相当于 {blogs:module,user:module}
......
import api from '@/api'
const install = Vue => {
  .....
  Object.defineProperties(Vue.prototype, {
    .....
    $api: { value: api },
  })
  install.installed = true
}

export default install

// 此时挂载到全局之后,在所有组件中都不需要再次 Import请求名称函数
// 组件内使用,可以链式调用如下
this.$api.user.login(params).then(res=>{})
this.$api.blogs.getList(params).then(res=>{})

// 也可使用async和await
async Login(){
  const data = await this.$api.user.login(params)
  console.log(data)
}

 

标签:vue,const,自定义,com,js,api,import,message,config
来源: https://blog.csdn.net/H_Elie/article/details/114871299

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有