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
    });
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章