vue中關(guān)于router,vuex缤剧,axios馅袁,api,utils的一些常用配置

項(xiàng)目介紹

基于vue-cli@2.0的常用配置,代碼切換到vuecli@2.0分支查看荒辕;

后期基于vue-cli@3.0進(jìn)行配置優(yōu)化,具體查看基于vue-cli@3.0搭建管理系統(tǒng)項(xiàng)目并進(jìn)行配置優(yōu)化

基于vue2.0項(xiàng)目開發(fā)中的一些思路

主要包括:

  1. 使用腳手架初始化項(xiàng)目

  2. 將需要用到的工具函數(shù)新建一個(gè)utils文件夾統(tǒng)一管理

  3. 使用router的一些優(yōu)化

  4. 使用Vuex的一些優(yōu)化

  5. 封裝axios及統(tǒng)一管理api

# 在項(xiàng)目目錄和server目錄分別進(jìn)行安裝依賴
git clone git@github.com:crui14994/Vue_Init-Config.git

# 在項(xiàng)目目錄和server目錄分別進(jìn)行安裝依賴
cnpm install

# 運(yùn)行項(xiàng)目
npm run dev

使用腳手架初始化項(xiàng)目

# 安裝cnpm
npm install -g cnpm --registry=https://registry.npm.taobao.org

# 用cnpm 命令安裝vue-cli了汗销,在命令行輸入下面的命令:
cnpm install vue-cli -g

# 用vue init命令來初始化項(xiàng)目
vue init webpack-simple Vue_Init-Config

# 在項(xiàng)目目錄和server目錄分別進(jìn)行安裝依賴
cnpm install

# 運(yùn)行項(xiàng)目
npm run dev

將需要用到的工具函數(shù)新建一個(gè)utils文件夾統(tǒng)一管理

  1. 在根目錄新建一個(gè)utils文件夾

  2. 在文件夾下新建index.js用于幾種管理工具函數(shù)

    export default {
        storage: require('./storage.js').default, //本地存儲(chǔ)localStorage
        formatDate: require('./formatDate.js').default,  //日期格式化
    }
    
  3. 編寫工具函數(shù)導(dǎo)出右index.js導(dǎo)入

      /** formatDate.js
     * 格式化日期
     * @param  {string} str 需要格式化的樣子
     * @param  {String|Date} day 日期對象或者日期字符串
     * @return  {String}
     * @template  formatDate('YYYY年mm月dd日hh小時(shí)ff分鐘ss秒 星期w','2017/1/1 12:13:14') 返回:2017年01月01日12小時(shí)13分鐘14秒 星期日;
     */
     function formatDate (str, day) {
         let d, arr
         let type = Object.prototype.toString.call(day)
         if (type === '[object Date]') {
         d = day
         } else if (type === '[object String' && (arr = day.match(/(\d{4})[-/](\d{1,2})[-/](\d{1,2})(?:\s+(\d{1,2}):(\d{1,2}):(\d{1,2}))?/))) {
         arr = arr.slice(0, arr[4] ? 7 : 4)
         arr[2] = arr[2] - 1
         d = new (Function.prototype.bind.apply(Date, arr))()
         } else {
         return ''
         }
         const obj = {
         'yyyy': d.getFullYear(),
         'yy': ('' + d.getFullYear()).slice(-2),
         'm': d.getMonth() + 1,
         'mm': ('0' + (d.getMonth() + 1)).slice(-2),
         'd': d.getDate(),
         'dd': ('0' + d.getDate()).slice(-2),
         'h': d.getHours(),
         'hh': ('0' + d.getHours()).slice(-2),
         'f': d.getMinutes(),
         'ff': ('0' + d.getMinutes()).slice(-2),
         's': d.getSeconds(),
         'ss': ('0' + d.getSeconds()).slice(-2),
         'w': ['日', '一', '二', '三', '四', '五', '六'][d.getDay()]
         }
         return ('' + str).replace(/([a-z]+)/ig, function (k) {
         return obj[k.toLowerCase()] || ''
         })
     }
    
     export default formatDate
    
      /*storage.js
      *本地存儲(chǔ)localStorage
      */
      class Storage {
          constructor () {
              this.storage = window.localStorage
              this.prefix = 'mytest_' //給key家一個(gè)前綴
          }
    
          set (key, value, fun) {
              if (typeof value !== 'string') {
              try {
                  value = JSON.stringify(value)
              } catch (e) {
              }
              }
              this.storage.setItem(this.prefix + key, value)
              typeof fun === 'function' && fun()
          }
    
          get (key, fun) {
              let value = this.storage.getItem(this.prefix + key)
              try {
              value = JSON.parse(value)
              if (value === null) value = {}
              } catch (e) {
              value = {}
              }
              return typeof fun === 'function' ? fun.call(this, value) : value
          }
    
          remove (key) {
              this.storage.removeItem(this.prefix + key)
          }
    
          cle() {
              this.storage.clear();
          }
      }
    
      export default new Storage()
    
      ```
      
    
  4. 在main.js中把通用方法掛載到Vue原型上在組件中只需使用this即可使用相關(guān)的函數(shù)

    import utils from "./utils/index" //導(dǎo)入工具函數(shù)
    
    // 把通用方法掛載到Vue原型上
    Vue.prototype.$formatDate = utils.formatDate
    Vue.prototype.$storage = utils.storage
    
  5. 在組件中使用

    computed:{
        dateNow(){
            return this.$formatDate('YYYY年mm月dd日hh小時(shí)ff分鐘ss秒 星期w',new Date())
        }
    }
    

使用vue-router的一些優(yōu)化(代碼中只提供思路;沒有具體實(shí)現(xiàn))

  1. 在根目錄新建一個(gè)router文件夾抵窒;安裝vue-router

    cnpm install vue-router --save-dev
    
  2. 在文件夾下新建index.js和route.js兩個(gè)文件

    在index.js中對路由進(jìn)行配置弛针;

    在route.js中對各個(gè)路徑進(jìn)行配置(具體參考源碼)

    import Vue from 'vue';
    import VueRouter from 'vue-router';
    import { routers } from './route';
    // import { Loading } from 'element-ui';
    // import { setTitle } from 'src/assets/js/util';
    
    Vue.use(VueRouter);
    
    const routerConfig = {
    mode: 'history',
    linkActiveClass: 'active',
    routes: routers
    };
    
    const router = new VueRouter(routerConfig);
    
    // let loading;
    // router.beforeEach((to, form, next) => {
    //   loading = Loading.service({
    //     // fullscreen: true,
    //     target: '.content-wrapper',
    //     text: '跳轉(zhuǎn)中...'
    //   });
    
    //   // 設(shè)置window.document.title 的名稱
    //   setTitle(to.meta.title);
    
    //   if (!to.matched.length) {
    //     next({
    //       path: '/error/404',
    //       replace: true
    //     });
    //   } else {
    //     next();
    //   }
    // });
    
    // router.afterEach((to, from) => {
    //   // 解決某些情況下loading無法關(guān)閉的情況
    //   setTimeout(() => {
    //     loading.close();
    //   }, 0)
    // });
    
    
    export default router;
    
    
  3. 在main.js中引入router

    import router from './router/index';
    

使用Vuex的一些優(yōu)化

  1. 在根目錄新建一個(gè)store文件夾;安裝vue-router

    cnpm install  vuex --save
    
  2. 在文件夾下新建index.js和user.js兩個(gè)文件

    在index.js引入我們的vue和vuex

    在user.js中定義user需要使用到的狀態(tài)

    //index.js
    import Vue from 'vue';
    import Vuex from 'vuex';
    import user from './user';
    Vue.use(Vuex);
    
    export default new Vuex.Store({
    modules: {
        user
    }
    });
    
    //user.js
    import utils from "./../utils/index";
    
    const state = {
    //token
    token: utils.storage.get("token")
    };
    const mutations = {
    setToken(state, data) {
        state.token = data;
    }
    };
    export default {
    state,
    mutations
    };
    
  1. 在main.js中引入router

    //sotre
    import store from "./store/index";
    

封裝axios李皇;統(tǒng)一管理api

  1. 在utils下新建axios.js文件

    import axios from 'axios'
    // import { Message } from 'element-ui'
    //sotre
    import store from "./../store/index";
    
    import qs from 'qs' // 序列化請求數(shù)據(jù)削茁,視服務(wù)端的要求
    
    // 創(chuàng)建axios實(shí)例
    const service = axios.create({
        //這里baseurl就是剛開始配置的開發(fā)環(huán)境和線上環(huán)境地址,webpack會(huì)自動(dòng)讀取無需手動(dòng)再改
        baseURL: process.env.BASE_URL, //baseurl
        timeout: 5000 // 請求超時(shí)時(shí)間
    })
    
    // request攔截器
    service.interceptors.request.use(config => {
        // Tip: 1
        // 請求開始的時(shí)候可以結(jié)合 vuex 開啟全屏的 loading 動(dòng)畫
        
        // Tip: 2 
        // 帶上 token , 可以結(jié)合 vuex 或者重 localStorage
        // if (store.getters.token) {
        //     config.headers['X-Token'] = getToken() // 讓每個(gè)請求攜帶token--['X-Token']為自定義key 請根據(jù)實(shí)際情況自行修改
        // } else {
        //     // 重定向到登錄頁面    
        // }
    
        // Tip: 3
        // 根據(jù)請求方法掉房,序列化傳來的參數(shù)茧跋,根據(jù)后端需求是否序列化
        if (config.method.toLocaleLowerCase() === 'post'
            || config.method.toLocaleLowerCase() === 'put'
            || config.method.toLocaleLowerCase() === 'delete') {
    
            config.data = qs.stringify(config.data)
        }
        return config
    }, error => {
        // 請求錯(cuò)誤時(shí)做些事(接口錯(cuò)誤、超時(shí)等)
        // Tip: 4
        // 關(guān)閉loadding
    
        console.log('request:', error);
        return Promise.reject(error) // 在調(diào)用的那邊可以拿到(catch)你想返回的錯(cuò)誤信息
    })
    
    // respone攔截器
    service.interceptors.response.use(
        response => response,
        /**
        * 下面的注釋為通過response自定義code來標(biāo)示請求狀態(tài)卓囚,當(dāng)code返回如下情況為權(quán)限有問題瘾杭,登出并返回到登錄頁
        * 如通過xmlhttprequest 狀態(tài)碼標(biāo)識(shí) 邏輯可寫在下面error中
        */
        //  const res = response.data;
        //     if (res.code !== 20000) {
        //       Message({
        //         message: res.message,
        //         type: 'error',
        //         duration: 5 * 1000
        //       });
        //       // 50008:非法的token; 50012:其他客戶端登錄了;  50014:Token 過期了;
        //       if (res.code === 50008 || res.code === 50012 || res.code === 50014) {
        //         MessageBox.confirm('你已被登出,可以取消繼續(xù)留在該頁面哪亿,或者重新登錄', '確定登出', {
        //           confirmButtonText: '重新登錄',
        //           cancelButtonText: '取消',
        //           type: 'warning'
        //         }).then(() => {
        //           store.dispatch('FedLogOut').then(() => {
        //             location.reload();// 為了重新實(shí)例化vue-router對象 避免bug
        //           });
        //         })
        //       }
        //       return Promise.reject('error');
        //     } else {
        //       return response.data;
        //     }
        error => {
            console.log('err' + error)// for debug
            // Message({
            //     message: error.message,
            //     type: 'error',
            //     duration: 5 * 1000
            // })
            return Promise.reject(error)
        })
    
    export default service
    
    
  2. 在src下新建目錄api和user.js文件

     import service from "./../utils/axios";
    
     export function mock(apiRouter) {
     return service({
         url: "https://easy-mock.com/mock/5c9c8e9ba0feb92705bf12b7/example/"+apiRouter,
         method: "get",
     });
     }
    
  3. 在組件中的使用

    import { mock } from "./api/user";
    
    
    created() {
        mock("mock").then(response => {
        this.reponseData = response.data;
        });
    }
    
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末粥烁,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子蝇棉,更是在濱河造成了極大的恐慌讨阻,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件银萍,死亡現(xiàn)場離奇詭異变勇,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)贴唇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門搀绣,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人戳气,你說我怎么就攤上這事链患。” “怎么了瓶您?”我有些...
    開封第一講書人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵麻捻,是天一觀的道長纲仍。 經(jīng)常有香客問我,道長贸毕,這世上最難降的妖魔是什么郑叠? 我笑而不...
    開封第一講書人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮明棍,結(jié)果婚禮上乡革,老公的妹妹穿的比我還像新娘。我一直安慰自己摊腋,他們只是感情好沸版,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著兴蒸,像睡著了一般视粮。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上橙凳,一...
    開封第一講書人閱讀 51,631評(píng)論 1 305
  • 那天蕾殴,我揣著相機(jī)與錄音,去河邊找鬼岛啸。 笑死区宇,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的值戳。 我是一名探鬼主播,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼炉爆,長吁一口氣:“原來是場噩夢啊……” “哼堕虹!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起芬首,我...
    開封第一講書人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬榮一對情侶失蹤赴捞,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后郁稍,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體赦政,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年耀怜,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了恢着。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡财破,死狀恐怖掰派,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情左痢,我是刑警寧澤靡羡,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布系洛,位于F島的核電站,受9級(jí)特大地震影響略步,放射性物質(zhì)發(fā)生泄漏描扯。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一趟薄、第九天 我趴在偏房一處隱蔽的房頂上張望绽诚。 院中可真熱鬧,春花似錦竟趾、人聲如沸憔购。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽玫鸟。三九已至,卻和暖如春犀勒,著一層夾襖步出監(jiān)牢的瞬間屎飘,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來泰國打工贾费, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留钦购,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓褂萧,卻偏偏與公主長得像押桃,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子导犹,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容