vue计算属性,过滤器,侦听器,JS中的回流与重绘

重绘与回流(重排)的概念:

回流(重排): 当浏览器必须重新处理和绘制部分或全部页面时,回流就会发生 

 重绘:不影响布局, 只是标签页面发生变化, 重新绘制

 注意: 回流(重排)必引发重绘, 重绘不一定引发回流(重排)

 JSON的方法使用:

JSON.stringify(JS数据) - 把JS数据序列化成JSON格式字符串

JSON.parse(JSON字符串)  - 把JSON格式化字符串, 再转回成JS数据

v-for 更新监测

数组变更方法, 就会导致v-for更新, 页面更新

数组非变更方法, 返回新数组, 就不会导致v-for更新, 可采用覆盖数组或this.$set()

 代码:

<template>
  <div>
    <ul>
      <li v-for="(val, index) in arr" :key="index">
        {{ val }}
      </li>
    </ul>
    <button @click="revBtn">数组翻转</button>
    <button @click="sliceBtn">截取前3个</button>
    <button @click="updateBtn">更新第一个元素值</button>
  </div>
</template>

<script>
export default {
  data(){
    return {
      arr: [5, 3, 9, 2, 1]
    }
  },
  methods: {
    revBtn(){
      // 1. 数组翻转可以让v-for更新
      this.arr.reverse()
    },
    sliceBtn(){
      // 2. 数组slice方法不会造成v-for更新
      // slice不会改变原始数组
      // this.arr.slice(0, 3)

      // 解决v-for更新 - 覆盖原始数组
      let newArr = this.arr.slice(0, 3)
      this.arr = newArr
    },
    updateBtn(){
      // 3. 更新某个值的时候, v-for是监测不到的
      // this.arr[0] = 1000;

      // 解决-this.$set()
      // 参数1: 更新目标结构
      // 参数2: 更新位置
      // 参数3: 更新值
      this.$set(this.arr, 0, 1000)
    }
  }
}
</script>

<style>

</style>

 以下方法会触发v-for更新

push()

pop()

shift()

unshift()

splice()

sort()

reverse()

以下不会触发v-for更新  

slice()

filter()

concat()

diff算法

 无key - 就地更新:v-for不会移动DOM, 而是尝试复用, 就地更新,如果需要v-for移动DOM, 你需要用特殊 attribute key 来提供一个排序提示

代码:

<template>
  <div>
   <ul id="myUL">
    <li v-for="str in arr">
        {{ str }} 
        <input type="text">
     </li>
   </ul>
   <button @click="addFn">下标为1的位置新增一个</button>
  </div>
</template>
<script>
 export default {
    data(){
        return {
            arr: ["老大", "新来的", "老二", "老三"]
        }
    },
    methods: {
        addFn(){
            this.arr.splice(1, 0, '新来的')
        }
    }
 };
</script>

 有key - 值为索引 :还是就地更新;因为新旧虚拟DOM对比, key存在就复用此标签更新内容, 如果不存在就直接建立一个新的

代码:  

<template>
  <div>
    <ul id="myUL">
      <li v-for="(str, index) in arr" :key="index">
        {{ str }} 
        <input type="text">
      </li>
    </ul>
    <button @click="addFn">下标为1的位置新增一个</button>
  </div>
</template>
<script>
export default {
    data(){
        return {
            arr: ["老大", "新来的", "老二", "老三"]
        }
    },
    methods: {
        addFn(){
            this.arr.splice(1, 0, '新来的')
        }
    }
};
</script>

 

有key - 值为id :key的值只能是唯一不重复的, 字符串或数值

   v-for不会移动DOM, 而是尝试复用, 就地更新,如果需要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>

 

过滤器

 过滤器只能用在, 插值表达式和v-bind表达式

语法:

  • Vue.filter("过滤器名", (值) => {return "返回处理后的值"})

  • filters: {过滤器名字: (值) => {return "返回处理后的值"}

传参和多过滤器

语法:

    过滤器传参: vue变量 | 过滤器(实参)

    多个过滤器: vue变量 | 过滤器1 | 过滤器2

注意:vue3已经没有过滤器,我们也可以自己使用函数调用,返回一个结果

计算属性

语法:

computed: {
    "计算属性名" () {
        return "值"
    }
}

案例:将2个数的和显示到页面上

<template>
  <div>
    <p>{{ num }}</p>
  </div>
</template>

<script>
export default {
  data(){
    return {
      a: 10,
      b: 20
    }
  },
 
 // 注意: 计算属性和data属性都是变量-不能重名
 // 注意2: 函数内变量变化, 会自动重新计算结果返回
  computed: {
    num(){
      return this.a + this.b
    }
  }
}
</script>

<style>

</style>

 注意: 计算属性也是vue数据变量, 所以不要和data里重名, 用法和data相同

总结:一个数据, 依赖另外一些数据计算而来的结果

缓存

计算属性是基于它们的依赖项的值结果进行缓存的,只要依赖的变量不变, 都直接从缓存取结果

侦听器(watch)

语法:

watch: {
    "被侦听的属性名" (newVal, oldVal){
        
    }
}

 代码:

<template>
  <div>
    <input type="text" v-model="name">
  </div>
</template>

<script>
export default {
  data(){
    return {
      name: ""
    }
  },
  watch: {
    // newVal: 当前最新值
    // oldVal: 上一刻值
    name(newVal, oldVal){
      console.log(newVal, oldVal);
    }
  }
}
</script>

<style>

</style>

深度侦听和立即执行

语法:

watch: {
    "要侦听的属性名": {
        immediate: true, // 立即执行
        deep: true, // 深度侦听复杂类型内变化
        handler (newVal, oldVal) {
            
        }
    }
}

代码:

<template>
  <div>
    <input type="text" v-model="user.name">
    <input type="text" v-model="user.age">
  </div>
</template>

<script>
export default {
  data(){
    return {
      user: {
        name: "",
        age: 0
      }
    }
  },
  watch: {
    user: {
      handler(newVal, oldVal){
        // user里的对象
        console.log(newVal, oldVal);
      },
      deep: true,
      immediate: true
    }
  }
}
</script>

<style>

</style>


版权声明:本文为m0_57923701原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。