v-if 和 v-show 有什么区别
共同点:
v-if 和 v-show 都是动态显示DOM元素
区别:
1、编译过程: v-if 是 真正 的 条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。v-show 的元素始终会被渲染并保留在 DOM 中。v-show 只是简单地切换元素的 CSS 属性display。
2、编译条件: v-if 是惰性的:如果在初始渲染时条件为假,则什么也不做。直到条件第一次变为真时,才会开始渲染条件块。v-show不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。
3、性能消耗: v-if有更高的切换消耗。v-show有更高的初始渲染消耗。
4、应用场景: v-if适合运行时条件很少改变时使用。v-show适合频繁切换。
vue常用的修饰符
v-on 指令常用修饰符:
- .stop - 调用 event.stopPropagation(), 禁止事件冒泡。
- .prevent - 调用 event.preventDefault(),阻止事件默认行为。
- .capture - 添加事件侦听器时使用 capture 模式。
- .self - 只当事件是从侦听器绑定的元素本身触发时才触发回调。
- .{keyCode | keyAlias} - 只当事件是从特定键触发时才触发回调。
- .native - 监听组件根元素的原生事件。
- .once - 只触发一次回调。
- .left - (2.2.0) 只当点击鼠标左键时触发。
- .right - (2.2.0) 只当点击鼠标右键时触发。
- .middle - (2.2.0) 只当点击鼠标中键时触发。
- .passive - (2.3.0) 以 { passive: true } 模式添加侦听器。
注意: 如果是在自己封装的组件或者是使用一些第三方的UI库时,会发现并不起效果,这时就需要用`·.native修饰符了,如
//使用示例:
<el-input
v-model="inputName"
placeholder="搜索你的文件"
@keyup.enter.native="searchFile(params)"
>
</el-input>
v-bind 指令常用修饰符:
- .prop - 被用于绑定 DOM 属性 (property)。
- .camel - (2.1.0+) 将 kebab-case 特性名转换为 camelCase. (从 2.1.0 开始支持)。
.sync (2.3.0+) 语法糖,会扩展成一个更新父组件绑定值的 v-on 侦听器。
v-model 指令常用修饰符:
- .lazy - 取代 input 监听 change 事件。
- .number - 输入字符串转为数字。
- .trim - 输入首尾空格过滤。
v-on可以监听多个方法吗?
v-on可以监听多个方法,例如:
<input type="text" :value="name" @input="onInput" @focus="onFocus" @blur="onBlur" />
但是同一种事件类型的方法,vue-cli工程会报错,例如:
<a href="javascript:;" @click="methodsOne" @click="methodsTwo"></a>
会报错。
vue中 key 值的作用
<a href="javascript:void(0);" data-id="12" @click="showEvent($event)">event</a>
showEvent(event) {
// 获取自定义data-id
console.log(event.target.dataset.id)
// 阻止事件冒泡
event.stopPropagation();
// 阻止默认
event.preventDefault()
}
2.2.0+ 的版本里,当在组件中使用 v-for 时,key 现在是必须的。
key值:用于 管理可复用的元素。因为Vue
会尽可能高效地渲染元素,通常会复用已有元素而不是从头开始渲染。这么做使 Vue 变得非常快,但是这样也不总是符合实际需求。
key的作用是为了更加高效的更新虚拟do'm,另外在vue中使用相同标签元素的过度切换的时候,也需要使用key属性,其目的是为了让vue区分它们,否则vueh就只会替换其内部属性而不会触发过度效果。
vue事件中如何使用event对象?
注意在事件中要使用 $ 符号
//html部分
<a href="javascript:void(0);" data-id="12" @click="showEvent($event)">event</a>
//js部分
showEvent(event){
//获取自定义data-id
console.log(event.target.dataset.id)
// 阻止事件冒泡
event.stopPropagation();
//阻止默认
event.preventDefault()
}
什么是$nextTick?
因为Vue
的异步更新队列,$nextTick
是用来知道什么时候DOM
更新完成的。
异步更新队列:Vue在观察到数据变化时并不是直接更新DOM,而是开启一个队列,并缓冲在同一个事件循环中发生的所以数据改变。在缓冲时会去除重复数据,从而避免不必要的计算和DOM操作。然后,在下一个事件循环tick
中,Vue刷新队列并执行实际(已去重的)工作。所以如果你用一个for循环来动态改变数据100次,其实它只会应用最后一次改变,如果没有这种机制,DOM就要重绘100次,这固然是一个很大的开销。Vue会根据当前浏览器环境优先使用原生的Promise.then
和MutationObserver
,如果都不支持,就会采用setTimeout
代替。
案例:
我们先来看这样一个场景:有一个div
,默认用 v-if
将它隐藏,点击一个按钮后,改变 v-if
的值,让它显示出来,同时拿到这个div
的文本内容。如果v-if
的值是 false,直接去获取div
内容是获取不到的,因为此时div
还没有被创建出来,那么应该在点击按钮后,改变v-if
的值为 true,div才会被创建,此时再去获取,示例代码如下
<div id="app">
<div id="div" v-if="showDiv">这是一段文本</div>
<button @click="getText">获取div内容</button>
</div>
<script>
var app = new Vue({
el : "#app",
data:{
showDiv : false
},
methods:{
getText:function(){
this.showDiv = true;
var text = document.getElementById('div').innnerHTML;
console.log(text);
}
}
})
</script>
但是运行后在控制台会抛出一个错误:Cannot read property 'innnerHTML of null
,意思就是获取不到div
元素。通过Vue异步更新DOM的原理,上面示例的报错也就不难理解了。事实上,在执行this.showDiv = true
时,div仍然还是没有被创建出来,直到下一个vue
事件循环时,才开始创建。$nextTick
就是用来知道什么时候DOM更新完成的,所以上面的示例代码需要修改为:
<div id="app">
<div id="div" v-if="showDiv">这是一段文本</div>
<button @click="getText">获取div内容</button>
</div>
<script>
var app = new Vue({
el : "#app",
data:{
showDiv : false
},
methods:{
getText:function(){
this.showDiv = true;
this.$nextTick(function(){
var text = document.getElementById('div').innnerHTML;
console.log(text);
});
}
}
})
</script>
v-for 与 v-if 的优先级
当它们处于同一节点,v-for
的优先级比v-if
更高,这意味着 v-if
将分别重复运行于每个 v-for
循环中。当你想为仅有的一些项渲染节点时,这种优先级的机制会十分有用,如下:
<li v-for="todo in todos" v-if="!todo.isComplete">{{todo}}</li>
上面的代码只传递了未完成的 todos。
而如果你的目的是有条件地跳过循环的执行,那么可以将 v-if 置于外层元素 (或 <template>
)上。如:
<ul v-if="todos.length">
<li v-for="todo in todos">
{{ todo }}
</li>
</ul>
<p v-else>No todos left!</p>