前提:vue3项目中一个通过点击显示隐藏的需求,但是要隐藏的这个dom元素,后续要作为其他库的容器
问题:此时用到了v-if,当通过 绑定点击事件+v-if,被控制的dom元素里面渲染的东西通过点击隐藏显示后,不再显示,无内容
那么我们可以先了解一下这些机制,然后我们在进行测试
v-if 和 v-show 机制 及其 总结
两种都是vue中常用于元素显示隐藏的指令
-
v-if
- v-if:Vue.js 中的一个指令,用于条件性地渲染一块 DOM 元素。
- v-if的值为false,相对应的dom元素及其子元素都会被从dom树中移除。一种真正意义上的 ’删除‘ 操作。在页面的文档结构中不存在,浏览器也不会对它们进行布局渲染
-
v-show
- v-show:Vue.js 中的一个指令,指令是通过控制元素的
visibility属性来实现显示和隐藏的。 - 当 v-show 表达式的值为 false 时,元素仍然存在于 DOM 树中,只是通过 CSS 样式使其不可见。元素仍然在 DOM 树中,只是用户看不到它们
- v-show:Vue.js 中的一个指令,指令是通过控制元素的
总结:
从上述可以得出,在面对一些需要频繁操作的元素,v-show比较合适,v-if因为会在dom树中清除dom,会导致重绘重排,带来一定的性能开销,影响页面的性能。
此外,对于一些特定的库操作,需要获取dom元素作为容器,当我们第一次在生命周期 mounted中建立后,后续通过v-if的显示隐藏,会需要库重新获取dom重新操作,可能需要我们对这种情况进行代码修改比较繁琐
简单的测试
测试准备:下载一个 需要dom作为容器操作的库,这里我们用的是:simpleMindMap库(一个可以创建思维导图的库) 准备了两个div元素,一个通过v-if控制,一个通过v-show控制(可以看到容器里面有渲染的内容)
此时分别点击: v-if 和 v-show按钮两次起到隐藏、显示的效果。同时观察元素情况。(可以看到点击后容器内部元素变化)
再回到开始,这次我们只点击一次看看,里面的变化(v-if的dom消失,v-show多了一个display:none进行隐藏,而元素还在)
总结:
除了以上的方法以外,在面试的环节还可以说一些,比如:opacity属性,定位/transform属性-100000px移动,z - index属性
测试代码
<script setup>
import { ref, onMounted } from 'vue'
import MindMap from "simple-mind-map";
// 控制显示和隐藏
var changIF = ref(true)
var changShow = ref(true)
// 创建俩个MindMap实例
onMounted(() => {
const mindMap_IF = new MindMap({
el: document.getElementById('VIF'),
data: {
"data": {
"text": "V-IF"
},
}
});
const mindMap_SHOW = new MindMap({
el: document.getElementById('SHOW'),
data: {
"data": {
"text": "V-SHOW"
},
}
});
})
</script>
<template>
<div style="width: 200px;height: 300px;">
<!-- 按钮控制 -->
<button @click="changIF=!changIF">控制v-if</button>
<button @click="changShow=!changShow">控制v-show</button>
<!-- 两个容器 -->
<div class="container" v-if="changIF" id="VIF">
</div>
<div class="container" v-show="changShow" id="SHOW">
</div>
</div>
</template>
<style scoped>
.container {
width: 200px;
height: 100px;
background-color: black;
color: aliceblue;
border: 1px red solid;
line-height: 100px;
margin-top: 10px;
}
</style>