待续…
<div id="app">
<div class="box-wrapper">
<div class="box box1" v-if="boxShow1">BOX 1</div>
<div class="box box2" v-show="boxShow2">BOX 2</div>
<div class="box box3" v-if="boxShow3">BOX 3</div>
<div class="box box4" v-show="boxShow4">BOX 4</div>
</div>
<button @click="showBox1">BOX 1</button>
<button @click="showBox2">BOX 2</button>
<button @click="showBox3">BOX 3</button>
<button @click="showBox4">BOX 4</button>
</div>
<script src="./index.js"></script>
<script>
new Vif({
el:'#app',
data:{
boxShow1:true,
boxShow2:false,
boxShow3:false,
boxShow4:false
},
methods:{
showBox1(){
// console.log(this)
console.log('click box 1')
this.boxShow1 = !this.boxShow1 //先访问再赋值
},
showBox2(){
console.log('click box 2')
this.boxShow2 = !this.boxShow2
},
showBox3(){
console.log('click box 3')
this.boxShow3 = !this.boxShow3
},
showBox4(){
console.log('click box 4')
this.boxShow4 = !this.boxShow4
},
}
})
</script>
index.js
class Vif {
constructor(options) {
const { el, data, methods } = options
this.el = document.querySelector(el)
this.data = data
this.methods = methods
this.showPool = new Map()
this.eventPool = new Map()
this.init()
}
init() {
this.initData()
this.initDOM(this.el)
this.initView(this.showPool)
this.initEvent(this.eventPool)
console.log(this.showPool)
console.log(this.eventPool)
}
initData() {
for (let key in this.data) {
// this.boxShow1 -> this.data.boxShow1
Object.defineProperty(this, key, {
get() {
console.log('查看数据', key, this.data[key])
return this.data[key]
},
set(newVal) {
console.log("设置数据", key, newVal)
this.data[key] = newVal
this.domChange(key,this.showPool)
}
})
}
}
initDOM(el) {
const _childNodes = el.childNodes
// console.log(_childNodes)
if (!_childNodes.length) { return }
_childNodes.forEach((node) => {
if (node.nodeType === 1) {
const Vif = node.getAttribute('v-if')
const VShow = node.getAttribute('v-show')
const VEvent = node.getAttribute('@click')
if (Vif) {
this.showPool.set(node, {
type: "if",
show: this.data[Vif],
data: Vif
})
} else if (VShow) {
this.showPool.set(node, {
type: 'show',
show: this.data[VShow],
data: VShow
})
}
if (VEvent) {
this.eventPool.set(node, this.methods[VEvent])
}
}
this.initDOM(node)
})
}
initView(showPool){
this.domChange(null,showPool)
}
domChange(data,showPool){
if(!data){
for(let [i,ch] of showPool){
switch(ch.type){
case 'if':
// 把带有if的节点替换为 注释节点
ch.comment = document.createComment('v-if')
console.log(ch)
!ch.show && i.parentElement.replaceChild(ch.comment,i)
break;
case 'show':
!ch.show && (i.style.display ="none") //隐藏show
break
default:
break
}
}
return
}
for(let [i,ch] of showPool){
if(ch.data === data){
switch(ch.type){
case 'if':
ch.show ? i.parentElement.replaceChild(ch.comment,i)
: ch.comment.parentElement.replaceChild(i,ch.comment)
ch.show = !ch.show
break
case 'show':
console.log(i.style.display)
ch.show ? (i.style.display='none')
: (i.removeAttribute('style'))
ch.show = !ch.show
break
default:
break
}
}
}
}
initEvent(eventPool){
for(let [i,ch] of eventPool){
i.addEventListener('click',ch.bind(this))
}
}
}