Vue에서 데이터를 초기화하는 방법은 무엇입니까?

青灯夜游
풀어 주다: 2022-12-26 18:09:35
원래의
3704명이 탐색했습니다.

Vue에는 데이터를 초기화하는 두 가지 방법이 있습니다. 1. 객체 모드, 구문 "var data = { 키-값 쌍 }" 2. 함수 모드, 구문 "data: function () {return { 키-값 쌍 }}" . 구성 요소 및 확장의 데이터 초기화는 객체가 될 수 없습니다. 그렇지 않으면 오류가 보고됩니다. 구성 요소의 데이터에 함수 모드를 사용하는 목적은 여러 구성 요소 인스턴스 개체가 동일한 데이터를 공유하여 데이터 오염을 일으키는 것을 방지하는 것입니다.

Vue에서 데이터를 초기화하는 방법은 무엇입니까?

이 튜토리얼의 운영 환경: windows7 시스템, vue3 버전, DELL G3 컴퓨터.

Vue 데이터에는 함수와 객체라는 두 가지 초기화 방법이 있는데, 이 두 가지 상황에 적용 가능한 시나리오는 무엇인가요? 보편적일 수 있을까? 이 두 가지 질문을 가지고 함께 분석해 봅시다

데이터 초기화

// 代码来源于官网示例

// 第一种定义方式
var data = { a: 1 }

// 直接创建一个实例
var vm = new Vue({
  data: data
})

// Vue.extend() 中 data 必须是函数
var Component = Vue.extend({
// 第二种定义方式
  data: function () {
    return { a: 1 }
  }
})
로그인 후 복사

위 코드는 단순히 데이터를 정의하는 두 가지 방법을 설명합니다

  • function

  • object

에도 있습니다. 공식 홈페이지 데모 확장에서는 데이터 초기화에 객체를 사용할 수 없다는 점을 강조합니다. 그렇다면 왜?

소스 코드 분석

공식 웹사이트 데모에 따르면 Vue.extend의 ​​데이터 초기화는 Object가 될 수 없습니다. 강제로 Object로 작성하면 어떻게 될까요?

var Component = Vue.extend({
  data: { a: 1 }
})
로그인 후 복사

실행 후 Chrome 콘솔에서 직접 오류를 보고하며 정보는 다음과 같습니다.

vue.esm.js?efeb:591 [Vue warn]: The "data" option should be a function that returns a per-instance value in component definitions.
로그인 후 복사

소스 코드와 오류 메시지를 분석하여 Vue.extend가 트리거되면 병합 작업을 수행하고 기본 구성 요소(내부)를 결합합니다. vmode, Translation 등) with 확장에서 정의한 정보는 mergeField를 통해 옵션으로 병합됩니다. 데이터에 병합되면 해당 데이터가 함수인지 확인하는 Strats.data가 트리거됩니다. 여기에는 필터, 구성 요소 등이 있습니다. 데이터는 두 가지 병합 프로세스를 따릅니다. 자세한 내용은 다음과 같이 코드 주석을 참조하세요.

// vue.extend 源码地址https://github.com/vuejs/vue/blob/dev/src/core/global-api/extend.js

  Vue.extend = function (extendOptions: Object): Function {
  ...
  // 在这里会触发mergeOptions方法
  Sub.options = mergeOptions(
      Super.options,
      extendOptions
    )
  ...
}

// mergeOptions 源码地址https://github.com/vuejs/vue/blob/dev/src/core/util/options.js

export function mergeOptions (
  parent: Object,
  child: Object,
  vm?: Component
): Object {
  ...

  const options = {}
  let key
  // parent对象内包含components、filter,、directive
  for (key in parent) {
    mergeField(key)
  }
  // child对象内对应的是Vue.extend内定义的参数
  for (key in child) {
    if (!hasOwn(parent, key)) {
      mergeField(key)
    }
  }
  function mergeField (key) {
  // 这一步是根据传入的key找到不同的合并策略filter、components、directives用到合并策略是这个方法mergeAssets和data用到的不一样,当合并到data的时候会进入专属的合并策略方法内
    const strat = strats[key] || defaultStrat
    options[key] = strat(parent[key], child[key], vm, key)
  }
}

// strats.data  源码地址https://github.com/vuejs/vue/blob/dev/src/core/util/options.js
strats.data = function (
  parentVal,
  childVal,
  vm
) {
  if (!vm) {
  // 如果data不是function的话会直接走下面的报错信息
    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)
};
로그인 후 복사

다른 상황

사실 위 코드는 단순한 프로세스입니다. 실제 개발에서는 유사한 상황이 포함됩니다. 하위 구성 요소 내에서 데이터는 모두 하단에서 mergeOptions 메서드를 호출하기 때문에 경로에서 객체로 정의할 수 없습니다. vue가 초기화되면 다음이 수행됩니다.

new Vue({
  data: {
    linke: '//sinker.club'
  }
})
로그인 후 복사

알겠습니다. 위에서 너무 많은 얘기를 했는데, 이렇게 한다는 게 무슨 뜻인가요? 왜 그러한 상황은 객체로 정의될 수 없는 걸까요? 사실 이 질문에 대답하려면 js 자체로 돌아가야 합니다. 우리 모두 알고 있듯이 js의 데이터 유형은 참조 유형과 기본 유형으로 구분됩니다. 참조 유형은 Object, Array 및 Function이 아닙니다. 여기에 설명되어 있습니다

  var obj = {link: '//www.sinker.club'}
  var obj2 = obj
  var obj3 = obj
  obj2.link = "//gitlab.sinker.club"
  console.log(obj3.link) // "//gitlab.sinker.club"
로그인 후 복사

위 코드는 문제를 반영합니다. obj3과 obj2 모두 메모리의 주소를 가리키므로 obj2를 수정하면 obj3에 영향을 미치기 때문입니다. 물론 이 문제를 해결하기 위해 전체 복사를 사용할 수 있습니다

JSON.parse(JSON.stringify(obj))

deepClone(obj)

  • 그러나 이 두 가지 방법은 개발이 필요하거나 프레임워크에서 데이터 양이 많을 때마다 전체 복사본을 만들어야 합니다. Vue는 성능에 우호적이지 않습니다. 그러면 Vue는 이를 어떻게 수행합니까? 데이터를 함수로 정의하세요

    function data() {
      return {
       link: '//sinker.club'
      }
    }
    
    var obj = test()
    var obj2 = test()
    
    obj2.link ="//gitlab.sinker.club"
    console.log(obj.link) '//sinker.club'
    로그인 후 복사

  • 이 작업을 수행하는 이유는 무엇인가요? 솔루션 시나리오는 무엇입니까?

예를 들어 하위 구성 요소를 정의하면 데이터가 개체로 정의됩니다. 이 구성 요소는 여러 위치에서 참조됩니다. 이 구성 요소를 참조하는 데이터 중 하나가 수정되면 이 구성 요소를 참조하는 다른 데이터가 수정됩니다. 변경, 종료.

확장 지식:

vue 인스턴스를 정의할 때 데이터 속성은 객체 또는 함수일 수 있습니다.

const app = new Vue({
    el:"#app",
    // 对象格式
    data:{
        foo:"foo"
    },
    // 函数格式
    data(){
        return {
             foo:"foo"
        }
    }
})
로그인 후 복사

컴포넌트에 정의된 데이터 속성은 함수일 뿐입니다

구성 요소 데이터가 객체

Vue.component('component1',{
    template:`<div>组件</div>`,
    data:{
        foo:"foo"
    }})
로그인 후 복사
로 직접 정의된 경우 경고 메시지가 표시됩니다

설명:

Vue 구성 요소는 재사용을 위해 사용됩니다. 데이터 재사용을 방지하려면 함수로 정의하세요. Vue에서 데이터를 초기화하는 방법은 무엇입니까?

vue 구성 요소의 데이터 데이터는 서로 격리되어야 하며 서로 영향을 주지 않아야 합니다. 구성 요소를 재사용할 때마다 데이터 데이터를 한 번 복사해야 합니다. 변경 시 재사용되는 다른 로컬 컴포넌트의 데이터 데이터는 영향을 받지 않으므로 데이터 함수를 통해 컴포넌트의 상태로 개체를 반환해야 합니다.

  • 컴포넌트의 데이터를 함수로 작성하면 데이터가 함수 반환 값 형식으로 정의되므로 컴포넌트를 재사용할 때마다 다음과 유사하게 자체 범위로 새 데이터가 반환됩니다. 각 구성 요소 인스턴스는 개인 데이터 공간을 생성하여 각 구성 요소 인스턴스가 자체 데이터를 유지할 수 있도록 합니다.

  • 컴포넌트의 날짜를 단순히 객체 형식으로 작성하는 경우 이러한 인스턴스는 동일한 생성자를 사용합니다. JavaScript의 특성상 모든 컴포넌트 인스턴스는 동일한 데이터를 공유하므로 하나의 변경이 발생하고 모든 변경이 발생합니다.

【관련 추천: vuejs 비디오 튜토리얼, 웹 프론트엔드 개발

위 내용은 Vue에서 데이터를 초기화하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿