function initData (vm: Component) {
  / / to get the data
  let data = vm.$options.data

  // If the type of data is a function, execute getData() and use the result as the value of the data option, otherwise it is data
  // Imagine a scenario where a component comp is defined that is executed only once when it is declared.
  Data: {count: 1} is initialized to the same address
  // This will cause instance pollution. Everyone is using the same data option.
  // If it is a component, you can only write data, otherwise an error will be reported.

  // Vue does not allow us to define data directly as an object in the component. In order to avoid mutual contamination between multiple instances of the component, we define data as a factory function.

  // The root instance of data can be directly defined as an object, because the data in vue2 is a singleton, only one of them will occur, so there is no possibility of mutual contamination.

  data = vm._data = typeof data === 'function'
    ? getData(data, vm)
    : data || {}
  // If data is not an empty object
  if(! isPlainObject(data)) { data = {} process.env.NODE_ENV ! = ='production' && warn(
      'data functions should return an object:\n' +
      'https://vuejs.org/v2/guide/components.html#data-Must-Be-a-Function',
      vm
    )
  }
Copy the code

conclusion

A Vue component can have multiple instances. If you define data as an object, they will share a single data object, and state changes will affect all component instances, which is not reasonable. It is defined as a function, and will be returned to the new data object as a factory function in initData, effectively avoiding the problem of state pollution before multi-instance. This restriction does not exist in the Vue root instance creation process, also because there can only be one root instance, do not need to worry about this situation. In source data initialization, found that detects the form of data to perform the execution of his specific way, another root instance when creating may at the time of merger option, he would have instance to only the root instance, he can effectively avoid the root instance validation, and a component module instance may not have at that time, There is no way to circumvent the validation if logic and check the type of data directly, so there is no way for the user to define data as an object in the component when writing code.