Vue2.X监听data变化的核心API—Object.defineProperty详解

Vue2.X监听data变化的核心API—Object.defineProperty基本使用:

Object.defineProperty实现响应式

1.监听对象(简单对象)

上面通过监听get,set方法了解到data变化,进而可以达到响应式。

2.复杂对象(深度监听),深度监听

触发更新视图

// 触发更新视图
function updateView() {
    console.log(‘视图更新‘)
}

在上面例子data加:

// 准备数据
const data = {
    name: ‘佩奇‘,
    age: 20,
    info: {
        address: ‘宁波‘  // 需要深度监听
    },
}
// 重新定义属性,监听起来
function defineReactive(target, key, value) {
    // 核心 API
    Object.defineProperty(target, key, {
        get() {
            return value
        },
        set(newValue) {
            if (newValue !== value) {
                // 设置新值
                // 注意,value 一直在闭包中,此处设置完之后,再 get 时也是会获取最新的值
                value = newValue

                // 触发更新视图
                updateView()
            }
        }
    })
}

// 监听对象属性
function observer(target) {
    if (typeof target !== ‘object‘ || target === null) {
        // 不是对象或数组
        return target
    }
    // 重新定义各个属性(for in 也可以遍历数组)
    for (let key in target) {
        defineReactive(target, key, target[key])
    }
}
// 监听数据
observer(data)
 

此时我们在上面例子代码,没有监听到。


 

此时优化一下,在defineReactive方法里加一层监听。

// 重新定义属性,监听起来
function defineReactive(target, key, value) {
    // 深度监听
    observer(value)
    // 核心 API
    Object.defineProperty(target, key, {
        get() {
            return value
        },
        set(newValue) {
            if (newValue !== value) {

                // 设置新值
                // 注意,value 一直在闭包中,此处设置完之后,再 get 时也是会获取最新的值
                value = newValue

                // 触发更新视图
                updateView()
            }
        }
    })
}

可以深度监听到了。

上面二例子, data.age = {num:21}  可以监听到  而data.age.num = 22 却没有监听到。

此时优化一下,在defineReactive方法中Object.defineProperty里set方法加 深度监听  observer(newValue)加一层监听。

// 重新定义属性,监听起来
function defineReactive(target, key, value) {
    // 深度监听
    observer(value)

    // 核心 API
    Object.defineProperty(target, key, {
        get() {
            return value
        },
        set(newValue) {
            if (newValue !== value) {
                 // 深度监听
                 observer(newValue)

                // 设置新值
                // 注意,value 一直在闭包中,此处设置完之后,再 get 时也是会获取最新的值
                value = newValue

                // 触发更新视图
                updateView()
            }
        }
    })
}

监听数组:

3.几个缺点

1.深度监听,需要递归到底,一次性计算量大(通过上面的例子)
2.
新增属性,监听不到 —— 所以有 Vue.set

3.删除属性,监听不到 —— 所有已 Vue.delete

原文地址:https://www.cnblogs.com/aixue/p/12687115.html

时间: 2024-10-13 01:31:42

Vue2.X监听data变化的核心API—Object.defineProperty详解的相关文章

vue教程2-08 自定义键盘信息、监听数据变化vm.$watch

vue教程2-08 自定义键盘信息 @keydown.up @keydown.enter @keydown.a/b/c.... 自定义键盘信息: Vue.directive('on').keyCodes.ctrl=17; Vue.directive('on').keyCodes.myenter=13; @keydown.a/b/c.... <input type="text" @keydown.c="show"> 自定义键盘信息: Vue.directi

vue.js之过滤器,自定义指令,自定义键盘信息以及监听数据变化

一.监听数据变化 1.监听数据变化有两种,深度和浅度,形式如下: vm.$watch(name,fnCb); //浅度 vm.$watch(name,fnCb,{deep:true}); //深度监视 2.实例用法 2.1-1浅度监听:当点击页面,弹出发生变化了,a的值变为1,b的值变为101 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8">

mvc 缓存 sqlCacheDependency 监听数据变化

对于MVC有Control缓存和Action缓存. 一.Control缓存 Control缓存即是把缓存应用到整个Control上,该Control下的所有Action都会被缓存起来. [OutputCache(Duration = 10)] public class HomeController : Controller { // GET: Home public ActionResult Index() { ViewBag.CurrentTime = DateTime.Now; return

09.VUE学习之watch监听属性变化实现类百度搜索栏功能ajax异步请求数据

cmd下安装axios npm install axios 安装好后,会多出node_modules文件夹 思路: 监听data里的word改变时,发送ajax异步请求数据, 把返回的数据赋值给data里的result,再传给模板里 9.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible&qu

Angular.JS中使用$watch监听模型变化

$watch简单使用 $watch是一个scope函数,用于监听模型变化,当你的模型部分发生变化时它会通知你. $watch(watchExpression, listener, objectEquality); 每个参数的说明如下: watchExpression:监听的对象,它可以是一个angular表达式如'name',或函数如function(){return $scope.name}. listener:当watchExpression变化时会被调用的函数或者表达式,它接收3个参数:n

Android实现后台长期监听时间变化

1.首先我们的目的是长期监听时间变化,事实上应用程序退出. 通过了解我们知道注冊ACTION_TIME_TICK广播接收器能够监听系统事件改变,可是 查看SDK发现ACTION_TIME_TICK广播事件仅仅能动态注冊: Broadcast Action: The current time has changed. Sent every minute. You can not receive this through components declared in manifests, only

$scope.$watch()——监听数据变化

$scope.$watch(watchFn, watchAction, [deepWatch]):监听数据变化,三个参数 --watchFn:监听的对象,一个带有Angular 表达式或者函数的字符串 --watchAction:是一个函数或者表达式,当watchFn 发生变化时会被调用.如果是函数的形式,它将会接收到watchFn 的新旧两个值,以及作用域对象的引用.其函数签名为function(newValue, oldValue, scope) --deepWatch:是否深度监听,可选.

赵雅智_ProviderContent监听数据变化

当程序A在执行insert.update.delete时,通过getContext().getContentResolver().notifyChange(uri, observer)方法来告诉所有注册在该Uri的监听者数据发生改变 参数1uri:注册的uri 参数2observer:注册的监听者 /** * 插入操作 */ @Override public Uri insert(Uri uri, ContentValues values) { if (uriMatcher.match(uri)

如何使用NodeJs来监听文件变化

1.前言 在我们调试修改代码的时候,每修改一次代码,哪怕只是很小的修改,我们都需要手动重新build文件,然后再运行代码,看修改的效果,这样的效率特别低,对于开发者来说简直不能忍. 2.构建自动编译工具 如何使用nodeJs来监听文件变化,一旦源文件修改保存时,自动运行build过程.比如当你写CoffeeScript文件或SASS文件时,保存之后可即时生成对应的JS或CSS. 基于Node.JS的侦听文件夹改变的模块有很多. a .  fs.watch.Node.JS的文件系统也可侦听某个目录