<!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>Document</title>
</head>
<body>
<div class="text" v-text="text"></div>
<div class="html" v-text="html"></div>
<script>
function Vue (options) {
let data = options.data
let computed = options.computed
initData(this, data)
initComputed(this, computed)
}
function initData (vm, data) {
// Object.keys() js方法返回对象的属性名
let keys = Object.keys(data)
keys.forEach(key => {
observer(vm, key, data[key])
})
}
function Dep () {
this.subs = []
}
Dep.target = null
function observer (vm, key, value) {
let dep = new Dep()
let initVal = value
// Object.defineProperty(obj, prop, descriptor)直接在一个对象上定义一个新属性,或者修改一个已经存在的属性, 并返回这个对象
// obj 需要定义属性的对象。
// prop 需被定义或修改的属性名。
// descriptor 需被定义或修改的属性的描述符。
Object.defineProperty(vm, key, {
get () {
debugger
if (Dep.target) {
dep.subs.push(Dep.target)
}
return initVal
},
set (val) {
debugger
initVal = val
for(let key in dep.subs) {
dep.subs[key].call(vm)
}
}
})
}
function initComputed (vm, computeds) {
let keys = Object.keys(computeds)
keys.forEach(key => {
watcher(vm, computeds[key])
})
}
function watcher (vm, fun) {
Dep.target = fun
fun.call(vm)
Dep.target = null
}
let vm = new Vue({
data: {
text: 123,
html: '<a href="http://www.baidu.com">456</a>'
},
// 应该是watcher的功能 不代表计算属性
computed: {
text () {
// debugger
document.querySelector('.text').innerText = this.text
},
html () {
document.querySelector('.html').innerHTML = this.html
}
}
})
</script>
</body>
</html>