Vue進階系列 --- 頁面架構優化

帕尼尼0_0發表於2018-07-08

寫在前面

玩vue已經快一年了,回首第一次遇見vue的時候,還是大二的暑假,一晃已經走完了大三。我們都知道程式設計的學習是分軟功和硬功的。外練筋骨皮,內練一口氣就是這個道理。
那麼什麼是硬功呢?硬功就是Vue語法的掌握,JS語法的掌握等等。
那麼什麼是軟功呢?演算法思想,程式設計思想,架構思想。
思想思想,對咯,軟功就是思和想。一個沒有思想的程式設計師,只知道重複搬磚,不知道造輪子,組裝汽車的程式設計師,我們親切的稱之為‘碼農’。
雖然我現在連碼農都算不上

這篇部落格我將為你介紹vue的架構思想,當然這只是我根據遇到的專案總結的vue架構,這是我發現的一個小三輪,如果你有好的架構也歡迎指教哦。

好了,我們開始聊吧!

以我手擼的一個小專案 高仿餓了麼外賣平臺 為例:線上演示地址

最初的版本

目錄結構

├── src                // 生產目錄
│   ├── api            // axios操作
│   ├── components     // 元件 
│   │		├── common  // 公共元件
│   │		├── admin   // 使用者元件
│   │		└── seller  // 商家元件  		
│   ├── router         // 路由
│   ├── store          // vuex狀態管理器
│	├── App.vue        // 首頁
│   └── main.js        // Webpack 預編譯入口 

程式碼邏輯

很簡單先訪問App.vue,根據路由對映不同元件渲染頁面,每個頁面都有ajax請求

ajax請求長這樣

getUserInfo: function() {
    this.axios.get('user/infor')
    .then(res => {
        if (res.data.status) {
            this.user = res.data.data;
        }
    })
    .catch(error => {
        console.log(error);
    });
},

前端第一次重構

2018 4月21日

Github地址:elm1.0

目錄結構

├── src                // 生產目錄
│   ├── api            // axios操作
│   ├── components     // 元件 
│   ├── router         // 路由
│   ├── store          // vuex狀態管理器
│	├── App.vue        // 首頁
│   └── main.js        // Webpack 預編譯入口

沒錯只是將ajax請求都集中到了api目錄下
api目錄下的index.js檔案

import axios from 'axios';
import store from '../store';

let httpURL = "http://www.xuguobin.club/api/elm/" //這是我伺服器的api介面
let localURL = 'http://localhost/api/elm/';     //這是本地koa2的api介面
axios.defaults.baseURL = localURL;
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';

export default {
    //獲取使用者資訊
    getUser() {
        return axios.get('user/infor');
    },
    //獲取訂單
    getOrders(orderType) {
        return axios.get('user/order?type=' + orderType);
    },
    //提交訂單
    submitOrder(order) {
        return axios.get('user/submit?order=' + order);
    },
    //確認收貨
    confirmOrder(orderId) {
        return axios.get('user/confirm?orderId=' + orderId);
    },
    //提交評價
    submitRating(rating) {
        return axios.get('user/rating?rating=' + rating);
    },
    //使用者登入
    userLogin(user) {
        return axios.post('user/login',`username=${user.username}&password=${user.password}`);
    },
};

這樣子做,很好的將axios請求與vue頁面解耦和了!
現在ajax請求長這樣

getUserInfo: function() {
    this.api.getUser()
    .then(res => {
        if (res.data.status) {
            this.user = res.data.data;
        }
    })
    .catch(error => {
        console.log(error);
    });
},

前端第二次重構

2018 7月8日
Github地址:elm2.0

目錄結構

講道理這次重構的有點過分

├── src                // 生產目錄
│   └── axios           // axios操作
|         ├──base       // axios模板
|         |    ├──base.js     //axios基類
|         |    └──setting.js  //狀態碼
|         └── user
|               ├──cache.js     //請求函式
|               └──config.js    //配置資訊
|
|   ├── base           //vue模板
│   ├── components     // 元件
|   |     ├──common    //公共元件
|   |     └──admin
|   |          ├── ui.vue             // 輸出元件
|   |          ├── component.html     // template
|   |          ├── component.js       // script
|   |          └── component.less     // style
|   |  
│   ├── router         // 路由
│   ├── store          // vuex狀態管理器
│	├── App.vue        // 首頁
│   └── main.js        // Webpack 預編譯入口

第一次的重構雖然已經將axios請求和頁面分離開來了,但是每次請求後都要驗證狀態碼,處理錯誤資訊。

其實這完全沒有必要每個頁面都來一下,這些公共操作可以一起放在axios的基類

import axios from 'axios'
import setting from './setting'

let httpURL = "http://www.xuguobin.club/api/elm/" //這是我伺服器的api介面
let localURL = 'http://localhost/api/elm/';     //這是本地koa2的api介面

axios.defaults.baseURL = httpURL;
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';

export default class AxiosCache {
	constructor() {
		this.__config = {}
		this.__setting = setting;
		this.init();
	}

	init() {
		this.doFlushSetting(CACHE_KEY, )
	}

	doFlushSetting(key, conf) {
		if (!key && typeof key !== 'string') {
			return
		}
		this.__config[key] = conf
	}
	
	/*判斷狀態碼*/
	resultJudge(code) {
		return code
	}
	
	/*傳送請求資料*/
	sendRequest(key, options) {
		let send = this.__config[this.settingKey][key];
		let self = this;
		let baseURL = send.url;
		send.method == 'get'
			? options.data && (send.url += options.data)
			: send.data = options.data
		axios(send)
			.then(function (response) {
				send.url = baseURL;
				if (self.resultJudge(response.data.status)) {
					options.success(response.data.data)
				} else {
					options.fail
						? options.fail(response.data.data)
						: self.handleErrorCase(response.data.status)
				}
			}).catch(function (error) {
				self.handleErrorCase(error)
			})
	}
	
	/*處理錯誤資訊*/
	handleErrorCase(error) {
		if (typeof error == 'Number') {
			console.log(error)
		} else {
			alert(error)
		}
	}
}

而傳送請求的時候,只需要這樣

getUSer: function() {
     this.userCache.getUser({
         success: res => this.user = res
     })
},

是不是很簡潔。這樣做,又進一步的解耦了axios操作,你可以對比我github上的elm1和elm2兩個版本結構,一定會有所收穫。

前端的架構追求就是儘量 完美複用和解耦

前端第三次重構?

未完待續…
你有好的架構也歡迎你fork我的master版本! _

相關文章