Reason: To prevent multiple component instance objects from sharing the same data and causing data pollution; in the form of a function, when initData is used as a factory function, a new data object will be returned. When the data in the component is written as a function, the data is defined in the form of function return value, so that every time the component is reused, a new data will be returned with its own scope, similar to creating a private data for each component instance. The data space allows each component instance to maintain its own data.
The operating environment of this tutorial: windows7 system, vue3 version, DELL G3 computer.
1. The difference between instance and component definition data
When defining a vue instance, the data attribute can be either an object or an Function
const app = new Vue({ el:"#app", // 对象格式 data:{ foo:"foo" }, // 函数格式 data(){ return { foo:"foo" } } })
The data attribute defined in the component can only be a function
If the component data is directly defined as an object
Vue.component('component1',{ template:`<div>组件</div>`, data:{ foo:"foo" }})
, you will get a warning message
Warning: The returned data should be a function in each component instance
2. The difference between component data definition functions and objects
It was mentioned above that component data must be a function. I wonder if you have ever thought about why this is?
When we define a component, Vue will eventually form a component instance through Vue.extend()
Here we imitate the component constructor, define the data attribute, and adopt the form of an object
function Component(){ } Component.prototype.data = { count : 0 }
Create two component instances
const componentA = new Component() const componentB = new Component()
Modify the value of the data attribute of the componentA component, and the value in componentB has also changed
console.log(componentB.data.count) // 0 componentA.data.count = 1 console.log(componentB.data.count) // 1
The reason for this is that it is shared by both At the same memory address, the content modified by componentA also affects componentB. [Learning video sharing: vue video tutorial, web front-end video]
If we use the form of a function, this will not happen (the object returned by the function The memory addresses are not the same)
function Component(){ this.data = this.data() } Component.prototype.data = function (){ return { count : 0 } }
Modify the value of the data attribute of the componentA component, and the value in componentB will not be affected
console.log(componentB.data.count) // 0 componentA.data.count = 1 console.log(componentB.data.count) // 0
The vue component may have many instances, and the function is used to return a new data form, so that the data of each instance object will not be contaminated by the data of other instance objects
3. Principle analysis
First of all, you can take a look Vue initializes the data code. The definition of data can be a function or an object.
Source code location: /vue-dev/src/core/instance/state.js
function initData (vm: Component) { let data = vm.$options.data data = vm._data = typeof data === 'function' ? getData(data, vm) : data || {} ... }
data can be both object and function, so why does the above warning appear?
Don’t worry, continue reading below
When the component is created, the options will be merged
Source code location:/vue-dev/src/core/ util/options.js
Customized components will enter mergeOptions for option merging
Vue.prototype._init = function (options?: Object) { ... // merge options if (options && options._isComponent) { // optimize internal component instantiation // since dynamic options merging is pretty slow, and none of the // internal component options needs special treatment. initInternalComponent(vm, options) } else { vm.$options = mergeOptions( resolveConstructorOptions(vm.constructor), options || {}, vm ) } ... }
Defining data will perform data verification
Source code location: / vue-dev/src/core/instance/init.js
At this time, the vm instance is undefined and enters the if judgment. If the data type is not function, a warning will appear
strats.data = function ( parentVal: any, childVal: any, vm?: Component ): ?Function { if (!vm) { if (childVal && typeof childVal !== "function") { process.env.NODE_ENV !== "production" && warn( 'The "data" option should be a function ' + "that returns a per-instance value in component " + "definitions.", vm ); return parentVal; } return mergeDataOrFn(parentVal, childVal); } return mergeDataOrFn(parentVal, childVal, vm); };
4. Conclusion
The root instance object data can be an object or a function (the root instance is a singleton), which will not cause data pollution
Component instance object data must be a function. The purpose is to prevent multiple component instance objects from sharing the same data and causing data pollution. In the form of a function, it will be used as a factory function when initData will return a new data object
Description:
The components in vue are used Reusable, in order to prevent data reuse, define it as a function.
The data data in the vue component should be isolated from each other and not affect each other. Every time the component is reused, the data data should be copied once. After that, when a certain place is reused When the data data in the used local component is changed, the data data of other reused local components will not be affected, so you need to return an object as the status of the component through the data function.
When we write the data in the component as a function, the data is defined in the form of function return value, so that every time the component is reused, a new data will be returned, with its own Scope is similar to creating a private data space for each component instance, allowing each component instance to maintain its own data.
When the date of our component is simply written in object form, these instances use the same constructor. Due to the characteristics of JavaScript, all component instances share one data, so It will lead to a result that changes everything.
(Learning video sharing: web front-end development, Basic programming video)
The above is the detailed content of Why is data in the vue component a function?. For more information, please follow other related articles on the PHP Chinese website!