Fork me on Bolg '◡'

vuecli3.0搭建vue项目全过程

最近新写一个项目,记录下新建项目过程及坑处理。供新人查看~

1 搭建脚手架

cnpm install @vue/cli -g
vue create test
2 加入eslint
  1. package.json中加入rules,具体的rules配置从这里找(https://www.cnblogs.com/webhmy/p/14776124.html)适合自己项目的配置项

  2. vue.config.js中配置编译的时候lint代码

lintOnSave: true, // 编译的时候lint代码

3 加入tslint

vue项目中加入tslint

4 添加githooks

因为多人开发,很多人不会carelint的错误,因此在提交前统一自动化执行lint

cnpm install  yorkie --save-dev
cnpm install lint-staged --save-dev

在package.json中配置

 "gitHooks": {
    "pre-commit": "lint-staged"
   },
   "lint-staged": {
    "*.{js,vue}": [
    "vue-cli-service lint",
    "git add"
    ]
   }

5 路由管理 vue-router

npm install vue-router

main.ts

import App from './App.vue'
import router from './router'

Vue.config.productionTip = false

new Vue({
    router,
    render: (h) => h(App)
}).$mount('#app')

route -index.ts

import Vue from 'vue'
import VueRouter, { RouteConfig }  from 'vue-router'

Vue.use(VueRouter)

const asyncFiles = require.context('./routeModules', true, /\.ts$/)
let permissionModules: Array<RouteConfig> = []
asyncFiles.keys().forEach((key) => {
    permissionModules = permissionModules.concat(asyncFiles(key).default)
})


const routes: Array<RouteConfig> = [
    { path: '/', redirect: '/home' },
    ...permissionModules
]

const router = new VueRouter({
    routes
});
export default router;

6 状态管理vuex

npm install vuex

main.ts

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'

Vue.config.productionTip = false

new Vue({
    router,
    store,
    render: (h) => h(App)
}).$mount('#app')

store.ts

import Vue from 'vue'
import Vuex from 'vuex'

const states = {};
const contexts = require.context('./stateModules', true, /\.ts$/);
contexts.keys().forEach(key => {
    let name = key.slice(2, -3);
    states[name] = contexts(key).default || contexts(key);
})

Vue.use(Vuex)

export default new Vuex.Store({
    modules: {
        ...states
    }
})

common.ts

const module = {
    state: () => ({
        count: 1
    }),
    mutations: {
        increment(state) {
            // 这里的 `state` 对象是模块的局部状态
            state.count++
        }
    },
    actions: {
         batchincrement({commit}){
            commit('someMutation') // -> 'foo/someMutation'
            commit('someMutation', null, { root: true }) // -> 'someMutation'
         }
    }
}

export default module

模块中使用

this.$store.state.common.count
this.$store.commit('increment')
this.$store.dispatch('batchincrement')

7 加入iview-design

cnpm install view-design --save

main.ts

import 'view-design/dist/styles/iview.css'  

/**
 * 按需引入iview
 * 常用的按需引入, 不常用的组件里单独引入
 */
import { Button, Table } from 'view-design';
Vue.component('Button', Button);
Vue.component('Table', Table);

借助插件 babel-plugin-import可以实现按需加载组件,减少文件体积。首先安装,并在文件 .babelrc 中配置:

npm install babel-plugin-import --save-dev
// .babelrc
{
  "plugins": [["import", {
    "libraryName": "view-design",
    "libraryDirectory": "src/components"
  }]]
}

8 配置axios

cnpm install axios --save

http index.ts

import axios, { AxiosRequestConfig, AxiosResponse } from 'axios';
import { Message } from 'view-design';
import store from '../store'

const $Message: any = Message;
class Interceptors {
    public instance: any;
    constructor(baseURL?: string) {
        // 创建axios实例
        this.instance = axios.create({
            baseURL: baseURL ? baseURL : '/'
        });
        // 初始化拦截器
        this.initInterceptors(baseURL);
    }

    public initInterceptors(baseURL?: string): void {
        this.instance.defaults.withCredentials = true;
        // 请求拦截器
        this.instance.interceptors.request.use((config: AxiosRequestConfig): AxiosRequestConfig => {
            const token = localStorage.userToken;
            if (token) {
                config.headers.Authorization = token;
            }
            return config;
        }, (error: any) => {
            // 关闭全局loading
            $Message.success(error.desc);
            return Promise.reject(error)
        });

        // 响应拦截器
        this.instance.interceptors.response.use((Response: AxiosResponse<any>) => {
            const { data } = Response;
            const { retcode, desc } = data;
            if ((retcode === '000000' || retcode === undefined) || (Response.config as any).isBolb) {
                return Promise.resolve(Response.data);
            } else if (retcode === '401' || retcode === '200008') {
                $Message.error('无权限,请重新登录!');
            } else {
                // ainote token失效
                if (data === 'Not Authorized') {
                    $Message.error(data);
                    window.open('/')
                } else {
                    if (desc) $Message.error(desc);
                    return Promise.reject(Response.data);
                }
            }
        })
    }

    public getInterceptors() {
        return this.instance;
    }
}
interface ResponseOptions {
    config: object;
    data: {
        retcode: string;
        desc: string;
        [propName: string]: any;
    };
    status: number;
    headers: object;
    [propName: string]: object | number | string | [];
}

interface ApiOptions {
    url: string; // 请求链接
    params?: object; // 请求参数
    method: string; // 请求方法
    headers?: object; // 请求头
    [keyName: string]: any;// 其他参数
}
export class HttpService {
    public axios: any;
    public baseURL: any;
    constructor(baseURL?: string) {
        this.baseURL = baseURL;
        this.axios = new Interceptors(baseURL).getInterceptors();
    }

    /**
     * 通用请求
     * @param {ApiOptions} options 请求参数
     */
    public fetch(options: ApiOptions): Promise<object> {
        return new Promise((resolve, reject) => {
            this.axios(options).then((res: ResponseOptions) => {
                resolve(res);
            }).catch((err: ResponseOptions) => {
                // 请求出错处理todo
                if (err && err.response) {
                    const data = (err.response as any).data || {};
                    switch ((err.response as any).status) {
                        case 401:
                            $Message.error('没有权限,请重新登录');
                            localStorage.clear();
                            break;
                        case 400:
                            $Message.error(data.message || data.desc || '请求出错');
                            break;
                        case 404:
                            $Message.error(data.message || '请求出错');
                            break;
                        case 503:
                            $Message.error(data.message || '服务器异常');
                            break;
                        default:
                            $Message.error(data.message || '服务器异常');
                            break;
                    }
                }
                reject(err);
            })
        })
    }
}

引用

/**
 * 首页接口请求
 */
import { HttpService } from '@/http';
const $HttpService: any = new HttpService('/');

// get 请求
export const getBusinessSceneList = (params) => {
    return $HttpService.fetch({
        url: '/api/business/scene/list',
        method: 'get',
        params
    });
}


// post 请求
export const createBusinessScene = (data) => {
    return $HttpService.fetch({
        url: '/api/business/scene',
        method: 'post',
        data
    });
}
posted @ 2022-07-11 19:50  webhmy  阅读(277)  评论(0编辑  收藏  举报