浅谈Vue.js应用的四种AJAX请求数据模式


Posted in Javascript onAugust 30, 2017

如果您闲的没事干去两个Vue.js开发人员:“在Vue应用中使用AJAX的正确姿势是咋样的?”,您将会得到三种或更多的不同回答。

Vue.js官方没有提供实现AJAX的指定方式,并且有许多不同的设计模式可以被有效地使用。每个都有自己的利弊,应根据要求进行判断。你甚至可以同时使用几个!

在本文中,我将向您展示您可以在Vue应用程序中实现AJAX的四个位置:

1、根实例
2、组件Components
3、Vuex actions
4、路线导航卫士
5、另加:奖金模式

我将解释每个方法,举一个例子,并涵盖利弊。

一、根实例

在使用Vue框架时,您可以一开始就从根实例发出所有AJAX请求,即写好所有的数据请求,并将所有状态存储在该实例中。如果任何子组件需要数据,它将会顺着props中传下来。如果子组件需要刷新数据,则将使用自定义事件来提示根实例请求它。

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逻辑和数据保存在一个地方。
  • 保持您的组件“独立性”,以便它们可以更加专注于展示。

缺点

  • 随着您的应用扩展,需要书写大量的“props”和自定义事件。

二、组件Components

在使用Vue框架时,组件负责管理自己的AJAX请求和独立状态。实际上,您可能需要创建几个“容器组件”来管理本地组“展示组件”的数据。

例如,filter-list可能是一个容器组件包装filter-input和filter-reset,它们作为展示组件。filter-list将包含AJAX数据逻辑,并且将管理该组中所有组件的数据,通过props和事件进行通信。

为了简化此架构的实现,您可以将任何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' ]
});

优点

  • 保持组件脱钩和可重用。
  • 在任何时候和任何地点都可以获取数据。

缺点

  • 与其他组件或组件组不通信数据。
  • 组件可能会产生很多累赘的职责和重复的功能。

三、Vuex actions

在使用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 和自定义事件。

缺点

  • 增加Vuex的开销。

四、路线导航卫士

在使用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))
 });
})

优点

  • 使UI更可预测。

缺点

  • 总体来说,直到所有数据准备就绪了 ,页面才能呈现。
  • 如果不使用路线,这模式没有太多的帮助。

奖金模式:将第一个AJAX调用的服务器渲染到页面中

建议在初始页面加载时使用AJAX来检索应用程序状态,因为它需要额外的往返服务器,这将延迟应用程序的渲染。

相反,将初始应用程序状态注入HTML页面的内联脚本中,以便应用程序作为全局变量在需要时可用。

<html>
...
<head>
 ...
 <script type="text/javascript">
  window.__INITIAL_STATE__ = '{ "data": [ ... ] }';
 </script>
</head>
<body>
 <div id="app"></div>
</body>
</html>

然后,AJAX可以更适合地用于后续数据提取。

如果您有兴趣了解有关此架构的更多信息,请参阅作者的文章“避免此全面堆栈Vue / Laravel应用程序中的常见反模式”。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JavaScript 编写匿名函数的几种方法
Feb 21 Javascript
分享一道笔试题[有n个直线最多可以把一个平面分成多少个部分]
Oct 12 Javascript
js实现div弹出层的方法
Nov 20 Javascript
javascript实现C语言经典程序题
Nov 29 Javascript
详解jQuery移动页面开发中的ui-grid网格布局使用
Dec 03 Javascript
JS+CSS实现下拉刷新/上拉加载插件
Mar 31 Javascript
Vue.js仿Metronic高级表格(一)静态设计
Apr 17 Javascript
微信小程序学习笔记之登录API与获取用户信息操作图文详解
Mar 29 Javascript
vue使用i18n实现国际化的方法详解
Sep 05 Javascript
javascript操作元素的常见方法小结
Nov 13 Javascript
javascript设计模式 ? 外观模式原理与用法实例分析
Apr 15 Javascript
JavaScript的一些小技巧分享
Jan 06 Javascript
如何理解Vue的render函数的具体用法
Aug 30 #Javascript
微信小程序之发送短信倒计时功能
Aug 30 #Javascript
使用node.js对音视频文件加密的实例代码
Aug 30 #Javascript
hammer.js实现图片手势放大效果
Aug 29 #Javascript
js禁止表单重复提交
Aug 29 #Javascript
View.post() 不靠谱的地方你知道多少
Aug 29 #Javascript
jsTree事件和交互以及插件plugins详解
Aug 29 #Javascript
You might like
php UBB 解析实现代码
2011/11/27 PHP
一个简洁实用的PHP缓存类完整实例
2014/07/26 PHP
浅析php适配器模式(Adapter)
2014/11/25 PHP
PHP利用DWZ.CN服务生成短网址
2019/08/11 PHP
javascript 播放器 控制
2007/01/22 Javascript
用cookies实现的可记忆的样式切换效果代码下载
2007/12/24 Javascript
简单通用的JS滑动门代码
2008/12/19 Javascript
jQuery实现移动 和 渐变特效的点击事件
2015/02/26 Javascript
JQuery显示、隐藏div的几种方法简明总结
2015/04/16 Javascript
由浅入深讲解Javascript继承机制与simple-inheritance源码分析
2015/12/13 Javascript
jQuery延迟执行的实现方法
2016/12/21 Javascript
微信小程序 登录实例详解
2017/01/16 Javascript
jQuery插件Echarts实现的双轴图效果示例【附demo源码下载】
2017/03/04 Javascript
基于vue-ssr服务端渲染入门详解
2018/01/08 Javascript
使用vue打包时vendor文件过大或者是app.js文件很大的问题
2018/06/29 Javascript
30分钟用Node.js构建一个API服务器的步骤详解
2019/05/24 Javascript
浅谈webpack 四个核心概念之Entry
2019/06/12 Javascript
微信小程序设置滚动条过程详解
2019/07/25 Javascript
javascript面向对象程序设计实践常用知识点总结
2019/07/29 Javascript
js实现拖拽元素选择和删除
2020/08/25 Javascript
[01:32:22]DOTA2-DPC中国联赛 正赛 Ehome vs VG BO3 第一场 2月5日
2021/03/11 DOTA
Tornado高并发处理方法实例代码
2018/01/15 Python
python使用Pycharm创建一个Django项目
2018/03/05 Python
python验证码识别教程之利用滴水算法分割图片
2018/06/05 Python
python3实现SMTP发送邮件详细教程
2018/06/19 Python
网友共享的几个面试题关于Java和Unix等方面的
2016/09/08 面试题
介绍一下JNDI的基本概念
2013/07/26 面试题
个人简历自我评价八例
2013/10/31 职场文书
80后职场人的职业生涯规划
2014/03/08 职场文书
单位工作证明范文
2014/09/14 职场文书
中秋联欢会主持词
2015/07/04 职场文书
2016年元旦主持词
2015/07/06 职场文书
工伤调解协议书
2016/03/21 职场文书
个人落户申请书怎么写?
2019/06/28 职场文书
盘点2020年适合农村地区创业的项目
2019/10/16 职场文书
python入门学习关于for else的特殊特性讲解
2021/11/20 Python