이유: 여러 구성 요소 인스턴스 개체가 동일한 데이터를 공유하고 함수 형태로 데이터 오염을 일으키는 것을 방지하기 위해 initData가 팩토리 함수로 사용될 때 새 데이터 개체가 반환됩니다. 컴포넌트의 데이터를 함수로 작성하면 데이터를 함수 반환값 형태로 정의하므로, 컴포넌트를 재사용할 때마다 프라이빗 데이터를 생성하는 것과 마찬가지로 고유한 범위로 새로운 데이터가 반환됩니다. 각 구성 요소 인스턴스에 대해 데이터 공간을 사용하면 각 구성 요소 인스턴스가 자체 데이터를 유지할 수 있습니다.
이 튜토리얼의 운영 환경: windows7 시스템, vue3 버전, DELL G3 컴퓨터.
1. 데이터의 인스턴스 정의와 컴포넌트 정의의 차이점
vue 인스턴스를 정의할 때 데이터 속성은 객체이거나 함수일 수 있습니다.
const app = new Vue({ el:"#app", // 对象格式 data:{ foo:"foo" }, // 函数格式 data(){ return { foo:"foo" } } })
컴포넌트에 정의된 데이터 속성은 function
컴포넌트 데이터를 객체
Vue.component('component1',{ template:`<div>组件</div>`, data:{ foo:"foo" }})
로 직접 정의하면 경고 메시지가 표시됩니다
주의사항: 반환되는 데이터는 각 컴포넌트 인스턴스의 함수여야 합니다
2. 컴포넌트 데이터 정의 함수와 객체의 차이점
위에서 컴포넌트 데이터가 함수여야 한다고 언급했는데 왜 그럴지 생각해보신 적 있으신가요?
컴포넌트를 정의하면 Vue는 결국 Vue.extend()를 통해 컴포넌트 인스턴스를 형성합니다
여기서 우리는 컴포넌트 생성자를 모방하고 데이터 속성을 정의하며 객체의 형식을 사용합니다
function Component(){ } Component.prototype.data = { count : 0 }
두 개의 컴포넌트 인스턴스 생성
const componentA = new Component() const componentB = new Component()
컴포넌트A 컴포넌트의 데이터 속성 값을 수정하면, 컴포넌트B의 값도 변경됩니다
console.log(componentB.data.count) // 0 componentA.data.count = 1 console.log(componentB.data.count) // 1
이유는 둘이 동일한 메모리 주소를 공유하고, 컴포넌트A에서 수정한 내용도 컴포넌트B에 영향을 미치기 때문입니다. [학습 영상 공유: vue 영상 튜토리얼, 웹 프론트엔드 영상]
함수의 형태를 채택하면 이런 상황은 발생하지 않습니다. (함수가 반환하는 객체의 메모리 주소가 동일하지 않습니다.) )
function Component(){ this.data = this.data() } Component.prototype.data = function (){ return { count : 0 } }
commentA 구성요소 수정 데이터 속성의 값, 구성요소B의 값은 영향을 받지 않습니다.
console.log(componentB.data.count) // 0 componentA.data.count = 1 console.log(componentB.data.count) // 0
vue 구성요소는 많은 인스턴스를 가질 수 있으며 함수는 새로운 데이터 형식을 반환하는 데 사용됩니다. 각 인스턴스 객체는 다른 인스턴스 객체의 데이터에 의해 오염되지 않습니다
3. 원리 분석
먼저 Vue 초기화 데이터의 코드를 보면 데이터의 정의가 함수일 수도 있고 객체일 수도 있습니다.
소스 코드 위치: /vue-dev/src/core/instance/state .js
/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既能是object也能是function,那为什么还会出现上文警告呢?
别急,继续看下文
组件在创建的时候,会进行选项的合并
源码位置:/vue-dev/src/core/util/options.js
自定义组件会进入mergeOptions进行选项合并
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 ) } ... }
定义data会进行数据校验
源码位置:/vue-dev/src/core/instance/init.js
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); };data는 객체이자 함수일 수 있는데 왜 위 경고가 나타나는 걸까요? 걱정하지 마세요. 아래를 계속 읽어보세요
컴포넌트가 생성되면 옵션이 병합됩니다.소스 코드 위치: /vue-dev/src/core/util/options.js
rrreee
데이터 정의에서 데이터 확인이 수행됩니다.소스 코드 위치:/vue-dev/src/core/instance/init.js
이것 vm 인스턴스가 정의되지 않은 경우 if 판단을 입력하고 데이터 유형이 함수가 아닌 경우 경고가 나타납니다 rrreee
참고:
(학습 영상 공유: 웹 프론트엔드 개발, 기본 프로그래밍 영상)
위 내용은 vue 구성 요소의 데이터가 함수인 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!