一、v-for 指令的使用
通常用于列表渲染,所在标签结构,按照数据量,循环生成。
语法:
v-for = "(值,索引) in 目标结构"
v-for= "值 in 目标结构"
可以遍历数组/对象/数字/字符串(可以遍历结构)
注意:v-for的临时变量不能用到 v-for 范围外。
<template>
<div>
<p :class="{red_str:bool}">动态class</p>
<div id="app">
<div id="app">
<p>学生姓名</p>
<ul>
<li v-for="(item,index) in arr" :key="item">
{{index}}-{{item}}
</li>
</ul>
<p>学生详细信息表</p>
<ul>
<li v-for="obj in stuArr" :key="obj.id">
<span>{{obj.name}}</span>
<span>{{obj.sex}}</span>
<span>{{obj.hobby}}</span>
</li>
</ul>
<!-- v-for遍历对象(了解) -->
<p>老师信息</p>
<div v-for="(value, key) in tObj" :key="value">
{{ key }} -- {{ value }}
</div>
<!-- v-for遍历整数(了解) - 从1开始 -->
<p>序号</p>
<div v-for="i in count" :key="i">{{ i }}</div>
</div>
</div>
</div>
</template>
<script>
export default {
data(){
return {
bool:true,
arr: ["小明", "小欢欢", "大黄"],
stuArr: [
{
id: 1001,
name: "孙悟空",
sex: "男",
hobby: "吃桃子",
},
{
id: 1002,
name: "猪八戒",
sex: "男",
hobby: "背媳妇",
},
],
tObj: {
name: "小黑",
age: 18,
class: "1期",
},
count: 10,
}
}
}
</script>
<style scoped>
.red_str{
color: red;
}
</style>
</style>
那些方法会触发 数组改变 v-for 会检测到 并更新页面
push(); pop(); shift(); unshift();splice(); sort();revers();
那些方法不会出发 v-for 更新
slice();filter();concat();
注意 vue不能检测到数组里面赋值到动作而更新,如果需要使用该操作,需要使用 vue.set 或者this.$set(),或者覆盖整个数组。
总结:改变原数组的方法才能让 v-for更新
v-for 更新性能为何高?
v-for的默认行为会尝试原地修改元素,而不是移动他们。产生一个虚拟dom
这种虚拟Dom 对比方式,可以提高性能 但是还不够高
二、什么是虚拟dom
概念:.vue 中的template里面写的标签,都是模版,要被vue处理成虚拟dom对象,才会渲染现实到真实Dom页面上。
介绍:内存生成一样的虚拟Dom结构 本质是个js 对象
因为真实的dom属性好几百个,没办法快速的知道哪一个属性改变了。
比如template 里面的标签结构
<template>
<div id="box">
<p class="my_p">123</p>
</div>
</template>
对应的虚拟dom 结构
以后vue数据更新,生成新的虚拟dom结构 和 旧的 dom结构 对比 利用diff算法,找不同,只更新变化的部分(重绘/回流)到页面。也叫打补丁。
优点:
提高了更新dom 的性能 不用把页面全部删除重新渲染
虚拟dom 只包含必要的属性 (没有真实的dom 上百个属性)
总结 :
虚拟dom保存在内存中,只记录dom 关键信息,配合diff算法更新提高Dom更新的性能。
在内存中比较差异,然后给真实Dom打补丁(重绘/回流)更新上。
三、diff算法
vue 利用diff算法 新虚拟dom 和 旧的虚拟dom 比较
情况1: 根元素变了,删除重建。
//旧虚拟dom
<div id="box">
<p class="my_p">123</p>
</div>
//新虚拟dom
<ul id="box">
<li class="my_p">123</li>
</ul>
情况2:根元素没变,属性改变,元素复用,更新属性。
//旧虚拟
<div id="box">
<p class="my_p">123</p>
</div>
//新虚拟
<div id="myBox" title="标题">
<p class="my_p">123</p>
</div>
四、key的作用
情况3:根元素没变,子元素没变,元素内容改变
无key -就地更新
v-for不会移动DOM, 而是尝试复用, 就地更新,如果需要v-for移动DOM, 你需要用特殊 attribute key 来提供一个排序提示
<ul id="myUL">
<li v-for="str in arr">
{{ str }}
<input type="text">
</li>
</ul>
<button @click="addFn">下标为1的位置新增一个</button>
export default {
data(){
return {
arr: ["老大", "新来的", "老二", "老三"]
}
},
methods: {
addFn(){
this.arr.splice(1, 0, '新来的')
}
}
};
有key 值 --值为索引的时候。
还是就地更新。
因为新旧虚拟Dom对比,key 存在就复用次标签更新内容,如果不存在就直接建立一个新的。
<ul id="myUL">
<li v-for="(str, index) in arr" :key="index">
{{ str }}
<input type="text">
</li>
</ul>
<button @click="addFn">下标为1的位置新增一个</button>
export default {
data(){
return {
arr: ["老大", "新来的", "老二", "老三"]
}
},
methods: {
addFn(){
this.arr.splice(1, 0, '新来的')
}
}
};
1. v-for先循环产生新的DOM结构, key是连续的, 和数据对应
2. 然后比较新旧DOM结构, 找到区别, 打补丁到页面上
最后补一个li, 然后从第二个往后, 都要更新内容
3. 口诀: key的值有id用id, 没id用索引
有key - 值 为ID
key的值 只能是唯一不重复的 字符串或数值;
v-for 不会移动Dom 而是尝试复用,就地更新,如果需要移动,需要使用特殊的attribute Key 来提供一个排序提示。
新dom 里数据key存在,去旧的虚拟dom结构里找到key 标记的标签 复用标签。
新dom 里数据key存在 去旧的虚拟dom里没有找到Key标记的标签 创建。
旧dom 结构的key 在新的dom 结构里没有了,则移除key所在的标签
<template>
<div>
<ul>
<li v-for="obj in arr" :key="obj.id">
{{ obj.name }}
<input type="text">
</li>
</ul>
<button @click="btn">下标1位置插入新来的</button>
</div>
</template>
<script>
export default {
data() {
return {
arr: [
{
name: '老大',
id: 50
},
{
name: '老二',
id: 31
},
{
name: '老三',
id: 10
}
],
};
},
methods: {
btn(){
this.arr.splice(1, 0, {
id: 19,
name: '新来的'
})
}
}
};
</script>
<style>
</style>
总结:
1.不用key也不影响功能(就地更新) 添加key 可以提高更新的性能。
2.口诀: 有ID用 ID。没有ID就用 索引。 Key属性 是必须的。
五、动态class
适用于 通过v-bind 给标签class 设置动态的值
语法:
:class={"类名:布尔值"}
<template>
<div>
<!-- 语法:
:class="{类名: 布尔值}"
使用场景: vue变量控制标签是否应该有类名
-->
<p :class="{red_str: bool}">动态class</p>
</div>
</template>
<script>
export default {
data(){
return {
bool: true
}
}
}
</script>
<style scoped>
.red_str{
color: red;
}
</style>
总结:如何给class 属性动态赋值?
:class="{类名:布尔值}",true 使用,false 不使用。
扩展-
1.多个动态class 如何处理
:class="{类名:布尔值1,类名2:布尔值2}"
<p :class="active:true,activeS:false">动态</p>
2.固定class 如何书写?
class 和 :class可以并存
<p class="active" :class="{activeS:true}">动态</p>
3.class的数组 语法
<div v-bind:class="[activeClass,errorClass]"></div>
data:{
acitveClass:"active",
errorClass:"text-danger"
}
//渲染的效果
<div class="active text-danger"></div>
4.三元运算
<div :class="bool ? 'heihei1':'heihei2'></div>
data(){
return{
bool:false
}
}
六、动态style
给标签动态设置style的值
语法:
:style="{css属性:值}"
<template>
<div>
<!-- 语法:
:class="{类名: 布尔值}"
使用场景: vue变量控制标签是否应该有类名
-->
<p :class="{red_str: bool}">动态class</p>
</div>
</template>
<script>
export default {
data(){
return {
bool: true
}
}
}
</script>
<style scoped>
.red_str{
color: red;
}
</style>
总结 :动态style 的KEY 都是CSS属性名
扩展:
1.带横线的样式(用引号引起来),或者用驼峰式命名,
2.style 对象语法。
<div v-bind:style="styleObject"></div>
data:{
return{
styleObject:{
color:'red',
fontSize:'13px'
}
}
}
3.style 数组语法
<div v-bind:style="[baseStyles,overridingStyles]"></div>
data: {
return{
baseStyles: {
color: 'red',
fontSize: '13px'
},
overridingStyles:{
width:'100px',
height:'200px'
}
}
}
4.三元运算
<p :style="{ backgroundColor: heihei ? 'red' : 'green' }"></p>
data: {
return{
heihei:true
}
}
原文:vue2 v-for ,虚拟dom ,diff算法,动态class,动态style_vue2 动态class-CSDN博客