0

0

vue初始化data方法有哪些

青灯夜游

青灯夜游

发布时间:2022-12-26 18:09:35

|

4081人浏览过

|

来源于php中文网

原创

vue初始化data方法有两种:1、object方式,语法“var data = { 键值对 }”;2、function方式,语法“data: function () {return { 键值对 }}”。需要注意组件和extend中的data初始化不能是Object,否则会报错。组件中data用function方式是为了防止多个组件实例对象之间共用一个data,产生数据污染。

vue初始化data方法有哪些

本教程操作环境:windows7系统、vue3版,DELL G3电脑。

vue data有两种初始化的方式,function和object,但是这两种情况适用场景有哪些?能不能通用?带着这两个问题咱们一起分析下

data初始化

// 代码来源于官网示例

// 第一种定义方式
var data = { a: 1 }

// 直接创建一个实例
var vm = new Vue({
  data: data
})

// Vue.extend() 中 data 必须是函数
var Component = Vue.extend({
// 第二种定义方式
  data: function () {
    return { a: 1 }
  }
})

上述代码简单描述了data定义的两种方式

立即学习前端免费学习笔记(深入)”;

  • function

  • object

官网demo中也着重说了extend中data初始化不能用object。那么为什么呢?

源码分析

按照官网demo,Vue.extend中的data初始化不能是Object,如果我们强制写成Object会出现什么?

var Component = Vue.extend({
  data: { a: 1 }
})

运行以后chrome的consolo直接报错,信息如下

vue.esm.js?efeb:591 [Vue warn]: The "data" option should be a function that returns a per-instance value in component definitions.

通过分析源码以及报错信息,当触发Vue.extend的时候,他会做一个合并操作,把一个基础组件(里面vmode, transtion等)和你定义在extend内的信息,通过mergeField往options上合并,当合并到data的时候,他会触发strats.data,在这个里面会check data是不是一个function,这里需要注意的是filter、components等和data走的是两套合并流程,详细的请看代码注释,如下

// vue.extend 源码地址https://github.com/vuejs/vue/blob/dev/src/core/global-api/extend.js

  Vue.extend = function (extendOptions: Object): Function {
  ...
  // 在这里会触发mergeOptions方法
  Sub.options = mergeOptions(
      Super.options,
      extendOptions
    )
  ...
}

// mergeOptions 源码地址https://github.com/vuejs/vue/blob/dev/src/core/util/options.js

export function mergeOptions (
  parent: Object,
  child: Object,
  vm?: Component
): Object {
  ...

  const options = {}
  let key
  // parent对象内包含components、filter,、directive
  for (key in parent) {
    mergeField(key)
  }
  // child对象内对应的是Vue.extend内定义的参数
  for (key in child) {
    if (!hasOwn(parent, key)) {
      mergeField(key)
    }
  }
  function mergeField (key) {
  // 这一步是根据传入的key找到不同的合并策略filter、components、directives用到合并策略是这个方法mergeAssets和data用到的不一样,当合并到data的时候会进入专属的合并策略方法内
    const strat = strats[key] || defaultStrat
    options[key] = strat(parent[key], child[key], vm, key)
  }
}

// strats.data  源码地址https://github.com/vuejs/vue/blob/dev/src/core/util/options.js
strats.data = function (
  parentVal,
  childVal,
  vm
) {
  if (!vm) {
  // 如果data不是function的话会直接走下面的报错信息
    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定义为一个对象,因为他们底层都调用了mergeOptions方法

什么时候可以定义成一个对象

在vue初始化的时候,如下

new Vue({
  data: {
    linke: '//sinker.club'
  }
})

意义

ok,上面说了那么多,那么这么做的意义是什么?为什么那几种情况不可以定义为对象? 其实回答这个问题,需要回到js本身,众所周知js数据类型分为引用和基本,引用类型包含Object, Array, Function,何为引用类型就不在这里阐述了

  var obj = {link: '//www.sinker.club'}
  var obj2 = obj
  var obj3 = obj
  obj2.link = "//gitlab.sinker.club"
  console.log(obj3.link) // "//gitlab.sinker.club"

上述代码反应了一个问题,由于obj3和obj2在内存中都是指向一个地址,那么obj2的修改会影响到obj3,当然处理这种问题可以用深copy来做到

Quinvio AI
Quinvio AI

AI辅助下快速创建视频,虚拟代言人

下载
  • JSON.parse(JSON.stringify(obj))

  • deepClone(obj)

但是这两种做法需要开发或者框架每一次都要深copy一次,当数据量大的时候对性能什么都不友好,那么Vue怎么做的呢?把data定义成一个function

function data() {
  return {
   link: '//sinker.club'
  }
}

var obj = test()
var obj2 = test()

obj2.link ="//gitlab.sinker.club"
console.log(obj.link) '//sinker.club'

为什么这么做?解决的场景是什么呢?

比如我定一个子组件,data是按照对象的方式定义的,这个组件在多个地方引用,如果其中一个引用此组件的data修改了,那么就会造成其余引用此组件的data同时改变, end.

扩展知识:

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

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

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

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

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

则会得到警告信息

1.png

说明:

  • vue中组件是用来复用的,为了防止data复用,将其定义为函数。

  • vue组件中的data数据都应该是相互隔离,互不影响的,组件每复用一次,data数据就应该被复制一次,之后,当某一处复用的地方组件内data数据被改变时,其他复用地方组件的data数据不受影响,就需要通过data函数返回一个对象作为组件的状态。

  • 当我们将组件中的data写成一个函数,数据以函数返回值形式定义,这样每复用一次组件,就会返回一份新的data,拥有自己的作用域,类似于给每个组件实例创建一个私有的数据空间,让各个组件实例维护各自的数据。

  • 当我们组件的date单纯的写成对象形式,这些实例用的是同一个构造函数,由于JavaScript的特性所导致,所有的组件实例共用了一个data,就会造成一个变了全都会变的结果。

【相关推荐:vuejs视频教程web前端开发

相关文章

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
js获取数组长度的方法
js获取数组长度的方法

在js中,可以利用array对象的length属性来获取数组长度,该属性可设置或返回数组中元素的数目,只需要使用“array.length”语句即可返回表示数组对象的元素个数的数值,也就是长度值。php中文网还提供JavaScript数组的相关下载、相关课程等内容,供大家免费下载使用。

557

2023.06.20

js刷新当前页面
js刷新当前页面

js刷新当前页面的方法:1、reload方法,该方法强迫浏览器刷新当前页面,语法为“location.reload([bForceGet]) ”;2、replace方法,该方法通过指定URL替换当前缓存在历史里(客户端)的项目,因此当使用replace方法之后,不能通过“前进”和“后退”来访问已经被替换的URL,语法为“location.replace(URL) ”。php中文网为大家带来了js刷新当前页面的相关知识、以及相关文章等内容

374

2023.07.04

js四舍五入
js四舍五入

js四舍五入的方法:1、tofixed方法,可把 Number 四舍五入为指定小数位数的数字;2、round() 方法,可把一个数字舍入为最接近的整数。php中文网为大家带来了js四舍五入的相关知识、以及相关文章等内容

754

2023.07.04

js删除节点的方法
js删除节点的方法

js删除节点的方法有:1、removeChild()方法,用于从父节点中移除指定的子节点,它需要两个参数,第一个参数是要删除的子节点,第二个参数是父节点;2、parentNode.removeChild()方法,可以直接通过父节点调用来删除子节点;3、remove()方法,可以直接删除节点,而无需指定父节点;4、innerHTML属性,用于删除节点的内容。

478

2023.09.01

JavaScript转义字符
JavaScript转义字符

JavaScript中的转义字符是反斜杠和引号,可以在字符串中表示特殊字符或改变字符的含义。本专题为大家提供转义字符相关的文章、下载、课程内容,供大家免费下载体验。

434

2023.09.04

js生成随机数的方法
js生成随机数的方法

js生成随机数的方法有:1、使用random函数生成0-1之间的随机数;2、使用random函数和特定范围来生成随机整数;3、使用random函数和round函数生成0-99之间的随机整数;4、使用random函数和其他函数生成更复杂的随机数;5、使用random函数和其他函数生成范围内的随机小数;6、使用random函数和其他函数生成范围内的随机整数或小数。

1031

2023.09.04

如何启用JavaScript
如何启用JavaScript

JavaScript启用方法有内联脚本、内部脚本、外部脚本和异步加载。详细介绍:1、内联脚本是将JavaScript代码直接嵌入到HTML标签中;2、内部脚本是将JavaScript代码放置在HTML文件的`<script>`标签中;3、外部脚本是将JavaScript代码放置在一个独立的文件;4、外部脚本是将JavaScript代码放置在一个独立的文件。

658

2023.09.12

Js中Symbol类详解
Js中Symbol类详解

javascript中的Symbol数据类型是一种基本数据类型,用于表示独一无二的值。Symbol的特点:1、独一无二,每个Symbol值都是唯一的,不会与其他任何值相等;2、不可变性,Symbol值一旦创建,就不能修改或者重新赋值;3、隐藏性,Symbol值不会被隐式转换为其他类型;4、无法枚举,Symbol值作为对象的属性名时,默认是不可枚举的。

553

2023.09.20

云朵浏览器入口合集
云朵浏览器入口合集

本专题整合了云朵浏览器入口合集,阅读专题下面的文章了解更多详细地址。

20

2026.01.20

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Vue3.x 工具篇--十天技能课堂
Vue3.x 工具篇--十天技能课堂

共26课时 | 1.4万人学习

Vue3.x 核心篇--十天技能课堂
Vue3.x 核心篇--十天技能课堂

共30课时 | 1.5万人学习

Vue3.x新特性篇--十天基础课堂
Vue3.x新特性篇--十天基础课堂

共20课时 | 1.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号