Vue没有提供实现AJAX的正式方法,而且有许多不同的设计模式可以有效地使用。每种方法都有其优缺点,应该根据需求进行判断。您甚至可以同时使用多个!
在本文中,我将向您展示在Vue应用程序中实现AJAX的四个地方:
根实例
组件
立即学习“前端免费学习笔记(深入)”;
Vuex行动
路线导航警卫
我将解释每种方法,给出一个例子,并讨论其优缺点。
1、根实例
使用这种体系结构,您可以从根实例发出所有AJAX请求,并将所有状态存储在根实例中。如果任何子组件需要数据,它将作为辅助。如果子组件需要刷新数据,将使用自定义事件提示根实例请求它。
例子:
new Vue({ data: { message: '' }, methods: { refreshMessage(resource) { this.$http.get('/message').then((response) { this.message = response.data.message; }); } }})Vue.component('sub-component', { template: '<p>{{ message }}</p>', props: [ 'message' ] methods: { refreshMessage() { this.$emit('refreshMessage'); } }});
优点:
将所有AJAX逻辑和数据保存在一个地方。
保持组件“dumb”,这样它们就可以专注于表示。
缺点:
随着应用程序的扩展,需要大量的道具和定制事件。
2、组件
使用这种体系结构,组件负责独立地管理它们自己的AJAX请求和状态。在实践中,您可能希望创建几个“容器”组件,这些组件为它们自己的本地“表示”组件组管理数据。
例如,filter-list可能是包装filter-input和filter-reset的容器组件,它们充当表示组件。filter-list将包含AJAX逻辑,并将管理该组中所有组件的数据,通过道具和事件进行通信。
为了使这个体系结构的实现更容易,您可以将任何AJAX逻辑抽象到mixin中,然后使用组件中的mixin使其启用AJAX。
let mixin = { methods: { callAJAX(resource) { ... } }}Vue.component('container-comp', { // No meaningful template, I just manage data for my children template: '<p><presentation-comp :mydata="mydata"></presentation-comp></p>', mixins: [ myMixin ], data() { return { ... } },})Vue.component('presentation-comp', { template: <p>I just show stuff like {{ mydata }}</p>, props: [ 'mydata' ]})
优点:
保持组件分离和可重用。
获取所需数据的时间和地点。
缺点:
不容易与其他组件或组件组通信数据。
组件可能会有太多的职责和重复的功能。
3、Vuex行动
使用这种体系结构,您可以在Vuex存储中管理状态逻辑和AJAX逻辑。组件可以通过分派操作请求新数据。
如果您实现了这种模式,那么最好在操作中返回一个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: '<p>{{ message }}</p>', methods: { refreshMessage() { this.$store.dispatch('refeshMessage').then(() => { // do stuff }); } }, computed: { message: { return this.$store.state.message; } }});
我喜欢这种架构,因为它很好地解耦了状态和表示逻辑。如果你正在使用Vuex,这是一个方法。如果你不使用Vuex,这可能是一个足够好的理由。
优点:
根组件体系结构的所有优点,不需要道具和自定义事件。
缺点:
增加了Vuex的开销
4、路线导航警卫
使用这种架构,您的应用程序将被分割为多个页面,当路由更改时,将获取页面及其子组件所需的所有数据。
这种方法的主要优点是它确实简化了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)) });})
优点:
使UI更加可预测。
缺点:
整体上比较慢,因为页面在所有数据都准备好之前无法呈现。
如果您不使用路由,也没有多大帮助。
附加模式:服务器—在页面中呈现第一个AJAX调用
不建议在初始页面加载时使用AJAX检索应用程序状态,因为它需要额外的到服务器的往返,这会延迟应用程序的呈现。
相反,将初始应用程序状态注入HTML页面头部的内联脚本中,以便在需要时将其作为全局变量提供给应用程序。
<html>...<head> ... <script type="text/javascript"> window.__INITIAL_STATE__ = '{ "data": [ ... ] }'; </script></head><body> <p id="app"></p></body></html>
然后,AJAX可以更恰当地用于后续数据获取。
更多编程相关知识,请访问:编程入门!!