IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> MVVM理解 ——(2)数据劫持 -> 正文阅读

[JavaScript知识库]MVVM理解 ——(2)数据劫持

  • 数据劫持 – 在使用或者设置某的对象的属性的时候,通过一系列的代码拦截此次的此次的行为。即可以在赋值过程中添加一些操作或者修改返回的结果。

  • 例如:
    对象设置一个 a = {name: 1};

    在进行赋值操作a.name = 2 的过程中,可以拦截赋值的过程,添加一些其他的操作。

    在获取 a.name 的时,可以改变其最终的结果。
    具体操作还是需要使用 Object.defineProperty(obj, key, {})

具体操作参考vue 的数据劫持过程。如下:

  • 明确需求 – 劫持所有我们需要或者说是可能更改的数据即 data
	let vue = new Vue({
		el: '#app',
		data: {
			name: 1,
			home: {
				num: 2,
				address: 3
			}
		}
	})
  • 实现Vue 类
    联系上一章,劫持所有的数据,即创建一个新的类,使其所有的key都拥有getter()setter() 方法.
function Vue(options = {}) {
	// 将data的值放在 Vue._data 上
	let data = this._data = options.data
	
	// 观察对象 给对象增加Object.defineproprety
	obseve(data);
}
  • 实现observe()方法
	
	let observe = function (data) {
	// 加层判断,非object return
	if(typeof data !== Object) return
		return new Observe(data)
	}

// 循环遍历 为data 添加 Objec.defineProperty

	function Observe(data) {
		// 循环data的key 
		Object.keys(data).forEach(key => {
			let val = data[key]
			Object.definePropety(data, key, {
				enumerable: true,
				get() {
					return val
				},
				set(newVal) {
					if (newVal === val) return
					val = newVal
				}
			})
		})
	}

  • 注意, 因为data是深层的, 需要每一层都进行数据劫持,于是写成递归函数。

function Observe(data) {
		// 循环data的key 
		Object.keys(data).forEach(key => {
			let val = data[key]
// 此处对val 进行递归
		observe(val)

			Object.definePropety(data, key, {
				enumerable: true,
				get() {
					return val
				},
				set(newVal) {
					if (newVal === val) return
					val = newVal
				}
			})
		})
	}
  • 这样这个数据劫持的功能就实现了。

  • 另外,在实现时出了点问题:此处记录下。
    其中的Object.keys('adasd') 在es5 中是不执行的,但是在es2015 即es6中执行,返回的是该字符串的字符index值。
    参考mdn:

    Object.keys("foo");
    // TypeError: "foo" is not an object (ES5 code)
    
    Object.keys("foo");
    // ["0", "1", "2"]                   (ES2015 code)
    
  • 简而言之
    数据劫持就是将对象中的每个 key 添加getter 和setter 方法,具体怎么添加,主要是用的Object.defineProperty()。再使用递归的思路,对一个对象深层次的添加这些属性。

差不多就这样子吧。敲一遍就明白了。

  • index.html/ vue.js demo代码

index.html

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>MVVM 数据劫持</title>
</head>
<script src="./vue.js"></script>

<body>
  <div id="app">
    {{a.name}}
  </div>

</body>
<script>
  let data = {
    name: 1,
    age: 23,
    home: {
      address: "aqweqwe",
      num: 333
    }
  }
  let vue = new Vue({
    el: '#app',
    data
  })
  console.log(vue)
</script>
</html>

vue.js 其中遍历data的时候有两种写法,仅供参考。


function Vue(options = {}) {
  this.$options = options;
  let data = (this._data = this.$options.data);

  observe(data);
}

function observe(data) {
    console.log('wwwwww', data);
    return new Observe(data);
  }
// 观察对象 给对象增加Object.defineproprety
function Observe(data) { // 写主要的逻辑

    // 业务是 将每个data上的属性都绑定 Object.defineproperty方法
    Object.keys(data).forEach(key => {

                let val = data[key];
        console.log('--------', val);
        observe(val);

        Object.defineProperty(data, key, {
            enumerable: true,
            set(newVal) {
                if (newVal == val) return 
                val = newVal
            },
            get() {
                return val
            }
        })
      })
    
    
    // for (let key in data) {
    //     let val = data[key];
    //     console.log('--------', val);
    //     // 监听val 如果是对象类型 再次进行递归操作
    //     // observe(val);
        
    //     Object.defineProperty(data, key, {
    //         enumerable: true,
    //         set(newVal) {
    //             if (newVal == val) return 
    //             val = newVal
    //         },
    //         get() {
    //             return val
    //         }
    //     })

    // }

}




  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-07-25 11:33:33  更:2021-07-25 11:35:20 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/2 17:13:52-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码