手机版

详细讲解vue.js的道具转移参数

时间:2021-09-02 来源:互联网 编辑:宝哥软件园 浏览:

本文通过演示实例,详细分析道具传送参数的使用以及遇到问题后的解决方法。以下是全部内容。

前段时间,vue被用作后台管理系统,每个页面都需要一个表格来显示信息。自然,我想到了将表提取出来做成一个通用组件,从不同的页面导入数据进行渲染,从而达到重用的目的。

演示地址

1.问题发现

在父组件中,要传输到表格组件的数据包括表格内容数据表格数据和表格页面数据。

div my-table : table-data=' tableData ' : page-info=' page info ' id=' my table '/my-table/div,其中table data是一个Array对象,它是由表中要显示的所有数据对象组成的数组。页面信息是一个对象,它包含表格页面信息。按照以下形式初始化父组件中的两个数据对

Tabledata: [],pageInfo: {current: 1,//什么页面总计: 100,//数据对象的总数大小: 20 //每页显示的数量}

根据官方文件,prop是单向绑定的,在子组件内部不应该更改prop。修改prop中数据的冲动是,在prop作为初始值引入后,子组件希望将其用作本地数据。在这种情况下,官方的说法是定义一个局部变量,并用prop的值初始化它:

Props: ['tabledata ',' pageinfo'],data () {return {tdata:this。tabledata,第:页。pageinfo}}然后根据官方文档,每次父组件更新时,子组件的所有prop都会更新到最新值。并且tableData和pageInfo的信息是通过api从服务器异步获取的:

{error: 0,msg: '调用成功。data : { restriction info :[.],总计: 42}}

因此,当获得数据时,父组件需要更改传递给子组件的值:

me . table data=Json . data . restriction info;me . PageInfo . total=Json . data . total;理所当然,此时子组件中的值应该更新为服务器返回的值,但是子组件页面的总数已经更新,但是初始化时表数据仍然是一个空数组。(黑色问号?)

2.分配和绑定

首先,我们需要定位数据出错的地方,所以我做了一个演示来定位问题。

首先查看父组件和子组件中每个元素的初始值:

然后,当您只更改父组件中数组的引用时,您可以看到子组件的props数组发生了变化,但是子组件中的绑定数组没有变化

所以可以发现,问题就出在这一步

prop :[' tableData ',' pageInfo'],data(){ return { tdata : this . tableData,page: this.pageInfo }}

要找出问题的根源,必须找出vue文档中深度响应的原理。

在Vue实例的数据选项中,Vue将遍历这个对象的所有属性,并使用Object.defineProperty将这些属性变成getter/setter。每个组件实例都有一个对应的观察器实例对象,在组件渲染过程中将属性记录为依赖项,然后当依赖项的设置器被调用时,它会通知观察器重新计算,以便更新其关联的组件。文档中有这么多描述,简单理解就是Vue绑定了vm。$data.a在data选项中以两个方向指向DOM中的vm.a,也就是说,其中一个发生变化,另一个也会发生变化。在Vue源代码中,它是通过defineReactive $ $ 1函数实现的:

但在其中,Object.defineProperty的获取和设置方法主要用于实现双向绑定。在子组件中,子组件的pros数据和$数据以下列方式链接在一起:

tData: this.tableData

查询Vue源代码显示this.tableData和tData只是赋值,也就是,'='关系

上面的initData函数是在组件构建过程中执行的,所以在创建过程中只会执行一次。这就是为什么官方文件说‘传入为初始值’,因为它只会执行一次。当构建组件时,this.tableData与tData没有关系,一个的改变不会引起另一个的改变。当然,这种说法并不准确,因为在上面,我们动态地改变了父组件引入的总量,子组件也发生了变化,这种感觉就像是被绑定在了一起。这是怎么回事?

3.引用类型导致的错觉

当然,这个问题还是要从官方文件上解决。文件中有这样的提示:

在这里,我们需要理解引用类型的概念。引用数据类型值引用存储在堆内存中的对象。也就是说,存储在变量中的实际上只是一个指针,它指向内存中存储对象的另一个位置。访问是通过引用进行的。例如,一个js对象A存储在内存中,如下图所示:

var a=新对象();

操作时,需要先从栈中读取内存地址,然后延迟指针找到堆内存中存储的值再进行操作。

a.name=' xz

引用类型变量的赋值本质上是栈中存储的指针,被复制到栈中新变量没有分配的空间,这个指针的副本和原来的指针指向堆中存储的同一个对象;赋值操作之后,这两个变量实际上将引用同一个对象。因此,在使用时,更改一个变量的值会影响另一个变量。

var b=a;

在理解了引用类型之后,让我们来看看在动态变化被引入到上面提到的子组件之前和之后内存中的情况:

me . table data=Json . data . restriction info;me . PageInfo . total=Json . data . total;=========================================prop s :[' tableData ',' pageInfo'],data(){ return { tdata : this . tableData,page: this.pageInfo }}

首先,对tableData的更改是更改它所引用的指针,而其中一个属性的值更改为pageInfo。因此,在动态变化之前:

动态变化后:

这解释了为什么子组件页面总数已经更新,但表数据在初始化时仍然是一个空数组。由于引用类型的存在,我们动态地改变父组件传入的总数,子组件也相应地改变。

版权声明:详细讲解vue.js的道具转移参数是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。