【实战】Vue.js 中 v-if 和 v-show 的区别

一、业务需求


在一个拥有4个步骤的单向流程(Flow)中,需要在第2步展现 A 组件,第4步展现 B 组件,在第1、3步的时候隐藏组件。在有组件展示的步骤里,会传给组件的4组不同的数据(param),组件需要根据传入的数据做一些业务操作。

二、需求分析


  1. 在同一个地方有组件间的切换,可采用动态组件 component
  2. 对一个组件来说,当传入参数改变的时候,需要有相应的动作,所以可用 watcher 监听传入的参数是否改变。
  3. 组件需要隐藏 / 显示,可考虑使用 v-if 或者 v-show
  4. v-if 会重新创建组件(这是所谓开销大的一方面),有些组件自己维护的状态是不能保留的

三、伪代码


/*
 * A.vue
 * 组件A
 */
<template lang="pug">
div
  p {{param.text}}
</template>
<script>
export default {
  name: 'A',
  props: [ 'param' ],
  watch: {
    param: () => {
      ...
    }
  }
}
</script>

组件 B 和组件 A 类似,除了 name: 'B',所以略过了。

/*
 * Flow.vue
 */
<template lang="pug">
div
  div#container(v-if='show')
    component(
      :is='view' 
      :param='param'
    )
</template>

<script>
import A from 'A.vue'
import B from 'B.vue'

export default {
  name: 'Flow',
  components: { A, B },
  data() {
    return {
      show: false,
      view: null,
      param: null
    }
  },
  mounted() {
    this.view = 'A'
    setTimeout(() => {
      // 经过1秒以后流程进入第二步
      this.param = { ... } // 模拟第一次传入数据
      this.show = true // 显示组件
      // ... 其余步骤模拟略过
    }, 1000)
  }
}
</script>

Flowmounted 执行的时候,A 中的 param watcher 并不会被执行;若把 Flow 中的 v-if 改成 v-show,则 param watcher 会被执行。

四、分析


当使用 v-show 的时候,this.view = 'A' 的时候,A 组件已经完成了初始化(会触发 mounted),此时 A 组件拿到的 paramnull,所以当 paramFlow 中被赋值的时候,会触发 watcher 事件。注意:在切换 view 的时候,把新组件的一些初始化操作放到 vm.$nextTick 的回调里面。
而使用 v-if的话,A 组件的初始化会被延迟到 this.show = true 的时候,此时 A 组件拿到的 param 是已经被赋过值的了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容