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">
- Windows.__INITIAL_STATE__ = '{"data": [ ... ] }';
- </script>
- </head>
- <body>
- <div id="app"></div>
- </body>
- </HTML>
然后, Ajax 可以更恰当地用于后续数据获取.
来源: http://www.css88.com/web/vue-js/12286.html