catalogue
1,vue.config.js alias configuration and use
2. General method global use (custom plug-in)
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) }