乐趣区

Vue开发总结-及-一些最佳实践-已更新

基本开发环境

vue-cli3 创建的项目,vscode 作为代码编写工具
vscode 插件推荐:vscode 插件配置

文章目录

  1. 项目目录结构介绍
  2. UI 框架选择
  3. main,js 处理
  4. axios 请求二次封装

1. 项目目录结构简介

├── public // index.html
├── src // 业务相关
│ ├── assets // 静态文件(css, images)
│ ├── components // 全局组件
│ ├── layouts // 基础样式布局
│ ├── plugin // 样式及工具引入
│ ├── request // 请求配置
│ ├── router // 路由
│ ├── store // 全局状态管理
│ ├── utils // 工具文件
│ ├── app.vue // 入口文件
│ ├── main.js // 主要配置文件
│ └── views // 页面
├── .eslintrc.js // eslint 检查配置
├── .env.release // 测试环境变量
├── .env.pre-build // 预发环境变量
└── vue.config.js // webpack 打包配置

2. UI 框架选择

经框架选择验证对比 element,iview,ant-design-vue
最终选择 ant-design-vue,传送门 https://vue.ant.design/docs/vue/introduce-cn/

优点:
    1. 好看
    1. 文档清晰

      1. 使用方便,示例清晰
    2. bug 少,组件使用顺滑
    3. 性能较好,有单例测试

    3. main.js 处理

    main.js 作为操作入口,很多东西需要引入,代码体积过大,需要进行删减

    import Vue from 'vue'
    import App from './App.vue'
    import router from '@/router'
    import store from '@/store'
    import * as filters from '@/utils/filters'   // 全局过滤器
    import './plugin'    // 引入操作集合
    import './assets/css/index.less'  // 样式集合
    Vue.config.productionTip = false
    
    // 全局过滤器
    Object.keys(filters).forEach(key => {Vue.filter(key, filters[key])
    })
    
    // 非父子组件传值公交车
    Vue.prototype.$bus = new Vue()
    
    new Vue({
      router,
      store,
      render: h => h(App)
    }).$mount('#app')

    这样通过几个集合,来分散引入各个模块

    1. 样式模块 (import ‘./assets/css/index.less’ // 样式集合)
    @import './atom.less';
    @import './global.less';
    @import './reset.less';
    1. 操作模块 (import ‘./plugin/index.js’ // 引入操作集合)
    import './custom.js'
    import './ant-design'
    import './tools'
    
    // tools.js
    import Vue from 'vue'
    import moment from 'moment'
    import 'moment/locale/zh-cn'
    import api from '@/request/api'
    import {isInvalid} from '@/utils/verify'
    // 自定义组件
    moment.locale('zh-cn')
    // 请求接口
    Vue.prototype.$api = api
    // 验证工具
    Vue.prototype.$isInvalid = isInvalid
    Vue.prototype.$moment = moment
    
    
    // ant-design.js 按需引入
    import Vue from 'vue'
    import {
      Layout,
      Spin,
      Button,
      Icon,
      Avatar,
      Select,
      Drawer,
      Menu,
      Form,
      LocaleProvider,
      Dropdown,
      Divider,
      Modal,
      Input,
      Tooltip,
      notification,
      Popover,
      ConfigProvider,
      Pagination,
      Steps,
      Cascader,
      Row,
      Col
    } from 'ant-design-vue'
    import 'ant-design-vue/dist/antd.less'
    Vue.use(Layout)
    Vue.use(Spin)
    Vue.use(Button)
    Vue.use(Icon)
    Vue.use(Avatar)
    Vue.use(Select)
    Vue.use(Popover)
    Vue.use(Form)
    Vue.use(Drawer)
    Vue.use(Menu)
    Vue.use(LocaleProvider)
    Vue.use(Dropdown)
    Vue.use(Modal)
    Vue.use(Input)
    Vue.use(Divider)
    Vue.use(notification)
    Vue.use(Pagination)
    Vue.use(Tooltip)
    Vue.use(ConfigProvider)
    Vue.use(Steps)
    Vue.use(Cascader)
    Vue.use(Row)
    Vue.use(Col)
    

    4. axios 请求二次封装

    axios 不过多介绍,上干货

    1. 新建文件 axios
    2. 请求拦截器
      根据自己业务需求,修改请求头以及超时时间等
    import axios from 'axios'
    axios.interceptors.request.use(
      config => {
        // 判断是否是提交文件,还是常规请求
        if (config.data instanceof FormData) {
          config.headers = {'Content-Type': 'multipart/form-data' // 此处格式自定义}
        } else {config.data = JSON.stringify(config.data)
          config.headers = {
            'Content-Type': 'application/json', // 此处格式自定义
            token: getLocalStorage('token')
          }
        }
        config.withCredentials = true
        config.timeout = 5000    // 超时时间
        return config
      },
      error => {return Promise.reject(error)
      }
    )
    1. 响应拦截器

    根据后台返回数据,做些统一处理

    // 添加响应拦截器
    axios.interceptors.response.use(
      res => {
        let data = res.data
        if (res.statusCode !== 200) {if (data.failureReason === 4011 || data.failureReason === 4012) {console.log('需要重新登录')
          }
        } else {if (data.resultStates === 0) {return data} else {return Promise.reject(data)
          }
        }
      },
      error => {notification['error']({
          message: '提示',
          duration: 2,
          description: '后台报错'
        })
        // 对响应错误做点什么
        return Promise.reject(error)
      }
    )
    1. 封装 get,post,并导出
    export function get (url, params = {}) {return new Promise((resolve, reject) => {
        axios
          .get(url, {params: params})
          .then(response => {if (response.success) {resolve(response.data)
            }
          })
          .catch(err => {reject(err)
          })
      })
    }
    
    /**
     * 封装 post 请求
     * @param url
     * @param data
     * @returns {Promise}
     */
    export function post (url, data = {}) {return new Promise((resolve, reject) => {axios.post(url, data).then(
          response => {if (response.success) {resolve(response.data)
            }
          },
          err => {reject(err)
          }
        )
      })
    }
    1. 重点:新建 api.js 文件

    将后台请求接口全部写在此处,统一管理

    import {get, post} from './axios'
    const api = {reqLogin: p => post('api/user/addFormId', p),
          reqGetInfo: p => post('api/user/addFormId', p)
    }
    export default api
    
    // 将 api 引入到 main.js 中
    Vue.prototype.$api = api
    
    // 这样页面中使用
    this.$api.reqLogin().then(res => {console.log(res)
    })

    是不是非常方便?鼓掌 啪啪啪啪 ……

    web 前端群招人,有梦想的一群小青年 https://www.jianshu.com/p/33eee1c26b8a

    退出移动版