daily-share
daily-share copied to clipboard
数据双休绑定,数据劫持,数据代理(2020-2-1)
数据双休绑定,数据劫持,数据代理
function Lesson(options = {} ) {
this.$options = options
var data = this._data = this.$options.data
// 数据观察
observe(data)
// 数据代理到this
for(let key in data) {
Object.defineProperty(this, key, {
enumerable: true,
get() {
return this._data[key]
},
set(newVal) {
if (this._data[key] === newVal ) {
return
}
this._data[key] = newVal
}
})
}
}
function observe(data) {
// 判断data是不是一个对象
if (type data !== 'object') return
return new Observe(data)
}
function Observe(data) { // 数据双向绑定的逻辑
for(let key in data) {
let val = data[key]
observe(val) // 观察
Object.defineProperty(data, key, {
enumerable: true,
get() {
return val
},
set(newVal) {
if (val === newVal ) {
return
}
val = newVal
observe(newVal)
}
})
}
}
编译的一个过程
function Lesson(options= {}) {
this.$options = options
var data = this._data = this.$options.data
observe(data)
for(let key in data) {
Object.defineProperty(this, key, {
enumerable: true,
get() {
return this._data[key]
},
set(newVal) {
if (this._data[key] === newVal) return
this._data[key] = newVal
}
})
}
//这里做编译
new Compile(options.el, this)
}
function observe(data) {
if (typeof data !== 'object' ) return
return new Observe(data)
}
function Observe(data) {
// 处理具体的Objcet.defineProperty的逻辑
for (let key in data) {
let val = data[key]
observe(val)
Object.defineProperty(data, key, {
enumerable: true,
get() {
return val
},
set(newVal) {
if (val === newVal) return
val = newVal
observe(newVal)
}
})
}
}
function Compile(el, vm) {
vm.$el = document.querySelector(el)
let fragement = document.createDocumentFragment()
while( child = vm.$el.firstChild) {
fragement.appendChild(child)
}
// 处理fargement
// console.log(Array.from(fragement.firstChild))
// let arr = Array.from(fragement.firstChild)
replace(fragement)
function replace(fragement) {
Array.from(fragement.childNodes).forEach( node => {
let text = node.textContent
let reg = /\{\{(.*)\}\}/
// console.log(node.nodeType)
if (node.nodeType === 3 && reg.test(text)) {
// console.log(RegExp.$1)
let arr = RegExp.$1.split('.')
let val = vm
arr.forEach( k => {
val = val[k]
})
node.textContent = text.replace(reg, val)
}
if (node.childNodes) {
replace(node)
}
})
}
vm.$el.appendChild(fragement)
}
新增发布订阅模式
function Lesson(options= {}) {
this.$options = options
var data = this._data = this.$options.data
observe(data)
for(let key in data) {
Object.defineProperty(this, key, {
enumerable: true,
get() {
return this._data[key]
},
set(newVal) {
if (this._data[key] === newVal) return
this._data[key] = newVal
}
})
}
//这里做编译
new Compile(options.el, this)
}
function observe(data) {
if (typeof data !== 'object' ) return
return new Observe(data)
}
function Observe(data) {
// 处理具体的Objcet.defineProperty的逻辑
let dep = new Dep()
for (let key in data) {
let val = data[key]
observe(val)
Object.defineProperty(data, key, {
enumerable: true,
get() {
Dep.target && dep.addSubs(Dep.target)
return val
},
set(newVal) {
if (val === newVal) return
val = newVal
observe(newVal)
dep.notify()
}
})
}
}
function Compile(el, vm) {
vm.$el = document.querySelector(el)
let fragement = document.createDocumentFragment()
while( child = vm.$el.firstChild) {
fragement.appendChild(child)
}
// 处理fargement
// console.log(Array.from(fragement.firstChild))
// let arr = Array.from(fragement.firstChild)
replace(fragement)
function replace(fragement) {
Array.from(fragement.childNodes).forEach( node => {
let text = node.textContent
let reg = /\{\{(.*)\}\}/
// console.log(node.nodeType)
if (node.nodeType === 3 && reg.test(text)) {
// console.log(RegExp.$1)
let arr = RegExp.$1.split('.')
let val = vm
arr.forEach( k => {
val = val[k]
})
new Watcher(vm, RegExp.$1,function(newVal) {
node.textContent = text.replace(reg, newVal)
})
node.textContent = text.replace(reg, val)
}
if (node.childNodes) {
replace(node)
}
})
}
vm.$el.appendChild(fragement)
}
function Dep() {
this.subs = []
}
Dep.prototype.addSubs = function(fn) {
this.subs.push(fn)
}
Dep.prototype.notify = function() {
// console.log(this.subs)
this.subs.forEach( fn => {
// console.log()
fn.update()
} )
}
function Watcher(vm, exp, fn) {
this.vm = vm
this.exp = exp
this.fn = fn
Dep.target = this
let val = vm
let arr = exp.split('.')
arr.forEach( k => {
val = val[k]
})
Dep.target = null
}
Watcher.prototype.update = function() {
let val = this.vm
let arr = this.exp.split('.')
arr.forEach( k => {
val = val[k]
})
this.fn(val)
}
数据双向绑定
function Lesson(options= {}) {
this.$options = options
var data = this._data = this.$options.data
observe(data)
for(let key in data) {
Object.defineProperty(this, key, {
enumerable: true,
get() {
return this._data[key]
},
set(newVal) {
if (this._data[key] === newVal) return
this._data[key] = newVal
}
})
}
//这里做编译
new Compile(options.el, this)
}
function observe(data) {
if (typeof data !== 'object' ) return
return new Observe(data)
}
function Observe(data) {
// 处理具体的Objcet.defineProperty的逻辑
let dep = new Dep()
for (let key in data) {
let val = data[key]
observe(val)
Object.defineProperty(data, key, {
enumerable: true,
get() {
Dep.target && dep.addSubs(Dep.target)
return val
},
set(newVal) {
if (val === newVal) return
val = newVal
observe(newVal)
dep.notify()
}
})
}
}
function Compile(el, vm) {
vm.$el = document.querySelector(el)
let fragement = document.createDocumentFragment()
while( child = vm.$el.firstChild) {
fragement.appendChild(child)
}
// 处理fargement
// console.log(Array.from(fragement.firstChild))
// let arr = Array.from(fragement.firstChild)
replace(fragement)
function replace(fragement) {
Array.from(fragement.childNodes).forEach( node => {
let text = node.textContent
let reg = /\{\{(.*)\}\}/
// console.log(node.nodeType)
if (node.nodeType === 3 && reg.test(text)) {
// console.log(RegExp.$1)
let arr = RegExp.$1.split('.')
let val = vm
arr.forEach( k => {
val = val[k]
})
new Watcher(vm, RegExp.$1,function(newVal) {
node.textContent = text.replace(reg, newVal)
})
node.textContent = text.replace(reg, val)
}
if (node.nodeType === 1) {
// 表示该元素是元素节点
// console.log(node.attributes)
let nodeAttrs = node.attributes
Array.from(nodeAttrs).forEach( attr => {
// console.log(attr)
let name = attr.name
let exp = attr.value
if (name.indexOf('v-') === 0) {
node.value = vm[exp]
}
new Watcher(vm, exp, function(newVal) {
node.value = newVal
})
node.addEventListener('input', function(e) {
let value = e.target.value
vm[exp] = value
})
})
}
if (node.childNodes) {
replace(node)
}
})
}
vm.$el.appendChild(fragement)
}
function Dep() {
this.subs = []
}
Dep.prototype.addSubs = function(fn) {
this.subs.push(fn)
}
Dep.prototype.notify = function() {
// console.log(this.subs)
this.subs.forEach( fn => {
// console.log()
fn.update()
} )
}
function Watcher(vm, exp, fn) {
this.vm = vm
this.exp = exp
this.fn = fn
Dep.target = this
let val = vm
let arr = exp.split('.')
arr.forEach( k => {
val = val[k]
})
Dep.target = null
}
Watcher.prototype.update = function() {
let val = this.vm
let arr = this.exp.split('.')
arr.forEach( k => {
val = val[k]
})
this.fn(val)
}
其中关键代码
if (node.nodeType === 1) {
// 表示该元素是元素节点
// console.log(node.attributes)
let nodeAttrs = node.attributes
Array.from(nodeAttrs).forEach( attr => {
// console.log(attr)
let name = attr.name
let exp = attr.value
if (name.indexOf('v-') === 0) {
node.value = vm[exp]
}
new Watcher(vm, exp, function(newVal) {
node.value = newVal
})
node.addEventListener('input', function(e) {
let value = e.target.value
vm[exp] = value
})
})
}