vue响应式原理实现:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<input id="index--input" value="">
<p id="index--p"></p>
</body>
<script type="text/javascript">
function Dep() {
this.subs = []
this.addSub = function (cb) {
this.subs.push(cb)
}
this.notify = function (value) {
this.subs.forEach(cb => {
cb(value)
})
}
}
function defineReactive(obj, key, value) {
let dep = new Dep()
Object.defineProperty(obj, key, {
enumerable: true,
configurable: true,
get() {
console.log('get was called')
if(window.cb){
dep.addSub(window.cb)
}
return value
},
set(v) {
console.log('set was called')
if(v === value){
return
}
value = v
dep.notify(v)
}
})
}
function observer(obj) {
for(let key in obj){
let value = obj[key]
if(typeof value === 'object'){
observer(value)
}
defineReactive(obj, key, value)
}
}
function Watcher(obj, key, cb) {
window.cb = cb
let value = obj[key]
window.cb = null
}
obj = {
name: 'jack',
age: 23,
value: '',
address: {
country: 'usa',
county: 'newYork'
}
}
observer(obj)
new Watcher(obj, 'value', function (value) {
document.getElementById('index--p').innerHTML = value
})
new Watcher(obj, 'name', function (value) {
alert(value)
})
window.onload = function () {
window.addEventListener('input', function (event) {
obj.value = event.target.value
})
}
</script>
</html>
← vue的生命周期 vue响应式原理简单实现 →