vue基础知识八:为什么data属性是一个函数而不是一个对象?

news2024/11/26 15:44:12

在这里插入图片描述
一、实例和组件定义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对象

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

学习day59

昨天学了插槽&#xff0c;但是没有即笔记了 今天的是vuex 总体来说&#xff0c;vuex就是一个共享单车&#xff0c;每个人都可以使用他&#xff0c;也可也对他进行反馈。即把一个数据列为vuex&#xff0c;然后每个组件可以使用这个对象&#xff0c;也可也反过来反馈他 这一个设…

VScode在服务器上远程调试python代码的工作目录问题

背景&#xff1a; 当前很多写代码都习惯使用相对路径&#xff0c;即以当前的py文件为工作目录去寻找其他的py文件。所以如果工作目录不是以当前的py文件为起始的话&#xff0c;这将导致去跑一些开源代码的时候运行不起来。 现在我遇到的问题就是&#xff0c;在远程服务器上&…

【MFC】tab控件 仿任务管理器 枚举窗口和进程

界面和关联变量设置 创建一个基于对话框的MFC项目&#xff0c;给主对话框添加一个tab控件&#xff08;设置关联变量 类型&#xff1a;CTabCtrl 名称&#xff1a;m_tab&#xff09;&#xff0c;添加两个子对话框&#xff08;IDC_PAGE1和IDC_PAGE2&#xff09;&#xff0c;给子对…

对IMU的认识

参数标定&#xff1a; 良率检测 内参标定过程 1.线性误差模型 零偏&#xff1a;静止时的误差 尺度偏差&#xff1a;每个轴上电压到实际值之间的比例差值 1->1.5 或者 1->1.3(直线的斜率) 轴偏差&#xff1a; 如下图 2.标定过程&#xff1a; 2.1角加速度标定 重…

84 # koa 实现文件上传功能

下面使用实现文件上传功能&#xff0c;先新建文件夹&#xff0c;结构如下&#xff1a; index.html <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-…

EtsyAI评论分析工具:让你的店铺运营更省心!

Etsy 是一个在线市场平台&#xff0c;成立于 2005 年&#xff0c;总部位于美国纽约。Etsy 的主要特点是它专注于手工艺品、独立设计、艺术品、古董物品和特色商品的销售。 Etsy是一个知名的电商平台&#xff0c;它专注于手工艺品、创意设计和独特商品的售卖&#xff0c;相信大家…

【自动化测试】如何提高自动化脚本的健壮性和稳定性?

自动化脚本可能出错的原因&#xff1f; 配置环境引起 自动化测试脚本的配置。对测试程序进行配置。如&#xff1a;是否还原初始设置、是否删除某些数据。对浏览器进行配置。对与测试程序有关的程序或影响脚本稳定性的程序进行配置。 非配置环境引起 网络延时&#xff0c;识…

python 爬虫的开发环境配置

1、新建一个python项目 2、在控制台中分别安装下面三个包 pip install requests pip install beautifulsoup4 pip install selenium/ 如果安装时报以下错误&#xff1a; raise ReadTimeoutError(self._pool, None, "Read timed out.") pip._vendor.urllib3.exceptio…

SegGPT: Segmenting Everything In Context论文笔记

论文https://arxiv.org/pdf/2304.03284.pdfCodehttps://github.com/baaivision/Painter 文章目录 1. 背景2. Motivation3. Method3.1 In-Context Coloring3.2 Context Ensemble3.3 In-Context Tuning 1. 背景 在Painter中&#xff0c;将各种密集预测任务视为一种着色问题。 在…

实用前端调试技巧

调试是项目开发中非常重要的环节。掌握一些调试技巧&#xff0c;不仅能帮助我们定位到问题&#xff0c;还能提升我们的开发效率。本文从两个场景来介绍调试技巧&#xff1a; 代码报错。 逻辑出错。 调试代码报错的技巧 技巧1: 读懂报错信息 大部分情况下&#xff0c;能读懂…

day5_C++

day5_C 继承 代码思维导图 继承 代码 #include <iostream>#define PI 3.14using namespace std;class Shape {protected:double perimeter;double area;public:Shape() {cout<<"Shape::无参构造"<<endl;}Shape(double perimeter,double area):per…

21 搜索二维矩阵 II

搜索二维矩阵 II 题解1 对角线上下循环搜索&#xff08;超时&#xff09; 生气&#xff01;&#xff01;无脑循环都不超时题解2 无脑循环题解3 学习STL(二分查找) 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性&#xff1a; 每行…

通过Power Platform自定义D365 CE 业务需求 - 3. 使用Microsoft Power应用程序

Microsoft Power Apps是一个用于开发应用程序的无代码、无代码平台。Power应用程序可以在Dataverse之上配置为数据库。尽管您可以连接Salesforce、OneDrive、Dropbox等多种云源,但Dataverse也可以用作内部数据库来构建应用程序,并通过连接器连接其他数据源进行集成。 Power应…

Redis 初识与入门

1. 什么是Redis Redis 是一种基于内存的数据库&#xff0c;对数据的读写操作都是在内存中完成&#xff0c;因此读写速度非常快&#xff0c;常用于缓存&#xff0c;消息队列、分布式锁等场景。 Redis 提供了多种数据类型来支持不同的业务场景&#xff0c;比如 String(字符串)、…

使用CoreOS来部署一个Kubernetes集群,包括必要的步骤和关键概念

文章目录 什么是CoreOS&#xff1f;准备CoreOS节点安装Kubernetes初始化Kubernetes控制平面加入其他节点设置kubectl配置安装网络插件验证集群部署应用程序结论 &#x1f388;个人主页&#xff1a;程序员 小侯 &#x1f390;CSDN新晋作者 &#x1f389;欢迎 &#x1f44d;点赞✍…

python 虚拟环境调用allure报错:FileNotFoundError: [WinError 2] 系统找不到指定的文件

一、遇到的问题 python代码调用命令行 allure命令报错&#xff0c;提示找不到allure这个命令。python虚拟环境中已经安装了pytest-allure 代码如下&#xff1a; import subprocessif __name__ "__main__":# retcode pytest.main()subprocess.call([pytest, --al…

SpringBoot整合Canal实现MySQL与ES数据同步

文章目录 SpringBoot项目引入Canal依赖配置文件项目结构设置监听类其余类、接口内容启动类实体类Controller类Mapper接口Serice接口 运行测试 开始之前请确认docker中已运行mysql与canal容器&#xff0c;并完成了监听binlog配置 未完成可移步&#xff1a; Docker部署Canal监听…

领域驱动设计:事件风暴构建领域模型

文章目录 事件风暴需要准备些什么&#xff1f;如何用事件风暴构建领域模型&#xff1f; 事件风暴是一项团队活动&#xff0c;领域专家与项目团队通过头脑风暴的形式&#xff0c;罗列出领域中所有的领域事件&#xff0c;整合之后形成最终的领域事件集合&#xff0c;然后对每一个…

共享股东模式:一种新型的商业模式,让你轻松创业

你是否想过拥有自己的事业&#xff0c;但又觉得创业风险太大&#xff0c;资金太少&#xff0c;人脉太弱&#xff1f;你是否想过利用自己的消费能力&#xff0c;获得更多的收益&#xff0c;而不仅仅是消费者&#xff1f;你是否想过成为一个有影响力的人&#xff0c;为社会创造价…

【STM32】影子寄存器

不可操作但是真正起作用的寄存器是影子寄存器 定时器框图中&#xff0c;有些寄存器下有个阴影 这些阴影的表示这些寄存器存在影子寄存器。 图中也有对这些影子的说明&#xff0c;在U事件时传送预装载寄存器至实际寄存器。 有阴影的寄存器(AutoReloadRegister)&#xff0c;表…