<body>
<div id="app">
<h2 v-html='salary'></h2>
<input type="text" v-model='salary'>
</div>
<script>
// 定义事件中心的构造函数
function EventCenter () {
this.guanjia = {}
}
EventCenter.prototype.$on = function(eventname,fn){
if(this.guanjia[eventname]) {
this.guanjia[eventname].push(fn)
}else{
this.guanjia[eventname] = []
this.guanjia[eventname].push(fn)
}
}
EventCenter.prototype.$emit = function (eventname){
if(this.guanjia[eventname]){
this.guanjia[eventname].forEach(fn=>{
fn()
})
}
}
// 创建事件中心实例
var ec = new EventCenter()
// 定义构造函数
function MVVM (options) {
let {el,data} = options
for (let key in data) {
Object.defineProperty(this, key,{
// 因为this指向实例对象,所以属性都挂载到了实例对象下,直接用this.salary就能访问data下的salary
get(){
return data[key]
},
set (val) {
if(val !== data[key]){
data[key] = val
// 实现数据到视图;值改变,触发事件中心guanjia[key]下的所有函数
ec.$emit(key)
}
}
})
}
// 获取当前节点及遍历子节点
let rootDom = document.querySelector(el)
Array.from(rootDom.children).forEach(node=>{
if(node.hasAttribute('v-html')){
let attrVal = node.getAttribute('v-html')
// 给事件中心guanjia[v-html] push 函数() => { node.innerHTML = this[attrVal]}
ec.$on(attrVal, () => {
node.innerHTML = this[attrVal]
})
}
if(node.hasAttribute('v-model')){
let attrVal = node.getAttribute('v-model')
ec.$on(attrVal, () => {
node.value = this[attrVal]
})
// 实现视图到数据
node.addEventListener('input', e => {
// 1) 获取当前的输入值
let val = e.target.value
// 2) 把值保存到数据项中
this[attrVal] = val
})
}
})
}
const vm = new MVVM({
el:'#app',
data:{
salary:1500
}
})
</script>
</body>
vue2——实现MVVM
最新推荐文章于 2023-02-02 15:02:19 发布