vue2 v-for ,虚拟dom ,diff算法,动态class,动态style

一、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博客

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值