如何理解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 相关文章推荐
vuex的使用和简易实现
Jan 07 Vue.js
Vue实现多页签组件
Jan 14 Vue.js
Vue 事件的$event参数=事件的值案例
Jan 29 Vue.js
vue 实现click同时传入事件对象和自定义参数
Jan 29 Vue.js
vue仿携程轮播图效果(滑动轮播,下方高度自适应)
Feb 11 Vue.js
Vue和Flask通信的实现
May 19 Vue.js
Vue图片裁剪组件实例代码
Jul 02 Vue.js
vue中控制mock在开发环境使用,在生产环境禁用方式
Apr 06 Vue.js
分享一个vue实现的记事本功能案例
Apr 11 Vue.js
vue报错function () { [native code] },无法出现我们想要的内容 Unknown custom element
Apr 11 Vue.js
vue的项目如何打包上线
Apr 13 Vue.js
关于vue-router-link选择样式设置
Apr 30 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
PHP5/ZendEngine2的改进
2006/10/09 PHP
PHP mysql事务问题实例分析
2016/01/18 PHP
使用自定义setTimeout和setInterval使之可以传递参数和对象参数
2009/04/24 Javascript
jquery实现div拖拽宽度示例代码
2013/07/31 Javascript
jquery监听div内容的变化具体实现思路
2013/11/04 Javascript
图片上传插件jquery.uploadify详解
2013/11/15 Javascript
textarea 控制输入字符字节数(示例代码)
2013/12/27 Javascript
jQuery调用RESTful WCF示例代码(GET方法/POST方法)
2014/01/26 Javascript
textarea焦点的用法实现获取焦点清空失去焦点提示效果
2014/05/19 Javascript
12行javascript代码绘制一个八卦图
2015/04/02 Javascript
AngularJS入门教程之AngularJS 模板
2016/08/18 Javascript
使用jquery如何获取时间
2016/10/13 Javascript
深入理解React Native原生模块与JS模块通信的几种方式
2017/07/24 Javascript
javascript算法之二叉搜索树的示例代码
2017/09/12 Javascript
JS/jQuery实现DIV延时几秒后消失或显示的方法
2018/02/12 jQuery
JS选取DOM元素常见操作方法实例分析
2018/12/10 Javascript
python中lambda与def用法对比实例分析
2015/04/30 Python
python脚本设置超时机制系统时间的方法
2016/02/21 Python
Python编程对列表中字典元素进行排序的方法详解
2017/05/26 Python
Python实现将HTML转换成doc格式文件的方法示例
2017/11/20 Python
python实现栅栏加解密 支持密钥加密
2019/03/20 Python
PyCharm 2019.3发布增加了新功能一览
2019/12/08 Python
Pycharm小白级简单使用教程
2020/01/08 Python
python3连接mysql获取ansible动态inventory脚本
2020/01/19 Python
Python异常原理及异常捕捉实现过程解析
2020/03/25 Python
Python3标准库之threading进程中管理并发操作方法
2020/03/30 Python
耐克巴西官方网站:Nike巴西
2016/08/14 全球购物
将世界上最美丽的摄影作品转化为艺术作品:Photos.com
2017/11/28 全球购物
Herve Leger官网:标志性绷带连衣裙等
2018/12/26 全球购物
李开复演讲稿
2014/05/24 职场文书
圣诞节活动策划方案
2014/06/09 职场文书
世界遗产的导游词
2015/02/13 职场文书
婚庆开业庆典主持词
2015/06/30 职场文书
2016大学生国家助学贷款承诺书
2016/03/25 职场文书
jquery插件实现搜索历史
2021/04/24 jQuery
用 Python 元类的特性实现 ORM 框架
2021/05/19 Python