繁花似锦觅安宁,淡云流水度此生。
缘深缘浅随它去,花开花落总归尘。

创建一个VUE项目,正式开发之前要做的配置~

一、使用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

 

posted @ 2021-07-02 17:13  良人非良  阅读(694)  评论(0编辑  收藏  举报