Vue的组件data为什么要用函数?简单代码重现分析

看了网上好多文章都是说使用函数是为了每个组件的数据独立,不被污染。其实使用传参正常是没有问题,问题出在Vue实现组件的原理我们只能使用函数。

为什么在定义组件的data使用对象就会制成数据污染呢?首先要了解出现问题的原因,这是JS对象指针搞出的问题,对象是用指针地址引用的,请看下面事例代码

var obj = {name:'vue'};
var obj2 = obj;
//改变obj2的name
obj2.name = '我修改一下';
console.log(obj, obj2);

控制台打印结果如下

 

为什么修改了obj2的name,obj的name也变了,这就是js对象的指针搞的鬼,原理如下图

 

obj指向内存地址:001,obj2 = obj,当我们修改了obj2.name的时候,其实就是修改了内存地址:001的数据,因为obj的内存地址为001,所以obj.name也被修改了。

再看一下Vue组件实现的流程,为什么data使用对象会出问题。

Vue的组件是定义在Vue.options.components静态属性下,下图中的todo-item就是我定义的组件,data我使用了对象,默认是不可以的,但我修改了代码,修改方法看第二张图。


 

vue.js

我使用的是vue2版本,查找strats.data关键字可以导航到,源代码会检查组件data是否为函数,如果为函数就会返回,我们注释这一行就行了。我定义的组件代码如下。

// 定义名为 todo-item 的新组件
Vue.component('todo-item', {
  template: '<div><b>这是个待办项:{{name}}<button @click="changeName">click</button></b></div>',
  //data:{name:'haha'},
  methods:{
    changeName(){
        this.name = new Date();
    }
  },
  data(){return {name:'haha'}}
})

var vm = new Vue(
{
    el:'#app',
    data:{
        message:'hello world'    
    }
}
);

html代码如下,使用两次组件todo-item

 

<div id="app">
  <div>{{ message }}</div>
  <todo-item></todo-item>
  <todo-item></todo-item>
</div>

 当点击click的时候会改变组件的变量name,这时我们点击其中一个的时候两个组件的值会一样,如下图,这就是出问题了

 我们来分析一下,它是怎么产生这个问题的。前面我们提到Vue的组件是定义在Vue.options.components静态属性下,组件在实例化的时候会使用这里定义的数据,我们可以看到data定义为对象{name:'haha'},当我们实例化组件的时候都会引用这个对象,你没听错是引用,引用就会有指针问题,当我们实例化两个对象的时候,任意一个组件修改了data的变量,data指向的源数据就会被修改,引用的组件的data也会改变。

修改后的数据如下图,可以看到组件定义的源对象和两个组件的值一样,因为是引用。

 当我们组件的data使用函数就不会出现对象污染问题了,如下图,因为每次组件实例化后的data会产生不一样的内存地址,所以组件的data修改只会影响自己的内存地址。

其实组件的data定义也可以是对象的,在实例化组件的时候对data作深度克隆产生新的地址就可以了,那为什么Vue没有作这个兼容性呢?它是老大它说了算,我们按说明书操作就可以了。

对象指针问题在实际项目中也会产生的,大家要多加注意。例如在列表点击详细,在详细修改了变量,列表的变量也会跟着修改,这时候在详细页就要做深度克隆处理了。怎么做深度克隆你们自行学习了。好像Vue没有提供深度克隆的函数,要自己引用第三方的函数。

 神奇的JS指针就讲到这了,指针应该是给全局使用场景用的(统一性,改一处全部生效),如果是拷贝场景(独立性,自己管理自己)就要对它做深度克隆再使用了,减少不必要的麻烦。

上面所讲只是个人认知,如有错误请自行学习改正。本人使用Vue不到两个星期,还是一个Vue小白。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值