关于vue.js:vue的vif和vshow需要注意的问题

44次阅读

共计 2943 个字符,预计需要花费 8 分钟才能阅读完成。

原文:https://mp.weixin.qq.com/s?__…
微信公众号: 毛毛虫的小小蜡笔

前言

应该大家都晓得 v -if 和 v -show 的区别。

v-if,是有条件的渲染,当条件是 true 的时候,才渲染到 dom 节点中。当条件是 false 的时候,是不会渲染到 dom 节点中。
v-show,则不论条件是否为 true,都会渲染到 dom 节点中,只是切换 css 的 display 来显示或暗藏而已。

场景和须要留神的问题

场景 1

如果只是简略的 tab 切换,并且每个 tab 组件的内容不多,那绝对应用 v -show 会更适合。
但须要留神的问题是,页面加载后,都会触发 tab 组件的 mounted,并且会依据组件程序来触发 mounted。

Demo

代码:

// tab.vue
<template>
  <el-tabs v-model="activeName">
    <el-tab-pane label="tab1" name="first">
      <tab1 v-show="activeName==='first'"></tab1>
    </el-tab-pane>
    <el-tab-pane label="tab2" name="second">
      <tab2 v-show="activeName==='second'"></tab2>
    </el-tab-pane>
  </el-tabs>
</template>

<script>
import tab1 from '../components/tab1.vue'
import tab2 from '../components/tab2.vue'
export default {components: { tab1, tab2},
  data: () => {
    return {activeName: 'first'}
  },
  mounted() {console.log('tab')
  }
}
</script>

<style lang="less" scoped>
.el-tabs {text-align: left;}
</style>

// tab1.vue
<template>
  <div class="tab1">
      {{value}}
  </div>
</template>

<script>
export default {data: () => {
    return {value: 'tab1 的内容...'}
  },
  mounted() {console.log('tab1')
  }
}
</script>

// tab2.vue
<template>
  <div class="tab2">
      {{value}}
  </div>
</template>

<script>
export default {data: () => {
    return {value: 'tab2 的内容...'}
  },
  mounted() {console.log('tab2')
  }
}
</script>

成果下图所示:

如果把下面的 v -show 改为 v -if 呢?

置信大家都能晓得,tab2 的组件是不会加载,也不会渲染到 dom 的,也就不会触发 mounted 了。
成果如下截图所示:

而且每次切换 tab,都会触发组件的 mounted。
成果如下截图所示:

场景 2

如果有这样的需要:
当组件 mounted 的时候,须要发个初始化申请,比方获取组件的根底数据(根本不会变动的数据)。

那这种场景就比拟适宜 v -show,不太适宜 v -if。
不然每次切换 tab,都会发申请获取根底数据。

但如果两个组件用同一个 mixin,mixin 中有个专用的函数呢?

代码次要改变点:
组件 tab2 会有个本人的函数,在 mixin 中会判断下,如果以后激活的 tab 是第二个,则调用 tab2 的函数,并返回处理结果。

具体代码如下所示:

// tab.vue
<template>
  <el-tabs v-model="activeName">
    <el-tab-pane label="tab1" name="first">
      <tab1 v-show="activeName==='first'":activeName="activeName"></tab1>
    </el-tab-pane>
    <el-tab-pane label="tab2" name="second">
      <tab2 v-show="activeName==='second'":activeName="activeName"></tab2>
    </el-tab-pane>
  </el-tabs>
</template>

<script>
import tab1 from '../components/tab1.vue'
import tab2 from '../components/tab2.vue'
export default {components: { tab1, tab2},
  data: () => {
    return {activeName: 'first'}
  },
  mounted() {console.log('tab')
  }
}
</script>

<style lang="less" scoped>
.el-tabs {text-align: left;}
</style>

// tab1.vue
<template>
  <div class="tab1">
      {{value}} <br/>{{getNum()}}
  </div>
</template>

<script>
import mixin from './mixin.js'
export default {mixins: [mixin],
  props: ['activeName'],
  data: () => {
    return {value: 'tab1 的内容...'}
  },
  mounted() {console.log('tab1')
  }
}
</script>

// tab2.vue
<template>
  <div class="tab2">
      {{value}} <br/>{{getNum()}}
  </div>
</template>

<script>
import mixin from './mixin.js'
export default {mixins: [mixin],
  props: ['activeName'],
  data: () => {
    return {value: 'tab2 的内容...'}
  },
  mounted() {console.log('tab2')
  },
  methods: {getTab2Num() {return 'tab2num is'+ Math.random()
    }
  }
}
</script>

// mixin.js
export default {
  methods: {getNum() {console.log('getNum')
      let result = 'tab1num is'+ Math.random()
      if (this.activeName === 'second') {result = this.getTab2Num()
      }
      return result
    }
  }
}

此时用了 v -show,而不是 v -if,就会有问题。

默认渲染 tab1 的时候,不会报错。
如下截图所示:

当点击 tab2 的时候,就报错了。
如下截图所示:

但把 v -show 换成 v -if,就没问题了。

默认渲染 tab1 的时候,不会报错。
如下截图所示:

当点击 tab2 的时候,也是没有问题。
如下截图所示:

最初

  • 公众号《毛毛虫的小小蜡笔》

有疑难和问题,请留言。

如果感觉文章还能够,请点赞或珍藏,谢谢。

正文完
 0