Vue响应式主要包含:
Object.defineProperty
实现数据劫持Proxy
实现数据劫持{
{}}
v-bind
, v-on
, v-model
, v-for
,v-if
vdom
,把vdom
渲染为普通dom数据变化时能自动更新视图,就是数据响应式
Vue2使用Object.defineProperty
实现数据变化的检测
new Vue()
⾸先执⾏初始化,对data
执⾏响应化处理,这个过程发⽣在Observer
中data
中获取并初始化视图,这个过程发⽣在 Compile
中Watcher实例
,将来对应数据变化时,Watcher会调⽤更新函数data
的某个key
在⼀个视图中可能出现多次,所以每个key
都需要⼀个管家Dep来管理多个 Watcher
data
中数据⼀旦发⽣变化,会⾸先找到对应的Dep
,通知所有Watcher
执⾏更新函数CVue
:自定义Vue类 Observer
:执⾏数据响应化(分辨数据是对象还是数组) Compile
:编译模板,初始化视图,收集依赖(更新函数、 watcher创建) Watcher
:执⾏更新函数(更新dom) Dep
:管理多个Watcher实例,批量更新
参考 前端手写面试题详细解答
observe
: 遍历vm.data
的所有属性,对其所有属性做响应式,会做简易判断,创建Observer实例
进行真正响应式处理
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>cvuetitle>
<script src="./cvue.js">script>
head>
<body>
<div id="app">
<p>{
{ count }}p>
div>
<script>
const app = new CVue({
el: '#app', data: {
count: 0
} }) setInterval(() => {
app.count +=1
}, 1000); script>
body>
html>
data
执⾏响应化处理// 自定义Vue类
class CVue {
constructor(options) {
this.$options = options
this.$data = options.data
// 响应化处理
observe(this.$data)
}
}
// 数据响应式, 修改对象的getter,setter
function defineReactive(obj, key, val) {
// 递归处理,处理val是嵌套对象情况
observe(val)
Object.defineProperty(obj, key, {
get() {
return val
},
set(newVal) {
if(val !== newVal) {
console.log(`set ${
key}:${
newVal}, old is ${
val}`)
val = newVal
// 继续进行响应式处理,处理newVal是对象情况
observe(val)
}
}
})
}
// 遍历obj,对其所有属性做响应式
function observe(obj) {
// 只处理对象类型的
if(typeof obj !== 'object' || obj == null) {
return
}
// 实例化Observe实例
new Observe(obj)
}
// 根据传入value的类型做相应的响应式处理
class Observe {
constructor(obj) {
if(Array.isArray(obj