如何理解Vue前后端数据交互与显示


Posted in Vue.js onMay 10, 2021

一、技术概述

将后端所计算的数据呈现在前端页面的相应位置并根据用户点击操作改变相应的数据和界面,再传值给后端。该技术是Web开发必备,是前后端交互的纽带。难点在于获取后端数据并且防止数据联动。

二、技术详述

1. 从接口获取后端数据

(1) 仔细查看后端所传数据的类型。主要是区分数组和单个数据。查看后端的请求方式,区分post或者get。

(2) 首先,在data中return一个xxxData:[]数组或一个变量xxxData:<类型>来接收后端传来的数据。

(3) 在方法中定义一个请求函数,比如我们这里函数名定义为update。请求函数中最主要的为请求语句通过api获取后端数据。

如何理解Vue前后端数据交互与显示

{params:this.xxx}中填写的是所携带的参数。

当get时,params作为一个关键字,总领所有携带参数的传递,例如传递参数的名字为id,值为data中已声明的值myId,那么在get请求语句中可以写成:

update(){
      this.$http.get(baseURL+`api/条件`,{params:{id:this.myId}}).then(function(res){
        this.memberData = res.body;
     });
},

当post时,可以不加params关键字。直接写成:

update(){
      this.$http.get(baseURL+`api/条件`,{id:this.myId}).then(function(res){
        this.memberData = res.body;
     });
},

返回的参数在then之后的匿名函数里。

这里baseURL是项目的路径,如果项目部署在服务器上面一般格式为www.XXX.com/项目名,之后的api是后端封装的api接口。

api/条件这个条件中往往会出现前端定义的变量,在传值时若将其直接写入便会成为接口地址的一部分。要想让其代表它内在的值,则使用${}取值。例如:

console.info(`大家好,我叫${name},今年${age}岁了`)
// 等价于
console.info('大家好,我叫' + name + ',今年' + age + '岁了')

(4) 此时这个请求操作是没有调用,是默认执行的,所以要在mounted里面实时执行。

整体代码呈现例如:

<script>
    export default {
        data(){
            memberData[],//等待存放后端数据的接收数组
        },
        mounted(){
            this.update();//在html加载完成后进行,相当于在页面上同步显示后端数据
        },
        methods:{
            update(){
                  this.$http.get(`/api/project/${this.$store.state.project.id}`, {
                      project_id:this.$store.state.project.id,
                    }).then(doc => {
                          var code = doc.data.status;
                          var msg = doc.data.msg;
                      if (code == 0){//请求成功,可以根据不同的状态码返回值做出相应的动作
                        this.memberData = doc.data.data.member//本数组存入后端数
                      }			
                  })
            },
        },
    };
</script>

在以上例子中,doc接收返回的参数,以doc.data开头获取。其中后端传送的数据又具有data结构,所以又再次.data,深入再次获取其中的member数据。

注意:在我刚开始学习获取数据的时候,将请求URL错用单引号(')引用。这里是使用反单引号(`)。

在使用vue编程中,组件里面绑定的事件如果有传入事件名称字符串/字符串参数,这个时候光用单双引号会出现string is undefined,这个时候我们就需要用到反单引号。

对比后端项目文档:

如何理解Vue前后端数据交互与显示

如何理解Vue前后端数据交互与显示

2. 前端向后端传值的交互

前端向后端传值和之前提到的携带参数的概念一样,是同样的方法。但是不同点在于这是以前端向后端传参为主的交互,所以携带参数很多的情况下,容易造成代码过长,阅读书写繁琐的问题。这就可以建立中间变量结构,统一传值,这时携带参数只需要填写一个。例如:

var obj = {//将所有携带参数放在一起
    project_id:this.$store.state.project.id,
    id:this.id,
    finish:checked,
    name:this.flowName
}
this.$http.post(`/api/project/${this.$store.state.project.id}/task/update`, obj)//直接传值的合集
    .then(doc => {
            var code = doc.data.status;
            var msg = doc.data.msg;
			if (code == 0){
				this.update()//更新后端数据后自动刷新前端,随着更改外观
			}
    		else{
					this.$alert(msg,'false')
			}
	});

3. 显示获取到的数据

相对于获取数据而言,显示数据就显得简单许多了。

首先后端传来的数据肯定是很多层结构或者是一个集合,所以在用一个大数组接受后台数据的同时,在data return中要声明几个自己需要显示的具体的变量,后台数据要分清楚存入前端变量中才能被前端所使用。将数组中的数据再次分离。例如:

getTaskData:function(){
	this.$http.get(`/api/project/${this.$store.state.project.id}/task/info?						id=${this.messageId}`,//根据后端提供的URL,其中?后跟参数要注意写法${}
        {params:{project_id:this.$store.state.project.id,task_id:this.messageId}})
        .then(doc=>{
            if(doc.data.data){//当有数据传来时才可获取。若是为空,则在传来的data下再次.xxx寻找结构中的子变量则会出错。
                this.taskData=doc.data.data;//所谓的整体大数组,包含了所有传来的数据
                this.defaultChecked=this.taskData.finish;//细分传来的数据结构并放入已声明过的变量
                this.taskRemarks=this.taskData.remarks;   
            }                  
            else
                this.taskData=null;
            }).catch(err=>{//处理错误的写法
           		this.$alert("未知错误", "false");  //服务器还没搭起来
  		 })                
},

在第一次接触接收数据时我就有个疑问,一直不知道类似于这样的“子数据”怎么获取:

如何理解Vue前后端数据交互与显示

获得了具体的数据之后,想要显示在html里。一般来说,将变量或者其代表的信息显示在网页上大多是插入在html标签中,变量作为属性值就要使用v-bind来实现。v-bind就是用于绑定数据和元素属性的。例如:

<a href="myHome.com" rel="external nofollow" >OK</a>

想要实时更新href属性值则需要绑定自定义的变量上去,而在双引号中的变量都会被当作字符串。这时我们需要用v-bind实现。绑定之后,对应的值要去vue的数据里面找。当我们在控制台改变url时,对应也会变化。相同的,我们还可以绑定图片src属性、class属性。

//这里url是在data中return的自定义变量,存储链接字符串
//url:"MyHome.com",
<a v-bind:href="url" rel="external nofollow"  rel="external nofollow" >OK</a>
//简写为(我简记为在需要变量名作为属性的时候,在属性前加冒号)
<a :href="url" rel="external nofollow"  rel="external nofollow" >OK</a>

我在刚开始想实时变化页面显示数据的时候,即根据后端传来的数据更改页面显示标签属性的时候,错误使用dom控制元素显示。因为之前没有接触过Vue,所以我对于界面元素的更改的意识停留在 “document.getElementById('xxx').<属性>=xxx” 的阶段,这样做起来代码很繁琐,效率也低,增加了代码的耦合性。

4. 防止数据联动

在任务面板的模块,为要根据不同的点击显示不同的任务详情就要传递每个任务唯一的id。而在显示详情后有更改信息的功能,在这随意的更改可能会影响其他任务的信息,造成信息错乱。主要原因是刚开始我们监听了所有组件的更改,例如这段代码在更改任务紧急程度的时候调用:

onFlowPri(pri){
			this.taskpriority = pri
			this.$http
         .post(`/api/project/${this.$store.state.project.id}/task/update`, {//当紧急程度一变化的时候就向后端传输数据,仅一项变化,更改的却是全部数据,这时传输其他旧数据就会遇到问题
				project_id:this.$store.state.project.id,
				id:this.id,
				remarks:this.flowMarks,
				name:this.flowName,
				finish:this.finish,
				priority:pri,
			})
         .then(doc => {
            var code = doc.data.status;
            var msg = doc.data.msg;
				if (code == 0){
					this.update()
				}else{
					this.$alert(msg,'false')
				}
         });
},

而在用户是否保存不得而知的时候太早的传输更改数据,积极的监听会造成错误。增加了代码的繁琐程度。尤其是和用户交互的数据足够多的时,会造成混乱。好的方式应在用户选择确认保存后再将整体表格中要求填写的数据移交给后端,这样一次性的传输保证了数据的准确性。

如何理解Vue前后端数据交互与显示

如何理解Vue前后端数据交互与显示

三、技术问题

1. 界面自动刷新

问题描述:在用户改变某些功能性质时,界面所表现出来的数据或者组件不能实时变化,即需要用户手动刷新整个页面。

解决方法:首先界面的加载是要靠mounted方法中定义的获取后台数据的方法(在这里一般将该方法命名为update)显示。作为钩子函数,它向后端请求,拿回数据,配合路由器钩子做一些事情。主要是依靠api拿数据 ,在mounted和改变的时候直接调用update就可以。即在用户点击事件发生之后在相应事件的位置调用update重新从后台获取新数据。

如何理解Vue前后端数据交互与显示

2. 获取数据数组出错

问题描述:后端传入前端的是一个数组,前端接收到自己的数组之后,二次使用push新的元素进入时报错。

如何理解Vue前后端数据交互与显示

问题表面看起来很简单找出原因,是因为我所push的数组不被承认为数组。但是我反复检查过确实在data中接收数据类型被声明为数组。这个报错也找不到具体的位置,它报错全是从runtime运行时缓存读的,一个源文件都没映射到。是个玄学问题。

解决方法:选定项目。就是这么简单。我们的产品是要通过选择项目来向后台传送数据的,即项目ID。所以在报错信息不明确的时候要尝试发现有无信息没读到的问题。

3. 传值显示值(针对时间)

问题描述:前后端数据交互中比较绕的问题就是时间作为DateTime类型传值的时候的数据类型转换。以及在使用时间选择器的时候将组件中的时间显示为所传值的时间。

如何理解Vue前后端数据交互与显示

如图设置时间位置所显示的时间是错误的,而控制台输出的是从后台传入的正确时间。即时间无法实时在时间选择框中显示。

从设置时间等时间选择框中更改时间并把其传入到后端时,会有类型不匹配的问题。即String和DateTime的转换。

解决方法:在时间选择器的属性中加入:value属性并以moment约束要显示的时间变量例如:

:value="[moment(taskDetails.t_begin), moment(taskDetails.t_end)]"

时间格式化组件moment的使用:需要在script中导入组件,并在methods中声明moment。

<script>import moment from 'moment'</script>

若要将时间数据传回后端的话需要将String类型的数据转换,即需要声明定义一个toDateTime函数:

function toDateTime(time) {
	var date = new Date(time);
	var Y = date.getFullYear() + '-';
	var M = (date.getMonth()+1 < 10 ? '0'+(date.getMonth()+1) : date.getMonth()+1) + '-';
	var D = (date.getDate() < 10 ? '0'+date.getDate() : date.getDate()) + ' ';
	var h = (date.getHours() < 10 ? '0'+date.getHours() : date.getHours()) + ':';
	var m = (date.getMinutes() < 10 ? '0'+date.getMinutes() : date.getMinutes()) + ':';
	var s = (date.getSeconds() < 10 ? '0'+date.getSeconds() : date.getSeconds());
	strDate = Y+M+D+h+m+s;
	return strDate;
}

在传值的时候直接规范化。

四、总结

1.Vue中数值传送是比较简单的部分,主要是准备好等待接收的变量,保证数据成功被载入,数据的类型问题也要注意,要仔细核对后端寄来的数据。Vue的前后端交互都是有较简单实用的模板来实现的,所以很好掌握。

2.显示数据的时候要参透不同组件的展示方式,有的利用item循环展示,有的直接引用,更多是用v-bind来实现变量影响显示。

3.本次项目开发中,任务面板的开发和代码的编写是很复杂的,容易混淆,因为有多个弹出窗口以及面板,上面用户所填写的内容还有从后台接收所显示的内容都是不同的,它们之间的数据联动是很可怕的,稍不注意就容易一个新面板数据的填写覆盖掉以前已显示的旧数据。尤其对于表单一类需要用户参与填写的组件来说,需要实时监控每个可能交互的子组件,但是千万要注意不一定是每个子组件都需要有及时的反馈,不然产生的不必要的关联动作有可能会影响到最后信息的存储。尤其是带有取消的表单,即需要一键归零,过早的产生相应动作会适得其反。

以上就是如何理解Vue前后端数据交互与显示的详细内容,更多关于Vue前后端数据交互与显示的资料请关注三水点靠木其它相关文章!

Vue.js 相关文章推荐
springboot+vue实现文件上传下载
Nov 17 Vue.js
VUE+Element实现增删改查的示例源码
Nov 23 Vue.js
vue打开其他项目页面并传入数据详解
Nov 25 Vue.js
vue element实现表格合并行数据
Nov 30 Vue.js
Vue-router中hash模式与history模式的区别详解
Dec 15 Vue.js
vue图片裁剪插件vue-cropper使用方法详解
Dec 16 Vue.js
vue+elementUI动态增加表单项并添加验证的代码详解
Dec 17 Vue.js
Vue中computed和watch有哪些区别
Dec 19 Vue.js
vue项目中openlayers绘制行政区划
Dec 24 Vue.js
vue+django实现下载文件的示例
Mar 24 Vue.js
vue报错function () { [native code] },无法出现我们想要的内容 Unknown custom element
Apr 11 Vue.js
vue生命周期钩子函数以及触发时机
Apr 26 Vue.js
Vue实现下拉加载更多
May 09 #Vue.js
如何使用vue3打造一个物料库
vue完美实现el-table列宽自适应
关于Vue Router的10条高级技巧总结
May 06 #Vue.js
Vue项目中如何封装axios(统一管理http请求)
May 02 #Vue.js
使用vue-element-admin框架从后端动态获取菜单功能的实现
vue使用v-model进行跨组件绑定的基本实现方法
You might like
30 个很棒的PHP开源CMS内容管理系统小结
2011/10/14 PHP
IIS6.0 开启Gzip方法及PHP Gzip函数分享
2014/06/08 PHP
php超快高效率统计大文件行数
2015/07/05 PHP
表单提交错误后返回内容消失问题的解决方法(PHP网站)
2015/10/20 PHP
PHP微信开发之有道翻译
2016/06/23 PHP
JavaScript 语法集锦 脚本之家基础推荐
2009/11/15 Javascript
js 事件处理函数间的Event物件是否全等
2011/04/08 Javascript
javascript瀑布流布局实现方法详解
2016/02/17 Javascript
浅谈jQuery 选择器和dom操作
2016/06/07 Javascript
jquery 获取select数组与name数组长度的实现代码
2016/06/20 Javascript
js实现为a标签添加事件的方法(使用闭包循环)
2016/08/02 Javascript
Angular的事件和表单详解
2016/12/26 Javascript
详解webpack介绍&amp;安装&amp;常用命令
2017/06/29 Javascript
微信小程序实现倒计时功能
2020/11/19 Javascript
[01:13:51]TNC vs Serenity 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/19 DOTA
[52:36]VGJ.S vs Serenity 2018国际邀请赛小组赛BO2 第一场 8.19
2018/08/21 DOTA
python创建临时文件夹的方法
2015/07/06 Python
简单谈谈python的反射机制
2016/06/28 Python
numpy.linspace 生成等差数组的方法
2018/07/02 Python
Python坐标线性插值应用实现
2019/11/13 Python
Python中的引用和拷贝实例解析
2019/11/14 Python
matplotlib绘制多子图共享鼠标光标的方法示例
2021/01/08 Python
同步和异步有何异同,在什么情况下分别使用他们?举例说明
2014/02/27 面试题
在网络中有两台主机A和B,并通过路由器和其他交换设备连接起来,已经确认物理连接正确无误,怎么来测试这两台机器是否连通?如果不通,怎么来判断故障点?怎么排
2014/01/13 面试题
Java程序员综合测试题
2014/04/25 面试题
初中政治教学反思
2014/01/17 职场文书
小学毕业家长寄语
2014/01/19 职场文书
2014乡镇“三八”国际劳动妇女节活动总结
2014/03/01 职场文书
公务员群众路线专题民主生活会发言材料
2014/09/17 职场文书
2014年向国旗敬礼活动方案
2014/09/27 职场文书
农村结婚典礼主持词
2015/06/29 职场文书
珍爱生命主题班会
2015/08/13 职场文书
如何写一份具有法律效力的借款协议书?
2019/07/02 职场文书
新店开业策划方案怎么书写?
2019/07/05 职场文书
HTML5基础学习之文本标签控制
2022/03/25 HTML / CSS
win10输入法不见了只能打出字母怎么解决?
2022/08/05 数码科技