手写Vue响应式实现
Vue响应式
代码仓库地址:https://gitee.com/jiailing/lagou-fed/tree/master/fed-e-task-03-01/code/Vue/jalVue
一、数据驱动
1.数据响应式
- 数据模型仅仅是普通的JavaScript对象,而当我们修改数据时,视图会进行更新,避免了繁琐的DOM操作,提高开发效率
2. 双向绑定
-
数据改变,视图改变;视图改变,数据也随之改变
-
我们可以使用v-modle在表单元素上创建双向数据数据
3. 数据驱动是Vue最独特的特性之一
- 开发过程中仅需要关注数据本身,不需要关心数据是如何渲染到视图
二、数据响应式的核心原理
1. Vue 2.x
- Vue 2.x深入响应式原理
- Object.defineProperty
- 浏览器兼容IE8以上(不兼容IE8)
<!DOCTYPE html>
<html lang="cn">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>defineProperty</title>
</head>
<body>
<div id="app">
hello
</div>
<script>
// 模拟 Vue 中的 data 选项
let data = {
msg: 'hello'
}
// 模拟 Vue 的实例
let vm = {
}
// 数据劫持:当访问或者设置 vm 中的成员的时候,做一些干预操作
Object.defineProperty(vm, 'msg', {
// 可枚举(可遍历)
enumerable: true,
// 可配置(可以使用 delete 删除,可以通过 defineProperty 重新定义)
configurable: true,
// 当获取值的时候执行
get () {
console.log('get: ', data.msg)
return data.msg
},
// 当设置值的时候执行
set (newValue) {
console.log('set: ', newValue)
if (newValue === data.msg) {
return
}
data.msg = newValue
// 数据更改,更新 DOM 的值
document.querySelector('#app').textContent = data.msg
}
})
// 测试
vm.msg = 'Hello World'
console.log(vm.msg)
</script>
</body>
</html>
-
如果有一个对象中多个属性需要被转换getter、setter 如何处理?
-
遍历这个对象的所有属性
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>defineProperty 多个成员</title> </head> <body> <div id="app"> hello </div> <script> // 模拟 Vue 中的 data 选项 let data = { msg: 'hello', count: 10 } // 模拟 Vue 的实例 let vm = { } proxyData(data) function proxyData(data) { // 遍历 data 对象的所有属性 Object.keys(data).forEach(key => { // 把 data 中的属性,转换成 vm 的 setter/setter Object.defineProperty(vm, key, { enumerable: true, configurable: true, get () { console.log(
-