vue中为什么data属性是一个函数而不是一个对象

面试官:为什么data属性是一个函数而不是一个对象?

一、实例和组件定义data的区别

vue实例的时候定义data属性既可以是一个对象,也可以是一个函数

const app = new Vue({
    el:"#app",
    // 对象格式
    data:{
        foo:"foo"
    },
    // 函数格式
    data(){
        return {
             foo:"foo"
        }
    }
})

组件中定义data属性,只能是一个函数

如果为组件data直接定义为一个对象

Vue.component('component1',{
    template:`<div>组件</div>`,
    data:{
        foo:"foo"
    }
})

则会得到警告信息

警告说明:返回的data应该是一个函数在每一个组件实例中

二、组件data定义函数与对象的区别

上面讲到组件data必须是一个函数,不知道大家有没有思考过这是为什么呢?

在我们定义好一个组件的时候,vue最终都会通过Vue.extend()构成组件实例

这里我们模仿组件构造函数,定义data属性,采用对象的形式

function Component(){
 
}
Component.prototype.data = {
	count : 0
}

创建两个组件实例

const componentA = new Component()
const componentB = new Component()

修改componentA组件data属性的值,componentB中的值也发生了改变

console.log(componentB.data.count)  // 0
componentA.data.count = 1
console.log(componentB.data.count)  // 1

产生这样的原因这是两者共用了同一个内存地址,componentA修改的内容,同样对componentB产生了影响

如果我们采用函数的形式,则不会出现这种情况(函数返回的对象内存地址并不相同)

function Component(){
	this.data = this.data()
}
Component.prototype.data = function (){
    return {
   		count : 0
    }
}

修改componentA组件data属性的值,componentB中的值不受影响

console.log(componentB.data.count)  // 0
componentA.data.count = 1
console.log(componentB.data.count)  // 0

vue组件可能会有很多个实例,采用函数返回一个全新data形式,使每个实例对象的数据不会受到其他实例对象数据的污染

三、原理分析

首先可以看看vue初始化data的代码,data的定义可以是函数也可以是对象

源码位置:/vue-dev/src/core/instance/state.js

function initData (vm: Component) {
  let data = vm.$options.data
  data = vm._data = typeof data === 'function'
    ? getData(data, vm)
    : data || {}
    ...
}

data既能是object也能是function,那为什么还会出现上文警告呢?

别急,继续看下文

组件在创建的时候,会进行选项的合并

源码位置:/vue-dev/src/core/util/options.js

自定义组件会进入mergeOptions进行选项合并

Vue.prototype._init = function (options?: Object) {
    ...
    // merge options
    if (options && options._isComponent) {
      // optimize internal component instantiation
      // since dynamic options merging is pretty slow, and none of the
      // internal component options needs special treatment.
      initInternalComponent(vm, options)
    } else {
      vm.$options = mergeOptions(
        resolveConstructorOptions(vm.constructor),
        options || {},
        vm
      )
    }
    ...
  }

定义data会进行数据校验

源码位置:/vue-dev/src/core/instance/init.js

这时候vm实例为undefined,进入if判断,若data类型不是function,则出现警告提示

strats.data = function (
  parentVal: any,
  childVal: any,
  vm?: Component
): ?Function {
  if (!vm) {
    if (childVal && typeof childVal !== "function") {
      process.env.NODE_ENV !== "production" &&
        warn(
          'The "data" option should be a function ' +
            "that returns a per-instance value in component " +
            "definitions.",
          vm
        );

      return parentVal;
    }
    return mergeDataOrFn(parentVal, childVal);
  }
  return mergeDataOrFn(parentVal, childVal, vm);
};

四、结论

  • 根实例对象data可以是对象也可以是函数(根实例是单例),不会产生数据污染情况
  • 组件实例对象data必须为函数,目的是为了防止多个组件实例对象之间共用一个data,产生数据污染。采用函数的形式,initData时会将其作为工厂函数都会返回全新data对象
参考链接

为什么data属性是一个函数而不是一个对象

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/175247.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

NX二次开发UF_CAM_opt_ask_subtypes 函数介绍

文章作者&#xff1a;里海 来源网站&#xff1a;https://blog.csdn.net/WangPaiFeiXingYuan UF_CAM_opt_ask_subtypes Defined in: uf_cam.h int UF_CAM_opt_ask_subtypes(const char * opt_type_name, UF_CAM_opt_stype_cls_t subtype_class, int * count, const char * * *…

CBC算法实践Demo

效果图 全部代码 package encryption001;import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import java.util.Base64;public class EncryptionDemo {// 加密算法private static final String ALGORITHM "AES";// 加密模式和填充方式private s…

软件工程--软件建模--结构化方法通俗语言总结(暴肝超详解)(包含数据流图、数据字典、ER图、结构化设计和优化......)

目录 结构化分析 数据流图DFD 定义数据字典 实体关系图&#xff08;E-R图&#xff09; 结构化设计 变换映射 事务映射 优化结构设计 实例分析 详细设计&#xff08;过程设计&#xff09; 结构化方法是一种系统化开发软件的方法&#xff0c;该方法基于模块化的思想&am…

使用vue-cli搭建vue项目

1&#xff1a;安装vue-cli 命令&#xff1a;npm install -g vue/cli 2&#xff1a;查看安装的版本 vue --version 或者 vue -V 3&#xff1a;创建项目 vue create 项目名称 名称小写 4&#xff1a;vue2框架中根据自己的需求选择&#xff08;我选择…

springboot+bootstrap+java农业电商服务商城系统_30249

本农业电商服务系统是为了提高用户查阅信息的效率和管理人员管理信息的工作效率&#xff0c;可以快速存储大量数据&#xff0c;还有信息检索功能&#xff0c;这大大的满足了管理员、会员和商家这三者的需求。操作简单易懂&#xff0c;合理分析各个模块的功能&#xff0c;尽可能…

系列二、为什么要使用ThreadLocal?

一、为什么要使用ThreadLocal&#xff1f; 1.1、概述 并发场景下&#xff0c;会存在多个线程同时修改一个共享变量的场景&#xff0c;这就有可能会出现线程安全的问题。为了解决线程安全问题&#xff0c;可以用加锁的方式&#xff0c;比如对核心代码使用synchronized或者Lock进…

排序算法--插入排序

实现逻辑 ① 从第一个元素开始&#xff0c;该元素可以认为已经被排序 ② 取出下一个元素&#xff0c;在已经排序的元素序列中从后向前扫描 ③如果该元素&#xff08;已排序&#xff09;大于新元素&#xff0c;将该元素移到下一位置 ④ 重复步骤③&#xff0c;直到找到已排序的元…

最新红盟云卡个人自动发卡开源系统源码+全开源无加密+虚拟商品在线售卖平台

源码简介&#xff1a; 最新红盟云卡个人自动发卡开源系统源码全开源无加密虚拟商品在线售卖平台&#xff0c;支持多个接口的个人免签功能。 红盟云卡系统是一款基于PHP和MySQL开发的虚拟商品在线售卖平台。它具备美观且功能丰富的发卡网站特性&#xff0c;并可与社区进行无缝…

数独·12中解法·anroid 数独小游戏·休闲益智小游戏

标题数独12中解法anroid 数独小游戏休闲益智小游戏&#xff08;继续更新中……&#xff09; 一款经典数独训练app 资源下载 &#xff08;0积分&#xff09;https://download.csdn.net/download/qq_38355313/88544810 —— —— 数独&#xff08;sh d&#xff09;是源自18世纪…

重磅!TikTok Shop将以新方式重启印尼业务

据报道&#xff0c;TikTok将通过与印尼电商平台合作的方式重启电商业务。 据悉&#xff0c;印尼合作社和中小企业部就TikTok Shop将在印尼重新开业的消息发表了讲话。合作社和中小企业部Temmy Satya Permana证实TikTok Shop将在印尼重新开业的消息。他表示&#xff0c;TikTok …

酒店预订订房小程序源码系统+多酒店入驻 功能齐全 附带完整的搭建教程

随着互联网的快速发展&#xff0c;越来越多的人选择通过在线预订平台预订酒店。为了满足这一需求&#xff0c;我们开发了这个酒店预订订房小程序源码系统。该系统基于先进的云计算技术和大数据分析&#xff0c;旨在为用户提供更加便捷、智能的酒店预订服务。 以下是部分代码示…

java+springboot+bootstrap校园闲置物品拍卖交易平台_ngad7-

根据日常实际需要&#xff0c;一方面需要在系统中实现基础信息的管理&#xff0c;同时还需要结合实际情况的需要&#xff0c;提供校园闲置物品交易管理功能&#xff0c;方便校园闲置物品交易管理工作的展开&#xff0c;综合考虑&#xff0c;本套系统应该满足如下要求&#xff1…

【C++】二叉搜索树

二叉搜索树 1.二叉搜索树概念2.二叉搜索的实现2.1结点2.1基本框架2.2插入2.3查找2.4删除2.5打印 3.二叉搜索树递归实现3.1查找3.2插入3.3删除 4.二叉搜索树默认成员函数4.1构造4.2析构4.3拷贝构造4.4赋值重载 6.二叉搜索树的应用6.1K模型6.2KV模型 7.二叉搜索树的性能分析 喜欢…

Apache服务Rwrite功能使用

Rewrite也称为规则重写&#xff0c;主要功能是实现浏览器访问时&#xff0c;URL的跳转。其正则表达式是基于Perl语言。要使用rewrite功能&#xff0c;Apache服务器需要添加rewrite模块。如果使用源码编译安装&#xff0c;–enable-rewrite。有了rewrite模块后&#xff0c;需要在…

Rust生态系统:探索常用的库和框架

大家好&#xff01;我是lincyang。 今天我们来探索Rust的生态系统&#xff0c;特别是其中的一些常用库和框架。 Rust生态系统虽然相比于一些更成熟的语言还在成长阶段&#xff0c;但已经有很多强大的工具和库支持各种应用的开发。 常用的Rust库和框架 Serde&#xff1a;一个…

Redis篇---第十三篇

系列文章目录 文章目录 系列文章目录前言一、redis的过期策略以及内存淘汰机制二、Redis 为什么是单线程的三、Redis 常见性能问题和解决方案?前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看…

绝地求生:想玩以前的老地图

小编是22年8月左右开始玩的&#xff0c;更早以前跟同学偶尔玩过几次&#xff0c;所以萨诺2.0玩过&#xff0c;不过那时候菜的还不如人机&#xff0c;死了都看不到人在哪&#xff0c;所以对地图没啥印象&#xff0c;比较有印象的是地图色调变得很黄昏。 自闭城 遗迹 这是迪厅&am…

机器人算法—ROS TF坐标变换

1.TF基本概念 &#xff08;1&#xff09;什么是TF&#xff1f; TF是Transformations Frames的缩写。在ROS中&#xff0c;是一个工具包&#xff0c;提供了坐标转换等方面的功能。 tf工具包&#xff0c;底层实现采用的是一种树状数据结构&#xff0c;根据时间缓冲并维护多个参考…

【云栖 2023】姜伟华:Hologres Serverless 之路——揭秘弹性计算组

云布道师 本文根据 2023 云栖大会演讲实录整理而成&#xff0c;演讲信息如下&#xff1a; 演讲人&#xff1a;姜伟华 | 阿里云计算平台事业部资深技术专家、阿里云实时数仓 Hologres 研发负责人 演讲主题&#xff1a;Hologres Serverless 之路——揭秘弹性计算组 实时化成为…

基于SSM 离退休管理平台-计算机毕设 附源码 52629

ssm离退休管理平台 摘 要 随着社会的发展&#xff0c;社会的方方面面都在利用信息化时代的优势。互联网的优势和普及使得各种系统的开发成为必需。 本文以实际运用为开发背景&#xff0c;运用软件工程原理和开发方法&#xff0c;它主要是采用SSM技术和mysql数据库来完成对系统的…
最新文章