xgqfrms™, xgqfrms® : xgqfrms's offical website of cnblogs! xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!

vue 组件响应式更新原理 All In One

vue 组件响应式更新原理 All In One

vue 组件更新原理 / vue 组件响应式原理

  1. 依赖收集
  2. 监听,通知
  3. 重绘

https://cn.vuejs.org/v2/guide/reactivity.html#如何追踪变化

对象

https://cn.vuejs.org/v2/guide/reactivity.html#对于对象

var vm = new Vue({
  data: {
    a: 1
  }
});
// `vm.a` 是响应式的

vm.b = 2;
// `vm.b` 是非响应式的

// Vue.set(vm.someObject, 'b', 2)

this.$set(this.someObject, "b", 2);

this.someObject = Object.assign({}, this.someObject, { a: 1, b: 2 });

数组

https://cn.vuejs.org/v2/guide/reactivity.html#对于数组

var vm = new Vue({
  data: {
    items: ["a", "b", "c"]
  }
});
vm.items[1] = "x"; // 不是响应性的
vm.items.length = 2; // 不是响应性的

// Vue.set
Vue.set(vm.items, indexOfItem, newValue);
vm.$set(vm.items, indexOfItem, newValue);

// Array.prototype.splice 就地复用
vm.items.splice(indexOfItem, 1, newValue);

vm.items.splice(newLength);

$nextTick


Vue Diff 算法 / virtual DOM

虚拟 DOM / VNode 树


https://cn.vuejs.org/v2/guide/render-function.html#节点、树以及虚拟-DOM

https://cn.vuejs.org/v2/guide/syntax.html#

虚拟 DOM Diff 算法 / 就地复用

key 的特殊 attribute 主要用在 Vue 的虚拟 DOM 算法,在新旧 nodes 对比时辨识 VNodes。
如果不使用 key,Vue 会使用一种最大限度减少动态元素并且尽可能的尝试就地修改/复用相同类型元素的算法。
而使用 key 时,它会基于 key 的变化重新排列元素顺序,并且会移除 key 不存在的元素。

https://cn.vuejs.org/v2/api/#key

注意,updated 不会保证所有的子组件也都被重新渲染完毕。如果你希望等到整个视图都渲染完毕,可以在 updated 里使用 vm.$nextTick:

updated: function () {
  this.$nextTick(function () {
    //  仅在整个视图都被重新渲染之后才会运行的代码     
  })
}

https://cn.vuejs.org/v2/api/#updated

生命周期图示

https://cn.vuejs.org/v2/guide/instance.html#生命周期图示

DOM tree

https://javascript.info/dom-nodes

render function & $slots

Vue.component('anchored-heading', {
  render: function (createElement) {
    return createElement(
      'h' + this.level,   // 标签名称
      this.$slots.default // 子节点数组
    )
  },
  props: {
    level: {
      type: Number,
      required: true
    }
  }
})

https://cn.vuejs.org/v2/api/#vm-slots

demo

  methods: {
    // 1. 通过调用父组件的方法,更改 props ✅
    updateForm(obj = {}, index = 0) {
      // this.formData.creativeList[index] = obj;
      // console.log("update data", obj, index);
      if (!this.formData.creativeList[index]) {
        this.formData.creativeList[index] = {};
      } else {
        // ✅对象属性合并
        obj = Object.assign({}, this.formData.creativeList[index], obj);
        // obj = {
        //   ...this.formData.creativeList[index],
        //   ...obj,
        // };
      }
      // ❌ 非响应式,数组
      // Object.assign(this.formData.creativeList[index], obj);
      // ✅ 响应式,数组, this.$set
      // this.$set(this.formData.creativeList, index, obj);
      // ✅ 响应式,数组,Array.splice 就地复用
      this.formData.creativeList.splice(
        this.formData.creativeList[index],
        1,
        obj
      );
    },
    // 2. 通过 Array[0].Object 对象引用,直接修改 props 的 formData 属性? 不推荐 ❌
  },

refs

https://cn.vuejs.org/v2/guide/reactivity.html

https://codesandbox.io/s/shit-vue-docs-4xwiu?file=/readme.md:19-29

in-place 就地复用

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice

https://www.cnblogs.com/xgqfrms/p/10711789.html

https://stackoverflow.com/questions/958908/how-do-you-reverse-a-string-in-place-in-javascript



©xgqfrms 2012-2020

www.cnblogs.com 发布文章使用:只允许注册用户才可以访问!

原创文章,版权所有©️xgqfrms, 禁止转载 🈲️,侵权必究⚠️!


posted @ 2021-05-27 11:19  xgqfrms  阅读(101)  评论(2编辑  收藏  举报