美文网首页
Vue 之 v-if 学习

Vue 之 v-if 学习

作者: 人话博客 | 来源:发表于2019-01-19 00:35 被阅读0次

    我们都知道,v-if指令是删除和新建dom(组件对应的本质上也就是一堆DOM+js+css).
    对于一般的HTML元素来说,是如此.

     <div id='app'>
        <h1 v-if="showHTML">v-if 删除和修改普通的dom元素</h1>
        <button @click="showHTML=!showHTML">普通的HTML元素使用v-if</button>
      </div>
      
    var app = new Vue({
        el: '#app',
        data: {
          showHTML: true
        }
    }
    

    结果:

    v-if作用于普通的HTML元素

    这没什么毛病,一般讲这些例子,都会这么写的.

    虽然,我们拿到不到普通的 HTML 元素的声明周期钩子,但从 Elements 开发工具选项卡可以看到的结果.

    但实际上,这有一个巨大的坑!!!

    2.v-if 用于组件

    由于,我们拿不到普通DOM的声明周期钩子(上述的h1标签.)
    仅从浏览器开发工具里查看到DOM元素确实是没有了.
    所以,就认定了:

    只要使用的 v-if 指令.那么就是对DOM元素的删除或者新建.

    2.1 v-if 使用在组件的标签上.

    组件,我们拿得到它们的生命周期钩子函数.

    我们定义一个HelloWorld的组件.

    并在组件标签上使用v-if来决定组件的新建或者删除.

     <div id='app'>
     // v-if 在 组件的标签上
        <hello-world v-if="showHelloWorld"></hello-world>
        <button @click="showHelloWorld=!showHelloWorld">v-if在组件的标签上</button>
      </div>
    
      <template id="helloworld">
        <div top>
          <h1>hello world</h1>
        </div>
      </template>
      
      
      
       Vue.component('HelloWorld', {
        template: '#helloworld',
        created() {
          console.log('helloworld created!')
        },
        destroyed() {
          console.log('helloworld destroyed!')
        },
      })
      var app = new Vue({
        el: '#app',
        data: {
          showHelloWorld: true
        }
      })
    

    结果:

    v-if作用于组件

    好像没什么问题诶.v-if就是能正确的触发dom的新建和删除.所以,对应的就触发了组件的 created 和 destroyed 钩子函数!!


    2.2 v-if 作用在组件内部的顶级HTML元素上.

    定义第一个HelloVue组件.

    <div id='app'>
        <hello-vue ref="child"></hello-vue>
        <button @click="toggle">v-if在组件内部的顶级HTML元素上</button>
      </div>
      <template id='hellovue'>
        <div top v-if='showSelf'>
          <h1>hello vue</h1>
        </div>
      </template>
      
     Vue.component('HelloVue', {
        template: '#hellovue',
        data() {
          return {
            showSelf: true
          }
        },
        methods: {
          toggle() {
            this.showSelf = !this.showSelf
          }
        },
        created() {
          console.log('hello vue created!')
        },
        destroyed() {
          console.log('hello vue destroyed!')
        },
      })
    
      var app = new Vue({
        el: '#app',
        methods: {
          toggle() {
            // console.log(this.$refs.child)
            this.$refs.child.toggle()
          }
        }
      })
    

    先看控制台输出:

    v-if 总用于组件内部的HTML

    发现在组件内部即使在顶级HTML使用v-if,当组件消失时,并没有按照我们预期的执行组件的 destroyed 函数.

    难道是组件的HTML结构没有被删除吗?

    看看组件的的HTML结果:

    组件内部的HTML结构确实是被删除了,但不代表组件被删除了

    结果表明,组件的HTML结构确实被删除了!!
    但是并没有触发组件的 destroyed 声明周期钩子函数!!!


    结论

    1. v-if 使用在组件上,表示 清除或者新建这个组件.

    2. v-if 作用在普通的 HTML 元素上,仅仅表示清除这段DOM 结构.

    3. 想通过 v-if 依赖生命周期钩子函数,必须把 v-if 修饰在组件上或者手动的调用组件的 vm.$destroy() 方法。

    相关文章

      网友评论

          本文标题:Vue 之 v-if 学习

          本文链接:https://www.haomeiwen.com/subject/yhqadqtx.html