浅谈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 相关文章推荐
[原创]提供复制本站内容时出现,该文章转自脚本之家等字样的js代码
Mar 27 Javascript
jquery attr 设定src中含有&amp;(宏)符号问题的解决方法
Jul 26 Javascript
jquery实现盒子下拉效果示例代码
Sep 12 Javascript
javascript中数组方法汇总
Jul 07 Javascript
基于JS实现导航条之调用网页助手小精灵的方法
Jun 17 Javascript
jquery submit()不能提交表单的解决方法
Apr 24 jQuery
JS实现动态添加DOM节点和事件的方法示例
Apr 28 Javascript
Angular实现预加载延迟模块的示例
Oct 12 Javascript
Bootstrap框架建立树形菜单(Tree)的实例代码
Oct 30 Javascript
vue弹窗组件的实现示例代码
Sep 10 Javascript
Angular7.2.7路由使用初体验
Mar 01 Javascript
利用百度echarts实现图表功能简单入门示例【附源码下载】
Jun 10 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时间戳使用实例代码
2008/06/07 PHP
PHP性能优化准备篇图解PEAR安装
2011/12/05 PHP
PHP引用返回用法示例
2016/05/28 PHP
jQuery探测位置的提示弹窗(toolTip box)详细解析
2013/11/14 Javascript
jquery+html5烂漫爱心表白动画代码分享
2015/08/24 Javascript
Node.js 文件夹目录结构创建实例代码
2016/07/08 Javascript
JavaScript提高网站性能优化的建议(二)
2016/07/24 Javascript
详解Vue 非父子组件通信方法(非Vuex)
2017/05/24 Javascript
js实现首屏延迟加载实现方法 js实现多屏单张图片延迟加载效果
2017/07/17 Javascript
vue使用drag与drop实现拖拽的示例代码
2017/09/07 Javascript
基于dataset的使用和图片延时加载的实现方法
2017/12/11 Javascript
基于substring()和substr()的使用以及区别(实例讲解)
2017/12/28 Javascript
JavaScript类的继承方法小结【组合继承分析】
2018/07/11 Javascript
微信小程序文章详情页面实现代码
2018/09/10 Javascript
JS Math对象与Math方法实例小结
2019/07/05 Javascript
Layui数据表格 前后端json数据接收的方法
2019/09/19 Javascript
[01:00:53]OG vs IG 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
[01:09:16]DOTA2-DPC中国联赛 正赛 SAG vs Dynasty BO3 第一场 1月25日
2021/03/11 DOTA
python开发中range()函数用法实例分析
2015/11/12 Python
python利用标准库如何获取本地IP示例详解
2017/11/01 Python
从头学Python之编写可执行的.py文件
2017/11/28 Python
Python高级特性切片(Slice)操作详解
2018/09/27 Python
浅谈Python在pycharm中的调试(debug)
2018/11/29 Python
在Python中调用Ping命令,批量IP的方法
2019/01/26 Python
Python 微信爬虫完整实例【单线程与多线程】
2019/07/06 Python
Python3.7基于hashlib和Crypto实现加签验签功能(实例代码)
2019/12/04 Python
PyTorch中torch.tensor与torch.Tensor的区别详解
2020/05/18 Python
CSS3实战第一波 让我们尽情的圆角吧
2010/08/27 HTML / CSS
土耳其国际性时尚购物网站:Modanisa
2018/01/19 全球购物
数据库设计的包括哪两种,请分别进行说明
2016/07/15 面试题
人力资源管理专业应届生求职信
2013/09/28 职场文书
青年文明号口号
2014/06/17 职场文书
岗位说明书怎么写
2014/07/30 职场文书
保险公司岗前培训工作总结
2015/10/24 职场文书
MySQL插入数据与查询数据
2022/03/25 MySQL
新的CSS 伪类函数 :is() 和 :where()示例详解
2022/08/05 HTML / CSS