Vue会尝试复用页面上的DOM,如切换 input 但是 input 的值却没有发生改变
如下,当 v-if 改变成 v-else时,input中的内容时不会改变的
(v-show的隐藏和显示的实质是,在css添加display:none属性,如果要频繁的隐藏和显示最好用v-show
v-if 的隐藏和显示的实质是,将不将这个DOM插进页面去
)
<div v-if="show=== 'A'">
用户名:<input />
</div>
<div v-else>
昵称:<input />
</div>
解决方法:用 key 管理可复用的元素
Vue 为你提供了一种方式来表达“这两个元素是完全独立的,不要复用它们”。
只需添加一个具有唯一值的 key attribute 即可:
(注意 key 前面不用加 :)
<div v-if="show=== 'A'">
用户名:<input key="username"/>
</div>
<div v-else>
昵称:<input key="nicheng"/>
</div>
为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而复用和重新排序现有元素,你需要为每项提供一个唯一 key 属性
(key值一定要唯一,一般都是后端传递数据中的,每条数据都有唯一一个id的值作为key值)
<div id="example">
<ul>
<li v-for="(item, index) in items" :key="item.id">
{{item.text}}
</li>
</ul>
</div>
<script>
var vm = new Vue({
el: '#example',
data: {
message: 'Hello world',
show:"",
items:[
{id:0122316343,
text:"学习"},
{id:0122316342,
text:"娱乐"},
{id:0122316341,
text:"技术"},
]
}
})
</script>
我们尝试变更data中定义的数组时,不能使用下标的形式对数组进行增加,修改等
如:
上述例子中的 items 数组有 3 个值,如果我们想要增加一个值
(当然,因为数组是引用类型,改变数组引用的指向时,页面也会跟着响应)
this.items[4] = {id:0122316340,text:"测试"}
//这样是不行的,虽然item的值确实改变了,但是页面不会跟着响应,只能用Vue给我们的方法
this.items.push({id:0122316340,text:"测试"} ) //这样是可以的
(当然,因为数组是引用类型,改变数组引用的指向时,页面也会跟着响应)
this.items = [
{id:01456123,
text:"学习2323"},
{id:012231123,
text:"娱乐2323"},
{id:012234321,
text:"技术2332"},
]
而是只能使用Vue为我们提供的方法进行修改
会改变原始数组
push() *** 可以接收任意数量的参数,把它们逐个添加到原数组末尾,并返回修改后数组的长度。
pop() *** 删除原数组末尾最后一项,减少数组的 length 值,然后返回移除的项。
shift() *** 删除原数组第一项,并返回删除元素的值;如果数组为空则返回undefined 。
unshift() *** 将参数逐个添加到原数组开头,并返回数组的长度 。
splice() *** 很强大的数组方法,它有很多种用法,可以实现删除、插入和替换。
sort() *** 按升序排列数组项——即最小的值位于最前面,最大的值排在最后面。
reverse() *** 反转数组项的顺序。
不会改变原始数组,而是返回一个新数组。
filter() 过滤功能,数组中的每一项运行给定函数,返回满足过滤条件组成的数组
var arr = [1, 2, 3, 4, 5];
var arr2 = arr.filter(function(x, index) {
return x>=3;
});
console.log(arr2,arr);
//[3, 4, 5] [1, 2, 3, 4, 5]
concat() 将参数添加到原数组中
1 . 如果参数不是数组,直接插进数组
var arr = [1,3,5,7];
var arrCopy = arr.concat(9,11,13);
//[1, 3, 5, 7, 9, 11, 13]
2 . 如果参数是数组,将数组拆开,插进去
var arr = [1,3,5,7];
var arrCopy = arr.concat([9,11,13]);
//[1, 3, 5, 7, 9, 11, 13]
3 . 如果参数是二维数组,将二维数组插进去
var arr = [1,3,5,7];
var arrCopy2 = arr.concat( [9,[11,13]] );
//[1, 3, 5, 7, 9, Array[2]]
slice() 返回从原数组中指定开始下标到结束下标之间的项组成的新数组
你也可以利用带有 v-for 的 template 来循环渲染一段 包含多个元素的内容。
比如:
好处,可以减少 v-for 的 代码(如果不用 template,就要在 li 和span 分别定义 v-for,当然也可以将template换成div , 但是 div 也会跟着循环渲染,div会出现在DOM中,template则不会)
<ul>
<template v-for="item in items">
<li>{{ item.msg }}</li>
<span>{{ item.msg }}</span>
</template>
</ul>
v-on : click=“handler” 绑定事件时加不加括号的问题 ()
不加括号() ,可以直接输出 该事件的DOM
加括号,则会显示 undefined ,此时需要使用 $event 作为参数,在事件函数中传递,也可以获取触发事件的DOM
<div id="example">
<button v-on:click="handler">
点击1
</button>
<button v-on:click="handler_two()">
点击2
</button>
<!-- <button v-on:click="handler_two($event)">
点击2
</button> -->
</div>
<script>
var vm = new Vue({
el: '#example',
data: {
},
methods: {
handler:function(e){
console.log(e);
// MouseEvent {isTrusted: true, screenX: 25, screenY: 124, clientX: 25, clientY: 22, …}
},
handler_two:function(e){
console.log(e);
// undefined
}
},
})
</script>
事件修饰符
在事件处理程序中调用 event.preventDefault()(阻止事件的默认行为,如提交表单之后自动跳转到对应页面) 或 event.stopPropagation() (阻止事件传播)是非常常见的需求。
VUE提供了时间修饰符,更加简单化的处理
.stop
.prevent
.capture
.self
.once 只触发一次
.passive
<!-- 阻止单击事件继续传播 -->
<a v-on:click.stop="doThis"></a>
<!-- 提交事件不再重载页面 -->
<form v-on:submit.prevent="onSubmit"></form>
<!-- 修饰符可以串联 -->
<a v-on:click.stop.prevent="doThat"></a>
<!-- 只有修饰符 -->
<form v-on:submit.prevent></form>
<!-- 通俗的说就是将事件冒泡,变成事件捕获,点击内部时,先触发外部父元素事件 -->
<div v-on:click.capture="out">
<div v-on:click.capture="inner">...</div>
</div>
<!-- 只当在 event.target 是当前元素自身时触发处理函数 -->
<!-- 事件不是从内部元素触发的 ,即不会出现事件冒泡-->
<div v-on:click.self="doThat">...</div>
self 就相当于 e.target = e.currentTaget,即触发事件的DOM 和 绑定事件的DOM 相等时,才触发
keyup 键盘监听器,当松开键盘时触发,当加上 .enter 修饰符时,只有点击回车后,才会触发函数
<input v-on:keyup.enter="submit">
.enter
.tab
.delete (捕获“删除”和“退格”键)
.esc
.space
.up
.down
.left
.right
同时按下 alt + c 才能触发事件
<input v-on:keyup.alt.67="clear">
.ctrl
.alt
.shift
.meta
只有当树表示右键点击时,才会触发事件函数
<button v-on:click.right="handler"> </button>
.left
.right
.middle
修饰符
.lazy,不会实时的监听输入框中的内容,即不会在输入框输入一个值,就显示一个值,而是鼠标失去焦点时,一次性输出
<input v-model.lazy="something" />
{{something}}
. number,将用户的输入值转为数值类型
input v-model="something" />
{{something}}
// typeof (something) string
// 即使输入的是数字,typeof 也会 解析成string
input v-model.number="something" />
{{something}}
// typeof(something),number
. trim 自动过滤首尾空白,空格
<input v-model.trim="something" />
{{something}}