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: '<div>{{ message }}</div>',
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: '<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' ]
})
优点:
-
保持组件分离和可重用。
-
获取所需数据的时间和地点。
缺点:
-
不容易与其他组件或组件组通信数据。
-
组件可能会有太多的职责和重复的功能。
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: '<div>{{ message }}</div>',
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>
<div id="app"></div>
</body>
</html>
然后,AJAX可以更恰当地用于后续数据获取。
英文原文地址:https://vuejsdevelopers.com/2017/08/28/vue-js-ajax-recipes/
更多相关知识,请查阅 web前端学习 !!