Vue API 详解(1)—— data

1. 官方文档:https://cn.vuejs.org/v2/api/#data

2. 首先这里涉及到一个面试题:组件中的 data 为什么必须是函数形式,而不能是对象形式?

  原因在于,组件可能会被多次实例化使用,如果组件中的 data 仍然是对象形式,则所有的实例化组件共享引用同一个 data 对象,其中一个组件实例改变 data 中的数据,会导致其他实例中 data 数据同时修改。因此需要将其设置为一个函数返回对象,这样每次实例化一个组件,每个组件拿到的是全新的一个属于自己的 data 对象,不会引起共享问题。

3. 涉及到 Vue 响应式原理

  data 中的属性会被递归的利用 Object.defineProperty 进行数据劫持,设置属性的 get 和 set 方法。

4. Vue 中的 data 一旦被观察过,那么之后向其中添加的属性,就不再是响应式的属性,这个后面会详细介绍,因为还涉及到一个问题:data 中数组、对象是响应式的吗 ?

5. 实例创建后,可以通过 vm.$data 访问 data 对象,同时 Vue 实例也代理了 data 对象上的所有属性,因此有两种方式访问属性,vm.$data.xxx / vm.xxx 【xxx为属性名】,以 _ 或 $ 开头的 property 不会被 Vue 实例代理,因为它们可能和 Vue 内置的 property、API 方法冲突。你可以使用例如 vm.$data._property 的方式访问这些 property。

Example:

<script>
  const app = new Vue({
    el: '#app',
    data() {
      return {
        message: 'Hello Vue-API-data.'
      }
    }
  });
  console.log(app.$data);
  console.log(app.$data.message);
  console.log(app.message)
</script>

Vue API 详解(1)—— data

 6. 对 4. 进行扩展补充:参考官方文档:https://cn.vuejs.org/v2/guide/reactivity.html

  由于 JavaScript 的限制,响应式原理无法追踪数组和对象中属性的变化【官方文档写的是无法追踪数组和对象的变化,我觉得不严谨,对象和数组改变了还是可以追踪到的,是它们内部属性的变化无法追踪】,但是我们可以通过一些方法回避这个缺陷。

  【1】对于对象:Vue 无法检测 property 的添加和删除,由于在初始化实例时,Vue 就对 property 进行了数据劫持,设置 set 和 get 方法,所以 property 必须提前在 data 对象上存在才可以转化为响应式的.

  虽然不允许初始化实例后在 data 中添加属性,但是如果 data 最初有一个空对象,那么可以使用 Vue.set 或者 vm.$set 向这个空对象中添加响应式 property.

(1)对于添加单个属性时:

  const app = new Vue({
    el: '#app',
    data() {
      return {
        message: 'Hello Vue-API-data.',
        obj: {},
     obj_: {} } } });
  app.obj.not_reactive = 'not reactive'; // 非响应式添加
  Vue.set(app.obj, 'reactive', 'reactive property'); // 响应式

最初:

Vue API 详解(1)—— data

 通过 Vue.set 添加的属性,更改值后:

Vue API 详解(1)—— data

 直接添加属性,更改值后:

Vue API 详解(1)—— data

(2)对于添加多个属性时,可能会用到 Object.assign(dest, src);

  /* 添加多个属性 */
  Object.assign(app.obj_, {
    name: "James",
    age: 18
  });

Vue API 详解(1)—— dataVue API 详解(1)—— data

但是我们看到了像以上形式直接使用 Object.assign 不是响应式的,那么我们需要这样使用:

  /* 添加多个属性 */
  app.obj_ = Object.assign({}, app.obj_, {
    name: "James",
    age: 18
  });

   【2】对于数组:

上一篇:报错java.lang.IllegalArgumentException: The maximum length of cell contents (text) is 32,767 character


下一篇:AcWing 767. 信息加密