翻譯原文出處:4 AJAX Patterns For Vue.js Apps
鄙人翻譯略差,別見笑。javascript
若是您閒的沒事幹去兩個Vue.js開發人員:「在Vue應用中使用AJAX的正確姿式是咋樣的?」,您將會獲得三種或更多的不一樣回答。html
Vue.js官方沒有提供實現AJAX的指定方式,而且有許多不一樣的設計模式能夠被有效地使用。每一個都有本身的利弊,應根據要求進行判斷。你甚至能夠同時使用幾個!vue
在本文中,我將向您展現您能夠在Vue應用程序中實現AJAX的四個位置:java
一、根實例
二、組件Components
三、Vuex actions
四、路線導航衛士
五、另加:獎金模式ios
我將解釋每一個方法,舉一個例子,並涵蓋利弊。laravel
在使用Vue框架時,您能夠一開始就從根實例發出全部AJAX請求,即寫好全部的數據請求,並將全部狀態存儲在該實例中。若是任何子組件須要數據,它將會順着props
中傳下來。若是子組件須要刷新數據,則將使用自定義事件來提示根實例請求它。git
new Vue({ data: { message: '' }, methods: { refreshMessage(resource) { this.$http.get('/message').then((response) { this.message = response.data.message; }); } } }) Vue.component('sub-component', { template: '<div>{{ message }}</div>', props: [ 'message' ] methods: { refreshMessage() { this.$emit('refreshMessage'); } } });
優勢github
缺點ajax
隨着您的應用擴展,須要書寫大量的「props」和自定義事件。axios
在使用Vue框架時,組件負責管理本身的AJAX請求和獨立狀態。實際上,您可能須要建立幾個「容器組件」來管理本地組「展現組件」的數據。
例如,filter-list多是一個容器組件包裝filter-input和filter-reset,它們做爲展現組件。filter-list將包含AJAX數據邏輯,而且將管理該組中全部組件的數據,經過props
和事件進行通訊。
請參閱譯文《容器組件和展現組件》原做者:Dan Abramov,能夠更好地深刻了解這種模式。
爲了簡化此架構的實現,您能夠將任何AJAX邏輯抽象爲混合,而後在組件中使用mixin使其成爲AJAX。
let mixin = { methods: { callAJAX(resource) { //... } } }; Vue.component('container-comp', { // No meaningful template, I just manage data for my children template: '<div><presentation-comp :mydata="mydata"></presentation-comp></div>', mixins: [ myMixin ], data() { return { //... } }, }); Vue.component('presentation-comp', { template: '<div>I just show stuff like {{ mydata }}</div>', props: [ 'mydata' ] });
優勢
缺點
在使用Vue框架時,您能夠在Vuex store
中管理狀態和AJAX邏輯; 組件能夠經過dispatch
方法操做來請求新數據(store.dispatch將用於觸發actions動做)。
若是您要使用此模式,最好從您的action
中返回一個promise
,以便對AJAX請求的解析作出反應,例如隱藏加載微調器,從新啓用按鈕等。
store = new Vuex.Store({ state: { message: '' }, mutations: { updateMessage(state, payload) { state.message = payload } }, actions: { refreshMessage(context) { return new Promise((resolve) => { this.$http.get('...').then((response) => { context.commit('updateMessage', response.data.message); resolve(); }); }); } } }); Vue.component('my-component', { template: '<div>{{ message }}</div>', methods: { refreshMessage() { this.$store.dispatch('refeshMessage').then(() => { // do stuff }); } }, computed: { message: { return this.$store.state.message; } } });
本人比較喜歡這種數據請求模式,由於它很好地分離了你的狀態和表現的邏輯。若是你正在使用Vuex,這是要走的路。若是你不使用Vuex,這模式多是一個很好的理由。
優勢
props
和自定義事件。缺點
在使用Vue框架時,您的應用程序分爲多個頁面,當路由更變時,將抓取頁面及其子組件所需的全部數據。
這種方法的主要優勢是它真正簡化了您的UI。若是組件獨立獲取本身的數據,則當組件數據以任意順序填充時,頁面將不可預測地從新呈現。
實現這一點的一個整潔的方法是在您的服務器上爲每一個頁面建立端點,例如/about,/contact與您的應用程序中的路由名稱相匹配。而後,您能夠實現一個通用beforeRouteEnter鉤子,將全部數據屬性合併到頁面組件的數據中:
import axios from 'axios'; router.beforeRouteEnter((to, from, next) => { axios.get(`/api${to.path}`).then(({ data }) => { next(vm => Object.assign(vm.$data, data)) }); })
優勢
缺點
建議在初始頁面加載時使用AJAX來檢索應用程序狀態,由於它須要額外的往返服務器,這將延遲應用程序的渲染。
相反,將初始應用程序狀態注入HTML頁面的內聯腳本中,以便應用程序做爲全局變量在須要時可用。
<html> ... <head> ... <script type="text/javascript"> window.__INITIAL_STATE__ = '{ "data": [ ... ] }'; </script> </head> <body> <div id="app"></div> </body> </html>
而後,AJAX能夠更適合地用於後續數據提取。
若是您有興趣瞭解有關此架構的更多信息,請參閱做者的文章「避免此全面堆棧Vue / Laravel應用程序中的常見反模式」。