Vue project (general method + axios customization + http request unified management binding + vue.config.js alias configuration)

catalogue

1,vue.config.js alias configuration and use

2. General method global use (custom plug-in)

3. axios customization

4. http request unified management binding

1,vue.config.js alias configuration and use

There is no Vue in the new vue-cli3 project by default config. JS, create a new one in the root directory. By default, the project defines @ for src directory

The following are some configurations in the personal project, including the use of class name and component introduction of svg, icon introduction settings similar to element UI, file compression and other configurations. You can refer to Vue admin template. If the later project is empty, send the configuration again, including the use of npm package and component, and the unified specification of code eslint

//Root directory Vue config. js
'use strict'
const path = require('path')
// Full absolute path
 let resolve = (dir)=> path.join(__dirname, dir)
const defaultSettings = require('./src/config/settings.js')
module.exports = {
  runtimeCompiler: true,
  productionSourceMap: false,
  // assetsDir is defined casually as public, that is, after packaging, except index HTML other resources exist in the public directory
  // assetsDir: 'public',
  configureWebpack: config => {
    // Project name. The names of different pages can be set in the routing guard
    config.name = defaultSettings.title || 'Traffic management system'
    // Production environment development, printing and 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'
      ]
    }
  },
// Alias settings customization
  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'))
  },
// Development configuration
  devServer: {
    port: process.env.VUE_APP_PORT || '9527',
    open: true,
// eslint configuration. If you think there are many problems, you can directly set it to false and rerun
    overlay: {
      warnings: true,
      errors: true
    },
// agent
    proxy: {
      '^/disease': {
        target: 'https://view.inews.qq.com/',
        changeOrigin: true,
        ws: true,
        pathRewrite: {
          '^/disease': '' //Path rewriting
        }
      }
    }
  }
}

style = = = src/assets/scss is set in the above configuration@ img === src/assets/image. I believe these two directories are the most commonly used parts of the project. Previous projects did not pay attention to them, and the page is full of a large number of.. /.. // And so on, especially when import ing scss files or setting picture backgrounds, path problems are most likely to occur, and the use of relative path introduction is also relatively low. There is no need to worry about the additional workload caused by the path after setting the alias here. Let's talk about the use below

1. script directly uses' import * as com 'from' COM / COM ', where com refers to the path of comJs in src directory

2. Use @ import '~ style / APP. In style SCSS scss'; Equal to introducing Src / assets / SCSS / APP Resources of SCSS; Introduction background in css: background: url(~@img/m.jpg);

3. Use < img SRC = "~ @ img / m.jpg" ALT = "" hidden ref = "IMGs" / > in template

To avoid some problems, it's best to add it in front of JS~

2. General method global use (custom plug-in)

It is mainly to mount some general methods or regular verification rules and http requests to Vue Prototype, the component can directly this Direct call avoids a large number of import {} from '..' Introduce operations, especially changes after configuring eslint, and there will be a large number of errors

 1. Directly create a new plugin directory in the src directory and create an index JS file, as the entry of public methods and requests of the project, is managed uniformly

Previous article message override Message JS, most operations are to send message JS introduces main JS, and then hang it on the prototype. If there are more such methods, it will appear very bloated. Therefore, it is necessary to manage a separate plugin module. Next, go directly to the code;

// plugn/index.js
// Path com is the alias setting above
import { message } from 'com/resetMessage'
const install = Vue => {
  if (install.installed) return false
  // Add to Vue's prototype chain
  Object.defineProperties(Vue.prototype, {
    $message: { value: message }
  })
  install.installed = true
}

export default install

// main.js

// Import custom plug-ins
import plugin from '@/plugin'
Vue.use(plugin)

// At this point, all components can directly use this$ message. success()

Since message can be introduced into the above code JS, other public methods can also be directly introduced and mounted. For example, a large number of public methods are generally used in the project, which are generally stored in com JS, similar to the following method

// com.js

import moment from 'moment'
/**
 * @description:Use moment to convert any time to standard format
 * @param {The parameter needs formatting time, and} time must be passed
 * @param {Format standard, '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
}

The general usage of methods of common classes in components is import {formatTime} from;;;;; It is cumbersome to use one import at a time. Please refer to the above message JS, which can also be introduced directly

// 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 can be used directly in the component$ com. Formattime() is called, and $com.com is directly in the dom xxx; However, there is no this in other JS files, which can only be used individually after import. Of course, this is rare

There are not only more than a dozen supplementary fields in the regular window, but also a few supplementary fields in the regular window can be filled in and managed in the same way as those in the background

UI frameworks such as element UI, Vue ant or iview can be used directly. The code is as follows:

// com/verify.js
/**
 * Verify that the phone number is correct
 * @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}$/

// The above verification results are consistent with regular 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

// Use in components 
console.log(this.$valid.isTel('1000'))  return false
// Take element UI as an example. There will be rules in the general form, which can be used as follows
 rules: {
        phoneNumber: [
          { required: true, message: 'Mobile phone number cannot be empty', trigger: 'blur,change' },
          { pattern: this.$valid.regTel, message: 'Please enter the correct mobile phone number' }
        ],
        genderCode: [
          { required: true, message: 'Gender cannot be empty', trigger: 'blur,change' }
        ]
    }
// This was not considered in the previous project. This new consideration is added and tested simply
// Data: {return() {isbool: this. $valid. Istel ('1000 ')}} can be used normally. If you have any questions, please communicate

3. axios customization

// 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. Configure the ip of the development environment in development. Baseurl is to obtain the ip of the current web deployment environment. The port remains unchanged and no additional configuration is required
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 {
        // If the token expires
        // message.error(data2.msg, 1, () => {
        //   router.push('/login')
        // })
        return res
      }
    }
  },
  error => {
    message({
      message: error,
      type: 'error' || 'network error',
      duration: 1000,
      onClose: () => {
        Promise.reject(error)
      }
    })
  }
)

export default service

Use: import request from 'comjs/api'

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

Or directly in main JS is introduced and attached to prototype, and this is used globally$ Request() call. It can be seen from the above that both public class methods and verifications can be directly in plugin / index JS, as a unified portal. Of course, http requests are no exception and managed uniformly

4. http request unified management binding

Let's take a look at the directory of personal project definitions

As shown in the above figure, the http request is divided into two parts in the project: static URLs of different modules are stored in constant, and static URLs of corresponding modules are introduced in modules respectively. The request method is defined and used; src/api/index.js reads all js files in the modules directory( Unified batch registration vue global public components The method here is similar, which should be better understood if you read it). It is introduced in batch and displayed in plugin / index JS, any component can be used

Let's take a look at the code of each file

// api/constant/user.js
// Store static url for easy management
export const login = '/UserController/login' // Sign in
export const handleObj = '/ImgObjController/obj' // operation


// api/modules/user.js
// It generally stores public interfaces such as login, logout, personal information or permissions
import request from 'comJs/api'
import * as userUrl from '@/api/constant/user'
// Sign in
export const login = data => {
  return request({ url: userUrl.login, data, method: 'post' })
}

modules contains multiple files, and multi person development does not interfere with each other (I will share the code format of multi person development when I have time tomorrow). I personally feel that it is more convenient to maintain in blocks; Let's take a look at API / index JS file

// api/index.js
// js files are nested under the folder for hump naming conversion
let _result = {}
const camelCaseChange = (str, separator = '/') =>
  str.replace(new RegExp(`${separator}(\\w)`, 'g'), str =>
    str.slice(1).toUpperCase()
  )
// Read http requests in modules
const context = require.context('./modules', true, /\.js$/)
context.keys().map(item => {
  const k = camelCaseChange(item.match(/\.\/(\S*)\.js$/)[1])
  // console.log('Get data ', item. Match (/ \. \ / (\ s *) \ js$/))
  _result[k] = context(item)
})
export default _result

The last step is to add API / index JS file reads that the module object {blog: Module, user: Module} is mounted to Vue Prototype is convenient for global calling

// plugs/index.js
// The following api is equivalent to {blogs:module,user:module}
......
import api from '@/api'
const install = Vue => {
  .....
  Object.defineProperties(Vue.prototype, {
    .....
    $api: { value: api },
  })
  install.installed = true
}

export default install

// At this time, after being mounted to the global, there is no need to Import the request name function again in all components
// Used within the component, it can be called in a chain as follows
this.$api.user.login(params).then(res=>{})
this.$api.blogs.getList(params).then(res=>{})

// async and await can also be used
async Login(){
  const data = await this.$api.user.login(params)
  console.log(data)
}

 

Tags: Vue Vue-cli https

Posted by mherr170 on Fri, 01 Apr 2022 22:58:16 +0300