Vue项目使用总结分享

一. 项目目录结构

|-- build                       项目构建(webpack相关代码)
|   |-- build.js                生成环境构建代码
|   |-- check_version.js        检查node、npm等版本
|   |-- utils.js                构建工具
|   |-- vue-loader.conf.js      webpack loader配置
|   |-- webpack.base.conf.js    webpack基础配置
|   |-- webpack.dev.conf.js     webpack开发环境配置,构建开发本地服务器
|   |-- webpack.prod.conf.js    webpack生成环境配置
|-- config                      项目开发环境配置
|   |-- dev.env.js              开发环境变量
|   |-- index.js                项目一些配置变量
|   |-- prod.env.js             生成环境变量
|-- src                         源码目录
|   |-- components              vue公共组件
|   |-- router                  vue路由管理
|   |-- App.vue                 页面入口文件
|   |-- main.js                 程序入口文件,加载各种公共组件
|-- static                      统一放置项目所需的静态资源文件
|-- .gitignore                  git上传需要忽略的文件格式
|-- README.md                   项目说明
|-- index.html                  入口文件
|-- package.json                项目基本信息,包依赖信息等

所有业务代码统一放在src目录下,对于项目层级的划分可以:

  1. 抽离所有的api接口统一管理,每个模块的api也单独管理
  2. 所有单页早src下新建views管理所有页面
  3. 项目使用的所有公共方法,以及相关的工具,统一在src下新建utils文件夹管理
  4. 项目所需要用到的字体统一在src下新建fonts管理
  5. 项目所需要的主题统一在src下新建theme管理
  6. 公共css文件在src下新建style管理

二、代码基本规范

<script>
export default {
    //组件名称,可以不写
    name: 'name',
    //引入组件,需要引入子组件时使用
    components: {},
    //接受父组件传递的数据
    props: {},
    //过滤器
    filter: {},
    //混入
    mixins: [],
    //组件实例数据
    data() {
        return {
        }
    },
    //计算属性,可以不写
    computed: {},
    //监听属性变化 执行异步或者是开销比较大的操作
    watch: {},
    //渲染函数jsx
    render(h) => {},
    //页面初始化方法,在模板渲染成html前调用,即通常初始化某些属性值,然后再渲染成视图
    created(){},
    //页面初始化方法,在模板渲染成html前调用,即通常初始化某些属性值,然后再渲染成视图
    mounted() {},
    //实例方法集合
    methods: {},
}
</script>
生命周期钩子 组件状态
beforeCreate 实例初始化之后,this指向创建的实例,不能访问到data、computed、watch、methods上的方法和数据
created 实例创建完成,可访问data、computed、watch、methods上的方法和数据,未挂载到DOM,不能访问到$el属性,$ref属性内容为空数组
beforeMount 在挂载开始之前被调用,beforeMount之前,会找到对应的template,并编译成render函数
mounted 实例挂载到DOM上,此时可以通过DOM API获取到DOM节点,$ref属性可以访问
beforeupdate 响应式数据更新时调用,发生在虚拟DOM打补丁之前
updated 虚拟 DOM 重新渲染和打补丁之后调用,组件DOM已经更新,可执行依赖于DOM的操作
beforeDestroy 实例销毁之前调用。这一步,实例仍然完全可用,this仍能获取到实例
destroyed 实例销毁后调用,调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁

beforeCreate 创建之前:已经完成了 初始化事件和生命周期
created 创建完成:已经完成了 初始化注册和响应
beforeMount 挂载之前:已经完成了模板渲染
mounted :挂载之后:已完成HTML虚拟化,创建了el节点 可以操作DOM了
beforeDestroy :摧毁之前:整个vue都处在实时监控空渲染和更新
destroyed: 已摧毁,已经摧毁了观察者,子元素和事件监听

三、组件设计原则

  1. 容错处理, 这个要做好, 极端场景要考虑到, 不能我传错了一个参数你就原地爆炸;
  2. 缺省值(默认值)要有, 一般把应用较多的设为缺省值;
  3. 颗粒化, 把组件拆分出来;
  4. 一切皆可配置, 如有必要, 组件里面使用中文标点符号, 还是英文的标点符号, 都要考虑到;
  5. 场景化, 如一个dialog弹出, 还需要根据不同的状态封装成success, waring等;
  6. 有详细的文档/注释和变更历史, 能查到来龙去脉, 新版本加了什么功能是因为什么;
  7. 组件名称, 参数prop, emit, 名称设计要通俗易懂, 最好能做到代码即注释这种程度;
  8. 可拓展性, 前期可能不需要这个功能, 但是后期可能会用上, 要预留什么, 要注意什么, 心里要有逼数;
  9. 规范化,我这个input组件, 叫on-change, 我另外一个select组件叫change, 信不信老子捶死你;

四、请求Axios

import axios from 'axios';
import { Message } from 'element-ui';

// 请求Url
let proEnv = require("@/config/prod.env");
let devEnv = require("@/config/dev.env");
//dev.env.js代码
//module.export = {
//    NODE_ENV: '"development"',
//    API_ROOT: 'http://localhost',
//}

const env = process.env.NODE_ENV;
let target = "";
if(env === 'production'){
    target = proEnv.API_ROOT;
} else if(env === 'dev'){
    target = devEnv.API_ROOT;
}

// 设定超时
axios.default.timeout = 10000;

// 请求拦截器 对request
axios.interceptors.request.use(config => {
    // 设置请求后台接口路径
    config.baseURL = target;
    // 发起请求之前判断假设token存在localStorage中
    // 如果token存在,在每次得请求header上带上token
    // token存在,但是token已经过期,在响应拦截器中对返回得状态进行判断
    const token = window.localStorage.token;
    token && (config.headers = {
        'Authorization': token,
        'Content-Type': 'application/json',
        'Cache-Control': 'no-cache',
    });
    return config;
}, err => {
    return Promise.reject(err);
});


// 请求拦截器 对response
axios.interceptors.response.use(response => {
    if(response.status === 200){
        return Promise.resolve(response);
    } else {
        return Promise.reject(response);
    }
}, err => {
    if(err.response){
        let status = err.response.status;
        switch(status) {
            // 401未登陆则跳转到登陆页面,并且携带当前页面得path 
            // 登陆成功后 返回当前页面
            case 401:
                router.replace({
                    path: '/login',
                    query: {
                         redirect: router.currentRouter.fullPath
                    }
                });
            break;
            // 403 token过期,对用户进行提示
            case 403:
                Message({
                    message : '登陆过期,请重新登陆',
                    type: 'error',
                    duration: 2000
                })
            break;
            case 404:
                Message({
                    message: '网络请求不存在',
                    type: 'error',
                    duration: 2000
                })
            break;
            //其他错误统一抛出,如果要对其中得返回码进行其他操作,在视情况在加case 进行操作
            default:
                Message({
                    message: error.response.message,
                    type: 'error',
                    durantion: 2000
                })
        }
    }
    return Promise.reject(err);
})

/**
 * GET
 * @param url
 * @param data
 * @return { Promise }
 */
export function get(url, params = {}) {
    return new Promise((resolve, reject) => {
        axios.get(url, {
            params: params
        })
        .then((res) => {
            resolve(res.data)
        })
        .catch((err) => {
            reject(err)
        })
    })
}

/**
* POST
* @param url
* @param data
* @return { Promise }
* 
*/
export function post(url, params = {}) {
    return new Promise((resolve, reject) => {
        axios.post(url, params)
        .then((res) => {
            resolve(res.data)
        })
        .catch((err) => {
            reject(err)
        })
    })
}

/**
* PATCH
* @param url
* @param data
* @returns { Promise }
* 
*/
export function patch(url, params = {}) {
    return new Promise((resolve, reject) => {
        axios.patch(url, params)
        .then((res) => {
            resolve(res.data)
        })
        .catch((err) => {
            reject(err)
        })
    })
}

/**
* put
* @param url
* @param data
* @returns { Promise }
* 
*/
export function put(url, params = {}) {
    return new Promise((resolve, reject) => {
        axios.put(url, params)
        .then((res) => {
            resolve(res.data)
        })
        .catch((err) => {
            reject(err)
        })
    })
}

/**
* deltet
* @param url
* @param data
* @returns { Promise }
* 
*/
export function delete(url, params = {}) {
    return new Promise((resolve, reject) => {
        axios.delete(url, params)
        .then((res) => {
            resolve(res.data)
        })
        .catch((err) => {
            reject(err)
        })
    })
}

 

参考资料


©️2020 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值