关于 Vue 中 vm.$nextTick、vm.$set 的使用和理解

vm 表示 new Vue 实例对象

vm.$nextTick

vue官网中关于 nextTick 的介绍:将回调延迟到下次 DOM 更新循环之后执行。在修改数据之后立即使用它,然后等待 DOM 更新。
$nextTick() 返回一个 Promise 对象(自2.1.0),所以可以使用新的 ES2017 async/await 语法完成相同的事情。

在实际开发项目中,有时需要基于更新后的 DOM 状态来做点什么(如项目需求一个轮播图swiper-slide一次同时显示个数为5,小于5个时不显示左右箭头,就需要先渲染数据再判断有几个slide显示了),在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。

// 示例
methods: {
	this.$nextTick(function() {
		  var slide = document.querySelector(".swiper-wrapper");
		  var btns = document.querySelectorAll(".swiper-button");
		  var slideLen = slide.children.length;
		  if (slideLen < 6) {
		    for (var i = 0; i < btns.length; i++) {
		      btns[i].style.display = "none";
		    }
		  }
	});
}

vm.$set

注:对象不能是 Vue 实例,或者 Vue 实例的根数据对象。

  • 问题概述
    在项目开发的过程中,经常会遇到这种情况:为data中的某一个对象添加一个属性,并确保这个新属性同样是响应式的,且触发视图更新。
// 例如
<template>  
  <div class="demo">
    <button @click="setMessage">添加属性button>
    <p>姓名:{{ student.name }}p>
    年龄:<input type="text" v-model="student.age">
  div>
template>
<script>
export default {
  data() {
    return {
      student: {
        name: "lili"
      }
    };
  },
  methods: {
    setMessage() {
        this.student.age = 23
        console.log(this.student);
    }
  }
};
</script>

点击按钮在控制台和页面中显示效果如下:
关于 Vue 中 vm.$nextTick、vm.$set 的使用和理解_第1张图片
可以看到在这个对象身上已经有了该属性,但是视图层并没有更新该数据,是什么造成的呢?由于受JavaScript 的限制,vue.js 不能监听对象属性的添加和删除,因为在vue组件初始化的过程中,会调用 getter 和 setter 方法,所以该属性必须是存在在 data 中,视图层才会响应该数据的变化。

  • 解决方案
    1\ 使用 this.$set(obj, key, value) / vue.set(obj, key, value)
<script>
export default {
  data() {
    return {
      student: {
        name: "lili"
      }
    };
  },
  methods: {
    setMessage() {
        this.$set(this.student, 'age', 23)
        console.log(this.student);
    }
  }
};
</script>

2\ 通过 Object.assign(target, sources) 方法

<script>
export default {
  data() {
    return {
      student: {
        name: "lili"
      }
    };
  },
  methods: {
    setMessage() {
        this.student.age = 23
        this.student = Object.assign({}, this.student)  // 合并对象
        console.log(this.student);
    }
  }
};
</script>

点击按钮在控制台和页面中显示效果如下:
可以发现通过这两种方式为对象添加属性之后,对象身上多了 get 和 set 方法,所以,此时我们再次操作该属性的时候,就会引起视图的更新了
关于 Vue 中 vm.$nextTick、vm.$set 的使用和理解_第2张图片

你可能感兴趣的:(vue)