响应式原理实现
响应式函数的封装
let reactiveFns = []
function watchFn(fn) {
reactiveFns.push(fn)
}
const obj = {
name: 'Fhup',
age: 18
}
watchFn(function obj1Fn(){
console.log(obj.name);
})
watchFn(function obj2Fn(){
const newName = obj.name
console.log(newName);
})
obj.name = 123
reactiveFns.forEach(fn => {
fn()
})
依赖收集类的封装
class Depend {
constructor() {
this.reactiveFns = []
}
addDepend(fn) {
this.reactiveFns.push(fn)
}
notify() {
this.reactiveFns.forEach(fn => {
fn()
})
}
}
const depend = new Depend()
function watchFn(fn) {
depend.addDepend(fn)
}
const obj = {
name: 'Fhup',
age: 18
}
watchFn(function obj1Fn(){
console.log(obj.name);
})
watchFn(function obj2Fn(){
const newName = obj.name
console.log(newName);
})
obj.name = 123
depend.notify()
自动监听对象变化
class Depend {
constructor() {
this.reactiveFns = []
}
addDepend(fn) {
this.reactiveFns.push(fn)
}
notify() {
this.reactiveFns.forEach(fn => {
fn()
})
}
}
const depend = new Depend()
function watchFn(fn) {
depend.addDepend(fn)
}
const obj = {
name: 'Fhup',
age: 18
}
const objProxy = new Proxy(obj, {
get(target, key, receiver) {
return Reflect.get(target, key, receiver)
},
set(target, key, newValue, receiver) {
depend.notify()
Reflect.set(target, key, newValue, receiver)
}
})
watchFn(function(){
console.log(objProxy.name);
})
watchFn(function(){
const newName = objProxy.name
console.log(newName);
})
objProxy.name = 'xxx'
objProxy.name = 'xxx'
objProxy.name = 'xxx'
依赖收集的管理
class Depend {
constructor() {
this.reactiveFns = []
}
addDepend(fn) {
this.reactiveFns.push(fn)
}
notify() {
this.reactiveFns.forEach(fn => {
fn()
})
}
}
const depend = new Depend()
function watchFn(fn) {
depend.addDepend(fn)
}
const targetMap = new WeakMap()
function getDepend(target, key) {
let map = targetMap.get(target)
if(!map) {
map = new Map()
targetMap.set(target, map)
}
let depend = map.get(key)
if(!depend) {
depend = new Depend()
map.set(key, depend)
}
return depend
}
const obj = {
name: 'Fhup',
age: 18
}
const objProxy = new Proxy(obj, {
get(target, key, receiver) {
return Reflect.get(target, key, receiver)
},
set(target, key, newValue, receiver) {
Reflect.set(target, key, newValue, receiver)
const depend = getDepend(target, key)
depend.notify()
}
})
watchFn(function(){
console.log(objProxy.name);
})
watchFn(function(){
const newName = objProxy.name
console.log(newName);
})
objProxy.name = 'xxx'
objProxy.name = 'xxx'
objProxy.name = 'xxx'
正确的收集依赖
class Depend {
constructor() {
this.reactiveFns = []
}
addDepend(fn) {
this.reactiveFns.push(fn)
}
notify() {
this.reactiveFns.forEach(fn => {
fn()
})
}
}
let activeFn = null
function watchFn(fn) {
activeFn = fn
fn()
activeFn = null
}
const targetMap = new WeakMap()
function getDepend(target, key) {
let map = targetMap.get(target)
if(!map) {
map = new Map()
targetMap.set(target, map)
}
let depend = map.get(key)
if(!depend) {
depend = new Depend()
map.set(key, depend)
}
return depend
}
const obj = {
name: 'Fhup',
age: 18
}
const objProxy = new Proxy(obj, {
get(target, key, receiver) {
const depend = getDepend(target, key)
depend.addDepend(activeFn)
return Reflect.get(target, key, receiver)
},
set(target, key, newValue, receiver) {
Reflect.set(target, key, newValue, receiver)
const depend = getDepend(target, key)
depend.notify()
}
})
watchFn(function(){
console.log(objProxy.name, objProxy.age, '```');
})
watchFn(function(){
const newName = objProxy.name
console.log(newName, '------');
})
console.log('--------------------');
objProxy.age = 'xxx'
对Depend类的重构
let activeFn = null
class Depend {
constructor() {
this.reactiveFns = new Set()
}
depend() {
if(activeFn) {
this.reactiveFns.add(activeFn)
}
}
notify() {
this.reactiveFns.forEach(fn => {
fn()
})
}
}
function watchFn(fn) {
activeFn = fn
fn()
activeFn = null
}
const targetMap = new WeakMap()
function getDepend(target, key) {
let map = targetMap.get(target)
if(!map) {
map = new Map()
targetMap.set(target, map)
}
let depend = map.get(key)
if(!depend) {
depend = new Depend()
map.set(key, depend)
}
return depend
}
const obj = {
name: 'Fhup',
age: 18
}
const objProxy = new Proxy(obj, {
get(target, key, receiver) {
const depend = getDepend(target, key)
depend.depend()
return Reflect.get(target, key, receiver)
},
set(target, key, newValue, receiver) {
Reflect.set(target, key, newValue, receiver)
const depend = getDepend(target, key)
depend.notify()
}
})
watchFn(function(){
console.log(objProxy.age, '```');
console.log(objProxy.age, '```');
console.log(objProxy.age, '```');
})
console.log('--------------------');
objProxy.age = 3
对象的响应式操作Vue3
let activeFn = null
class Depend {
constructor() {
this.reactiveFns = new Set()
}
depend() {
if(activeFn) {
this.reactiveFns.add(activeFn)
}
}
notify() {
this.reactiveFns.forEach(fn => {
fn()
})
}
}
function watchFn(fn) {
activeFn = fn
fn()
activeFn = null
}
const targetMap = new WeakMap()
function getDepend(target, key) {
let map = targetMap.get(target)
if(!map) {
map = new Map()
targetMap.set(target, map)
}
let depend = map.get(key)
if(!depend) {
depend = new Depend()
map.set(key, depend)
}
return depend
}
function reactive(obj) {
return new Proxy(obj, {
get(target, key, receiver) {
const depend = getDepend(target, key)
depend.depend()
return Reflect.get(target, key, receiver)
},
set(target, key, newValue, receiver) {
Reflect.set(target, key, newValue, receiver)
const depend = getDepend(target, key)
depend.notify()
}
})
}
const obj = {
name: 'Fhup',
age: 18
}
const info = {
address: '宝鸡市',
height: 1.88
}
const infoProxy = reactive(info)
const objProxy = reactive(obj)
watchFn(() => {
console.log(infoProxy.address, '~~~~~~~');
})
watchFn(() => {
console.log(objProxy.name, '`````````');
})
infoProxy.address = '北京市'
objProxy.name = 'xxx'
对象的响应式操作Vue2
let activeFn = null
class Depend {
constructor() {
this.reactiveFns = new Set()
}
depend() {
if(activeFn) {
this.reactiveFns.add(activeFn)
}
}
notify() {
this.reactiveFns.forEach(fn => {
fn()
})
}
}
function watchFn(fn) {
activeFn = fn
fn()
activeFn = null
}
const targetMap = new WeakMap()
function getDepend(target, key) {
let map = targetMap.get(target)
if(!map) {
map = new Map()
targetMap.set(target, map)
}
let depend = map.get(key)
if(!depend) {
depend = new Depend()
map.set(key, depend)
}
return depend
}
function reactive(obj) {
Object.keys(obj).forEach(key => {
let value = obj[key]
Object.defineProperty(obj, key, {
get() {
const depend = getDepend(obj, key)
depend.depend()
return value
},
set(newValue) {
value = newValue
const depend = getDepend(obj, key)
depend.notify()
}
})
})
return obj
}
const obj = {
name: 'Fhup',
age: 18
}
const info = {
address: '宝鸡市',
height: 1.88
}
const infoProxy = reactive(info)
const objProxy = reactive(obj)
watchFn(() => {
console.log(infoProxy.address, '~~~~~~~');
})
watchFn(() => {
console.log(objProxy.name, '`````````');
})
infoProxy.address = '北京市'
objProxy.name = 'xxx'