v-if与v-show的区别
v-if="false" 此时节点不存在,不展示的DOM元素在移除与不移除之间切换,在切换频率高时,效率低
v-show="false" 此时节点存在,只是使用样式使其不可见,DOM元素存在,在切换频率高时,效率高
使用v-if时,元素可能无法获取到,因为不展示的DOM元素被移除,使用v-show一定能被获取到
template与v-if的搭配使用
template模板标签在渲染时不会渲染,只能搭配v-if使用,不能用v-show,可以解决多个相同判断在使用v-if时被迫加上div破环结构的问题
<div id="root">
<button @click="n++">n++</button>
<div v-if="n===1">1</div>
<div v-if="n===1">2</div>
<div v-if="n===1">3</div>
<div v-if="n===1">4</div>
</div>
<script>
new Vue({
el:"#root",
data: {
n:0
},
})
</script>
此时有多个判断,为了简洁,改为
<div id="root">
<button @click="n++">n++</button>
<div v-if="n===1">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
</div>
</div>
<script>
new Vue({
el:"#root",
data: {
n:0
},
})
</script>
但是很明显多加了一个div,会破坏结构,因此使用template标签(只与v-if搭配,不与v-show搭配)解决结构破坏
<div id="root">
<button @click="n++">n++</button>
<template v-if="n===1">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
</template>
</div>
<script>
new Vue({
el:"#root",
data: {
n:0
},
})
</script>
v-for
用于展示列表数据
只要是v-for的遍历生成同样结构的数据,必须给每个元素打个标识(key(:key))
<div id="root">
<ul>
<li v-for="(p,index) in persons" :key="index">
{{p.name}}-{{p.age}}-{{index}}
</li>
</ul>
</div>
<script>
new Vue({
el:"#root",
data: {
persons:[
{id:'1',name:'a',age:'12'},
{id:'2',name:'b',age:'13'},
{id:'3',name:'c',age:'14'}
]
},
})
</script>
v-for="p in persons" 可以写为v-for="p of persons"
js中for in 与for of 的区别
for in 遍历键名 主要遍历对象 k得键名 persons[k]得键值
for of遍历键值 主要遍历数组 k得键值 persons[k]得键名
v-for中的key的原理(diff算法)
key在vue和虚拟DOM中 真实DOM中没有
不写key时vue会自动将索引值作为key
根据key值对比
找到相同的key新旧虚拟DOM对比,若内容没变,直接使用之前的真实DOM,若内容改变,则生成新的真实DOM,替换掉之前的真实DOM
若未找到相同的key 创建新的真实DOM,渲染到页面
index(索引值)作为key时
当index作为key时会导致产生不必要的真实DOM生成(复用性不高),如果有input输入类DOM会产生错误的DOM更新如图,效率低
id(唯一标识)作为key时
当id作为key时不易产生错误
列表过滤
watch写法
<div id="root">
<h2>查找</h2>
<input type="text" v-model="keyWord"/>
<ul>
<li v-for="(p,i) in newda" :key="">
{{p.id}}--{{p.name}}--{{p.sex}}--{{p.age}}
</li>
</ul>
</div>
<script>
new Vue({
el:"#root",
data: {
da:[
{id:1,name:'李小强',sex:'男' ,age:'13'},
{id:2,name:'李强',sex:'男' ,age:'1'},
{id:3,name:'王晓丽',sex:'女' ,age:'1823'},
{id:4,name:'晓楠',sex:'女' ,age:'24'}
],
newda:[
{id:1,name:'李小强',sex:'男' ,age:'13'},
{id:2,name:'李强',sex:'男' ,age:'1'},
{id:3,name:'王晓丽',sex:'女' ,age:'1823'},
{id:4,name:'晓楠',sex:'女' ,age:'24'}
],
sortType:0
},
watch:{
immediate:true,
keyWord:{
handler(val){
this.newda=this.da.filter((h)=>{
return h.name.indexOf(val)!==-1
})
return this.newda
}
}
}
})
</script>
computed写法
<div id="root">
<h2>查找</h2>
<input type="text" v-model="keyWord"/>
<ul>
<li v-for="(p,i) in newda" :key="">
{{p.id}}--{{p.name}}--{{p.sex}}--{{p.age}}
</li>
</ul>
</div>
<script>
new Vue({
el:"#root",
data: {
keyWord:"",
da:[
{id:1,name:'李小强',sex:'男' ,age:'13'},
{id:2,name:'李强',sex:'男' ,age:'1'},
{id:3,name:'王晓丽',sex:'女' ,age:'1823'},
{id:4,name:'晓楠',sex:'女' ,age:'24'}
],
},
computed:{
newda(){
return this.da.filter((h)=>{
return h.name.indexOf(this.keyWord)!==-1
})
}
}
})
</script>
列表排序
<div id="root">
<h2>查找</h2>
<input type="text" v-model="keyWord"/>
<button @click="sortType=1">升序</button>
<button @click="sortType=2">降序</button>
<ul>
<li v-for="(p,i) in newda" :key="">
{{p.id}}--{{p.name}}--{{p.sex}}--{{p.age}}
</li>
</ul>
</div>
<script>
new Vue({
el:"#root",
data: {
keyWord:"",
sortType:0,
da:[
{id:1,name:'李小强',sex:'男' ,age:'13'},
{id:2,name:'李强',sex:'男' ,age:'1'},
{id:3,name:'王晓丽',sex:'女' ,age:'1823'},
{id:4,name:'晓楠',sex:'女' ,age:'24'}
],
},
computed:{
newda(){
const arr= this.da.filter((h)=>{
return h.name.indexOf(this.keyWord)!==-1
})
if(this.sortType){
arr.sort((a,b)=>{
return this.sortType===1?a.age-b.age:b.age-a.age
})
}
return arr
}
}
})
</script>
数据代理的理解
数据代理的简易过程
this是obs
先创建一个用于监视data的实例对象,将data传入函数,get和set修改obs的值,最后obs将数据还给data和vm._data
Vue.set和vm.$set的使用
为后添加的属性做响应式
对象中追加的属性,Vue默认不做响应式处理
Vue.set() ,vm.$set只能追加data对象中的属性,不能追加data中的对象
Vue.set(vm._data.对象,'属性','值') Vue.set(vm.对象,'属性','值') 可不写_data 因为有数据代理
vm.$set(vm._data.对象,'属性','值') vm.$set(vm.对象,'属性','值') 可不写_data 因为有数据代理
Vue监测数组改变
数组中没有为元素提供的set get方法,不靠setget监视数组,只有对象有set,get方法
靠数组的方法和Vue.set和vm.$set才能使改变的数组在视图上更新,以下方法为Vue重写的数组方法,重新解析了模板,触发视图更新
push向数组最后添加元素
pop删除数组最后的元素
shift删除数组第一个元素
unshift向数组第一位添加元素
spilce指定位置增添删改
sort排列
reverse反转
数据劫持的理解
data中的对象Vue会默认提供get,set方法,当对象改变时,set和get方法劫持改变的值,改变数据,重新解析模板,实现页面更新
收集表单数据
<body>
<div id="root">
<form @submit11as.prevent="demo">
账号<input type="text" v-model="info.uname"><br><br>
密码<input type="password"v-model="info.upassWord"><br><br>
年龄<input type="number" v-model.number="info.uage"><br><br>
性别: 男<input type="radio" value="男" v-model="info.sex">
女<input type="radio" value="女" v-model="info.sex"><br><br>
爱好: 抽烟<input type="checkbox" value="抽烟" v-model="info.hobby">
喝酒<input type="checkbox" value="喝酒" v-model="info.hobby">
烫头<input type="checkbox" value="烫头" v-model="info.hobby"><br><br>
所属校区:
<select v-model="info.address">
<option value="请选择校区">请选择校区</option>
<option value="西青" >西青</option>
<option value="南开" >南开</option>
<option value="合开" >合开</option>
</select><br><br>
其他信息
<textarea name="" id="" cols="30" rows="10" v-model="info.others"></textarea><br><br>
<input type="checkbox" v-model="info.uture">阅读并同意<a href="https://code.sipcoj.com/problem?page=1&limit=10">《用户协议》</a>
<input type="submit">
</form>
</div>
<script>
new Vue({
el:'#root',
data:{
info:{
uname:'',
upassWord:'',
uage:18,
sex:'男',
hobby:[],
address:'',
others:'',
uture:'',
}
},
methods: {
demo(){
console.log(this.info);
}
},
})
</script>
</body>