Vue的data为啥只能是函数原理详解

 更新时间:2022年10月19日 14:13:18   作者:当然是黑猫警长啦  
这篇文章主要为大家介绍了Vue的data为啥只能是函数原理详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

前言

在学习vue的时候vue2只有在组件中严格要求data必须是一个函数,而在普通vue实例中,data可以是一个对象,但是在vue3出现后data必须一个函数,当时看着官方文档说的是好像是对象的引用问题,但是内部原理却不是很了解,今天通过一个简单的例子来说明为啥data必须是一个函数

参考 (vue2data描述)

参考: (vue3data描述)

1.Vue3中的data

const { createApp } = Vue
const app = {
    data: {
        a: 1
    },
    template: `
    <h1>{{a}}</h1>
    `
}
createApp(app).mount('#app')

可以看到上来vue就给了警告说明data必须是一个函数 下面直接抛错

2.vue中的data

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

这种写法是可以的,前面提过普通实例data可以是对象,但是在组件中必须是函数, 那么在vue2中难道普通实例就没有缺陷嘛?答案:是有缺陷的, 比如这样

<div id="app1">{{ message }}</div>
<div id="app2">{{ message }}</div> 
const data = { message: 'hello world' }
const vue1 = new Vue({
    el: '#app1',
    data
})
const vue2 = new Vue({
    el: '#app2',
    data
})

这样在页面中会显示2个内容为hello world的div标签 那么当我们通过实例去改变messag呢?

 vue1.message = 'hello Vue'

奇怪的事情发生了,我知识改变了vue1的实例中的数据,但是其他实例的数据也发生了改变,相信很简单就能看出来这应该是共用同一个对象的引用而导致的,这在开放中是非常不友好的,开发者很容易就产生连串的错误,vue2也知道这种缺陷只是没有在普通实例中去体现而已,只在组件中实现了对于data的约束

为了让大家更好的立即为啥data必须是一个函数,黑猫在此简单实现一个vue的实例然后来证明为啥data是一个函数,以及如果data不是一个函数,我们应该如何处理

3.证明data是函数以及原理实现

在实现简单原理之前,我们需要搞清楚Vue在创建实例之前,对于data到底做了什么事情简单来说就是:

vue 在创建实例的过程中调用data函数返回实例对象通过响应式包装后存储在实例的data上并且实例可以直接越过data上并且实例可以直接越过data上并且实例可以直接越过data访问属性

1.通过这句描述可以知道Vue是一个构造函数,并且传入的参数中有一个data的属性,我们可以$data去访问,也可以直接访问这个属性,并且我们需要对这个data做代理
那么简单实现如下

function Vue(options) {
    this.$data = proxy(options.data())
}
function proxy(options) {
    return new Proxy(options, {
        get(target, key, value, receiver) {
            return Reflect.get(target, key, value, receiver)
        },
        set(target, key, newValue, receiver) {
            Reflect.set(target, key, newValue, receiver)
        }
    })
}
const data = function () {
    return {
        a: 'hello world'
    }
}
const vue1 = new Vue({
    data
})
const vue2 = new Vue({
    data
})
vue1.$data.a = 'hello Vue'
console.log(vue1.$data.a) // hello Vue
console.log(vue2.$data.a) // hello world

通过简单实现可与看出来,当我们的data是一个函数的时候,在Vue的构造函数中,只有有实例创建就有执行data函数,然后返回一个特别的对象,所以当我们修改其中一个实例的时候并不会对其他实例的数据产生变化

那么当data不是一个函数呢 ,我们简单改下代码,代码如下

function Vue(options) {
    this.$data = proxy(options.data)
}
function proxy(options) {
    return new Proxy(options, {
        get(target, key, value, receiver) {
            return Reflect.get(target, key, value, receiver)
        },
        set(target, key, newValue, receiver) {
            Reflect.set(target, key, newValue, receiver)
        }
    })
}
const data = {
    a: 'hello world'
}
const vue1 = new Vue({
    data
})
const vue2 = new Vue({
    data
})
vue1.$data.a = 'hello Vue'
console.log(vue1.$data.a) // hello Vue
console.log(vue2.$data.a) // hello Vue

可以看出,由于共用一个对象,当代理的时候也是对同一个对象进行代理,那么当我们通过一个实例去改变数据的时候,就会影响其他实例的状态

4.如果data必须是一个对象呢?

假如有人提出如果data是一个对象,那么我们应该如何处理呢,其实也非常简单,在代理的时候我们可以将传入的data对象通过深拷贝即可,这样我们就不会使用相同引用的对象啦。

[深拷贝封装参考]不一样的深拷贝 

以上就是Vue的data为啥只能是函数原理详解的详细内容,更多关于Vue data 函数原理的资料请关注脚本之家其它相关文章!

相关文章

  • Vue+axios 实现http拦截及路由拦截实例

    Vue+axios 实现http拦截及路由拦截实例

    这篇文章主要介绍了Vue+axios 实现http拦截及路由拦截 ,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-04-04
  • 如何解决.vue文件url引用文件的问题

    如何解决.vue文件url引用文件的问题

    这篇文章主要介绍了解决.vue文件url引用文件的问题,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-01-01
  • vue中路由重定向redirect问题

    vue中路由重定向redirect问题

    这篇文章主要介绍了vue中路由重定向redirect问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-05-05
  • Vue如何实现文件预览和下载功能的前端上传组件

    Vue如何实现文件预览和下载功能的前端上传组件

    在Vue.js项目中,使用ElementUI的el-upload组件可以轻松实现文件上传功能,通过配置组件参数和实现相应的方法,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-09-09
  • Vue+ECharts+高德地图API实现天气预报数据可视化的教程

    Vue+ECharts+高德地图API实现天气预报数据可视化的教程

    所谓数据可视化,我们可以理解为从宏观角度来看一眼就能看出来整个数据的占比,走向,对于数据可视化,很多互联网公司是很看重这一块的,包括大厂,本就将给大家介绍如何通过Vue+ECharts+高德地图API实现天气预报数据可视化
    2023-06-06
  • 记一次Vue中$route序列号报错

    记一次Vue中$route序列号报错

    本文主要介绍了记一次Vue中$route序列号报错,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-04-04
  • vue element 关闭当前tab 跳转到上一路由操作

    vue element 关闭当前tab 跳转到上一路由操作

    这篇文章主要介绍了vue element 关闭当前tab 跳转到上一路由操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-07-07
  • 详解Vue源码之数据的代理访问

    详解Vue源码之数据的代理访问

    这篇文章主要介绍了详解Vue源码之数据的代理访问,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-12-12
  • 如何在Vue单页面中进行业务数据的上报

    如何在Vue单页面中进行业务数据的上报

    为什么要在标题里加上一个业务数据的上报呢,因为在咱们前端项目中,可上报的数据维度太多,比如还有性能数据、页面错误数据、console捕获等。这里我们只讲解业务数据的埋点。
    2021-05-05
  • 详解Vue.js 2.0 如何使用axios

    详解Vue.js 2.0 如何使用axios

    本篇文章主要介绍了Vue.js 2.0 如何使用axios,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-04-04

最新评论