翻译原文出处: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应用程序中的常见反模式”。