条件渲染 | v-if、v-show
- v-if
语法:
- v-if = ‘表达式’
- v-else-if = ‘表达式’
- v-else = ‘表达式’
适用于:切换频率较低的场景
特点:不展示的DOM元素直接被移除
注意:v-if可以和:v-else-if、v-else一起使用,但要求结构不能被“打断”
- v-show
语法:
v-show=‘表达式’
适用于:切换频率较高的场景
特点:不展示的DOM元素未被移除,仅仅是使用样式隐藏掉(display:none)
备注:使用 v-if 的时,元素可能无法获取到,而使用v-show一定可以获取到 v-if 是实打实地改变dom元素,v-show 是隐藏或显示dom元素
<div id="root">
<h2>条件渲染</h2>
<hr>
<!-- v-show 可以接受布尔值/表达式作为属性值 -->
<div v-show="true">{{ hello_name }}</div>
<div v-show="0.1+0.2===0.3">{{ vue_name }}</div>
<!-- v-if 可以接受布尔值/表达式作为属性值 -->
<div v-if="n==1">{{ hello_name }}</div>
<div v-else-if="n==2">{{ hello_name }}!</div>
<div v-else-if="n==3">{{ hello_name }}!!</div>
<div v-else-if="n>=3">{{ hello_name }} good</div>
<button @click="n++">点击变换</button>
<!-- v-if与template的配合使用 管理多个元素渲染 -->
<template v-if="n==1">
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
</template>
</div>
<script type="text/javascript">
const x = new Vue({
el: '#root',
data: {
hello_name: 'Vue',
vue_name: 'Vue',
n: 1
}
})
</script>
列表渲染 | v-for
v-for指令,用于展示列表数据
语法: v-for=“(item, index) in xxx” :key=“yyy”
可遍历元素:数组、对象、字符串(用的很少)、指定次数(用的很少)
数组: (item, index)
对象: (value, key)
字符串:(char, index)
指定次数:(number, index)
<div id="root">
<h2>列表渲染</h2>
<hr>
<div>
<!-- 遍历数组 -->
<!-- <ul v-for="p in persion" :key="p.id"> -->
<ul v-for="p of persion" :key="p.id">
<li>{{p.name}} ,年龄:{{p.age}}</li>
</ul>
<!-- 遍历对象 -->
<ul v-for="(value,key) of persion[0]" :key="key">
<li>{{ value }}</li>
</ul>
<!-- 遍历字符串 -->
<ul v-for="(char,index) of 'hello'" :key="index">
<li>第{{index}}字母为:{{ char }}</li>
</ul>
<!-- 遍历指定次数 -->
<ul v-for="(char,index) of 4" :key="char+index+Math.random()">
<li>{{ char }} ,索引为 {{index}}</li>
</ul>
</div>
</div>
<script type="text/javascript">
const x = new Vue({
el: '#root',
data: {
persion: [
{ id: 'sk9G2O01avD', name: '张三', age: '12' },
{ id: 'k8F4Dl7m', name: '李四', age: '34' },
{ id: 'oB5vA0Qmm1p', name: '杰克', age: '22' }
]
}
})
</script>
key 的作用与原理
虚拟DOM中key的作用:
key是虚拟DOM对象的标识,当数据发生变化时,Vue会根据【新数据】生成【新的虚拟DOM】, 随后Vue进行【新虚拟DOM】与【旧虚拟
DOM】的差异比较,比较规则如下:
对比规则:
- 旧虚拟DOM中找到了与新虚拟DOM相同的key:
①若虚拟DOM中内容没变, 直接使用之前的真实DOM
②若虚拟DOM中内容变了, 则生成新的真实DOM,随后替换掉页面中之前的真实DOM - 旧虚拟DOM中未找到与新虚拟DOM相同的key创建新的真实DOM,随后渲染到到页面。
用index作为key可能会引发的问题:
- 若对数据进行:逆序添加、逆序删除等破坏顺序操作: 会产生没有必要的真实DOM更新 ==> 界面效果没问题, 但效率低
- 如果结构中还包含输入类的DOM: 会产生错误DOM更新 ==>界面有问题
开发中如何选择key:
- 最好使用每条数据的唯一标识作为key, 比如id、手机号、身份证号、学号等唯一值。
- 如果不存在对数据的逆序添加、逆序删除等破坏顺序操作,仅用于渲染列表用于展示,使用index作为key是没有问题的。
实现列表排序
<div id="root">
<h2>列表排序</h2>
<hr>
<input type="text" v-model="inputKey" placeholder="检索姓名">
<button @click="sortType = 1">年龄升序</button>
<button @click="sortType = 2">年龄降序</button>
<button @click="sortType = 0">原顺序</button>
{{sortType}}
<div>
<ul v-for="p of filePersion" :key="p.id">
<li>{{p.name}} ,年龄:{{p.age}}</li>
</ul>
</div>
</div>
<script type="text/javascript">
new Vue({
el: '#root',
data: {
sortType: 0, //0 原顺序 ,1 升序,2 降序
inputKey: '',
persion: [
{ id: 'dsadafds', name: '张三', age: '12' },
{ id: 'ewrsr23', name: '李四', age: '34' },
{ id: 'fdsa32424', name: '王五', age: '54' },
{ id: 'gdsbjryey', name: '张露西', age: '32' },
{ id: 'trevcdfhgtr', name: '贝克汉姆', age: '22' }
],
},
computed: {
filePersion() {
const arr = this.persion.filter((p) => {
return p.name.indexOf(this.inputKey) >= 0
})
// 判断是否需要排序
if (this.sortType) {
arr.sort((p1, p2) => {
return this.sortType === 1 ? p1.age - p2.age : p2.age - p1.age
})
}
return arr
}
}
})
</script>
数据监测原理_对象
简单模拟vue更新数据原理
let data = {
name:'VUE',
address:'北京',
} f
unction Observer(obj){
//汇总 data 对象中所有的属性形成一个数组
const keys = Object.keys(obj)
//遍历 keys 数组,分别添加 getter 、 setter
keys.forEach((k) => {
Object.defineProperty(this, k, {
get() {
return obj[k]
},
set(val) {
console.log(`${k}被改了,我要去解析模板,生成虚拟DOM.....`)
obj[k] = val
}
})
})
} /
/创建一个监视的实例对象,用于监视(中转) data 中属性的变化
const obs = new Observer(data)
console.log(obs)
//准备一个vm实例对象
let vm = {}
vm._data = data = obs