2.v-if

这篇博客探讨了Vue.js中模板条件渲染(v-if/v-show)和事件处理(@click)的使用。通过示例代码展示了如何根据数据状态控制元素显示,并通过点击事件切换显示状态。同时,还介绍了一个名为Vif的自定义实现,用于处理数据变化与视图更新的关系。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

待续…

<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))
    }
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

柳晓黑胡椒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值