一、使用vue-cli脚手架创建一个项目,根据我们开发所需生成固定的文件目录(可配置)。
二、创建好项目之后,还并不能开始真正的开发,我们需要做一些开发前的准备,比如请求的axios封装,多环境的地址配置,解决本能地开发跨域等等,做好准备,在后续开发中会有一劳永逸的感觉哦~。
1、多环境的地址配置
- 根据启动命令Vue会自动加载对应的环境,同时其会读取相对应的环境配置文件。
- 在package.json文件中配置好不同环境的打包运行命令
"scripts": {
"dev": "npm run serve", // 本地运行,环境为development
"serve": "vue-cli-service serve",
"build": "vue-cli-service build", // 打生产包 会去读取 .env.product的配置
"build:test": "vue-cli-service build --mode test", // 打测试包 会去读取 .env.test的配置
"lint": "vue-cli-service lint"
},
- 在项目根目录下以.env开头创建不同环境下的地址配置文件,文件里可以配置相应的地址。
2、跨域处理和一些基本配置
在项目根目录创建vue.config.js文件(脚手架帮我们封装好了一套webpack配置,我们有需要的话叠加就好了,不用再写一遍基本配置)
(1)本地开发跨域:通过proxy代理真实请求的地址
(2)配置文件快捷路径: 通过alias配置快捷
(3)配置全局样式:需要先下载对应的插件,这里用了less,需要先下载less, less-loader,style-resources-loader,vue-cli-plugin-style-resources-loader这四个插件(少下载都会导致样式无效哦~)
const path = require(‘path‘) const devServerConfig = { proxy: { ‘/my-web‘: { target: process.env.url, // 需要代理的后端地址 changeOrigin: true, secure: false, }, }, port: 8080, } module.exports = { devServer: devServerConfig, pluginOptions: { ‘style-resources-loader‘: { preProcessor: ‘less‘, patterns: [path.resolve(__dirname, ‘./src/assets/styles/base.less‘)], // 可以设置多个 }, }, // 设置快捷路径 chainWebpack: config => { config.resolve.alias .set(‘@api‘, path.resolve(__dirname, ‘./src/api‘)) .set(‘@assets‘, path.resolve(__dirname, ‘./src/assets‘)) .set(‘@components‘, path.resolve(__dirname, ‘./src/components‘)) .set(‘@views‘, path.resolve(__dirname, ‘./src/views‘)) } }
3、axios的封装
在src目录下创建一个api文件夹(名字可以自定义)
// httpError.js 公共错误提示的js const ErrorMap = new Map([ [400, ‘请求错误‘], [401, ‘未授权,请重新登录‘], [403, ‘拒绝访问‘], [404, ‘请求错误,未找到该资源‘], [405, ‘请求方法未允许‘], [408, ‘请求超时‘], [500, ‘服务器端出错‘], [501, ‘网络未实现‘], [502, ‘网络错误‘], [503, ‘服务不可用‘], [504, ‘网络超时‘], [505, ‘http版本不支持该请求‘], ]) export const getErrorMessage = (status) => { if (ErrorMap.has(status)) { return ErrorMap.get(status) } else { return ‘连接错误,请联系管理员‘ } }
(1)使用一:将每个请求都写成独立的请求函数,组件中引用调用。
优点:多个地方调用,如果接口有变动,直接改这个函数即可(比如请求方法、接口路径等发声改变)
// http.js import axios from ‘axios‘ import Vue from ‘vue‘ import router from ‘@/router‘ import { getErrorMessage } from ‘@assets/js/httpError‘ const Axios = axios.create({ baseURL: ‘/my-web‘, timeout: 5000, }) // 添加请求拦截器 Axios.interceptors.request.use(req => { let token = localStorage.getItem(‘_a‘) token && (req.headers.Authorization = token) return req }, err => { return Promise.reject(err) }) // 响应拦截器 Axios.interceptors.response.use(res => { if (res.data.code === ‘0‘) { return { data: res.data.data, response: res, } } else { return Vue.prototype.$message.error(res.data.message) } }, err => { let status if (err && err.response) { status = err.response.status err.message = getErrorMessage(status) Vue.prototype.$message.error(err.message) } if (status === 401) { router.replace({ path: ‘/login‘, query: { redirect: router.currentRoute.fullPath } }) } return Promise.reject(err) }) export default Axios
// home.js import http from ‘./http‘ // 获取主页信息 export const getHomeInfo = () => http({ url: ‘/home/info‘, method: ‘get‘, }) // xxx功能接口 export const xxxx = () => http({ url: ‘/home/xxx‘, method: ‘get‘, })
...
// vue文件中调用请求函数 <script> import { getHomeInfo } from ‘@api/home‘ export default { mounted() { this.getData() }, methods: {
async getData () { let { data } = await getHomeInfo() } }, }
</script>
(2)使用方法二:在第一种axios封装的基础上,再针对不同类型请求封装,api文件只维护请求接口的url
优点:需要改变请求路径时,只需改动url的配置文件
// http.js import axios from ‘axios‘ import Vue from ‘vue‘ import router from ‘@/router‘ import { getErrorMessage } from ‘@assets/js/httpError‘ const Axios = axios.create({ baseURL: ‘/my-web‘, timeout: 5000, }) // 添加请求拦截器 Axios.interceptors.request.use(req => { let token = localStorage.getItem(‘_a‘) token && (req.headers.Authorization = token) return req }, err => { return Promise.reject(err) }) // 响应拦截器 Axios.interceptors.response.use(res => { if (res.data.code === ‘0‘) { return { data: res.data.data, response: res, } } else { return Vue.prototype.$message.error(res.data.message) } }, err => { let status if (err && err.response) { status = err.response.status err.message = getErrorMessage(status) Vue.prototype.$message.error(err.message) } if (status === 401) { router.replace({ path: ‘/login‘, query: { redirect: router.currentRoute.fullPath } }) } return Promise.reject(err) }) // 封装的请求函数 function request(url, methods, params, option = {}) { let headers if (option.headers) headers = option.headers return Axios({ url, methods, headers, data: [‘POST‘, ‘PUT‘].includes(methods) ? params : null, params: [‘GET‘, ‘DELETE‘].includes(methods) ? params : null, }) } // 暴露给vue文件使用的请求方法 export const getData = (url, params, option) => { return request(url, ‘GET‘, params, option) } export const postData = (url, params, option) => { return request(url, ‘POST‘, params, option) } export const putData = (url, params, option) => { return request(url, ‘PUT‘, params, option) } export const deleteData = (url, params, option) => { return request(url, ‘DELETE‘, params, option) }
// url.js export default { login: ‘/login‘, homeInfo: ‘/home/info‘, ... }
有两张方式去调用请求:
- 在vue文件中直接引入url
<script> import url from ‘@api/url‘ import { getData } from ‘@api/http‘ export default { mounted() { this.getHomeInfo() }, methods: { async getHomeInfo () { // url.homeInfo:接口地址 let { data } = await getData(url.homeInfo) console.log(24, data) } }, } </script>
- 在Vue原型上挂在url,vue文件中直接获取到this.$url.xxx接口
// main.js文件中加入以下代码,将url挂在到vue实例上 import url from ‘./api/url‘ Vue.prototype.$url = url // vue 文件中 <script> import { getData } from ‘@api/http‘ export default { mounted() { this.getHomeInfo() }, methods: { async getHomeInfo () { // 直接通过vue拿到url let { data } = await getData(this.$url.homeInfo) console.log(24, data) } }, } </script>
看个人习惯选择要那种~
3、路由的处理
- 可以将路由按照页面结构拆分成多个文件引入,便于维护(建议)
- 也可以直接在页面中写完全部路由
import Vue from ‘vue‘ import VueRouter from ‘vue-router‘ import Home from ‘../views/Home.vue‘ Vue.use(VueRouter) // 解决重复点击相同路由控制台报错问题 const VueRouterPush =VueRouter.prototype.push VueRouter.prototype.push = function push (to) { return VueRouterPush.call(this, to).catch(err => err) } const routes = [ { path: ‘/‘, name: ‘Home‘, component: Home }, ] router.beforeEach((to, from, next) => { // 进入每个路由前会先进这个函数,一般对身份的验证,路由页面的验证可以放在这里 }) const router = new VueRouter({ mode: ‘history‘, base: process.env.BASE_URL, routes }) export default router
4、配置eslint