Maison  >  Article  >  interface Web  >  Pourquoi les données du composant vue sont-elles une fonction ?

Pourquoi les données du composant vue sont-elles une fonction ?

青灯夜游
青灯夜游original
2022-12-01 19:46:2911772parcourir

Raison : Pour empêcher plusieurs objets d'instance de composants de partager les mêmes données et de provoquer une pollution des données sous la forme d'une fonction, lorsque initData est utilisé comme fonction d'usine, un nouvel objet de données sera renvoyé. Lorsque les données du composant sont écrites sous forme de fonction, les données sont définies sous la forme d'une valeur de retour de fonction, de sorte que chaque fois que le composant est réutilisé, une nouvelle donnée sera renvoyée avec sa propre portée, similaire à la création d'une donnée privée. pour chaque instance de composant. L'espace de données permet à chaque instance de composant de conserver ses propres données.

Pourquoi les données du composant vue sont-elles une fonction ?

L'environnement d'exploitation de ce tutoriel : système windows7, version vue3, ordinateur DELL G3.

1. La différence entre la définition d'instance et de composant de données

Lors de la définition d'une instance de vue, l'attribut de données peut être soit un objet, soit une fonction

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

L'attribut de données défini dans un composant ne peut être qu'un function

Si les données du composant sont directement définies comme un objet

Vue.component('component1',{
    template:`<div>组件</div>`,
    data:{
        foo:"foo"
    }})

, vous recevrez un message d'avertissement

Pourquoi les données du composant vue sont-elles une fonction ?

Remarque d'avertissement : les données renvoyées doivent être une fonction dans chaque instance du composant

2. Données du composant fonction de définition et La différence entre les objets

Il a été mentionné ci-dessus que les données des composants doivent être une fonction. Je me demande si vous avez déjà réfléchi à la raison pour laquelle cela se produit ?

Lorsque nous définissons un composant, Vue finira par former une instance de composant via Vue.extend()

Ici, nous imitons le constructeur du composant, définissons l'attribut data et utilisons la forme d'un objet

function Component(){
 
}
Component.prototype.data = {
	count : 0
}

Créons deux instances de composant

const componentA = new Component()
const componentB = new Component()

Modifiez la valeur de l'attribut data du composant composantA, et la valeur dans le composantB change également

console.log(componentB.data.count)  // 0
componentA.data.count = 1
console.log(componentB.data.count)  // 1

La raison en est que les deux partagent la même adresse mémoire et que le contenu modifié par le composantA affecte également le composantB. [Partage vidéo d'apprentissage : tutoriel vidéo vue, vidéo web front-end]

Si nous utilisons le formulaire d'une fonction, cette situation ne se produira pas (l'adresse mémoire de l'objet renvoyé par la fonction n'est pas la même )

function Component(){
this.data = this.data()
}
Component.prototype.data = function (){
    return {
   count : 0
    }
}

Modifier le composant composantA La valeur de l'attribut data, la valeur dans le composantB n'est pas affectée

console.log(componentB.data.count)  // 0
componentA.data.count = 1
console.log(componentB.data.count)  // 0

Le composant vue peut avoir plusieurs instances, et la fonction est utilisée pour renvoyer un nouveau formulaire de données, de sorte que les données de chaque objet d'instance ne sera pas contaminé par les données des autres objets d'instance

3. Analyse du principe

Tout d'abord, vous pouvez regarder le code des données d'initialisation de la vue. La définition des données peut être une fonction ou un objet.

Emplacement du code source : /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 === &#39;function&#39;
    ? 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(
          &#39;The "data" option should be a function &#39; +
            "that returns a per-instance value in component " +
            "definitions.",
          vm
        );
      return parentVal;
    }
    return mergeDataOrFn(parentVal, childVal);
  }
  return mergeDataOrFn(parentVal, childVal, vm);
};

data peut être à la fois un objet et une fonction, alors pourquoi l'avertissement ci-dessus apparaît-il ?

Ne vous inquiétez pas, continuez à lire ci-dessous

Lorsque le composant est créé, les options seront fusionnéesEmplacement du code source : /vue-dev/src/core/util/options.js

Puisque la définition des composants entrera dans les options de fusion pour la fusion des options

rrreee

La définition des données effectuera la vérification des données

Emplacement du code source : /vue-dev/src/core/instance/init.js

Ceci Chaque fois que l'instance vm n'est pas définie, entrez le jugement if, si le type de données n'est pas une fonction, un avertissement apparaîtra rrreee

  • 4. Conclusion

  • Les données de l'objet de l'instance racine peuvent être un objet ou une fonction ( l'instance racine est un singleton), aucune pollution des données ne se produit

    Les données d'objet d'instance de composant doivent être une fonction. Le but est d'empêcher plusieurs objets d'instance de composant de partager les mêmes données et de provoquer une pollution des données. Sous la forme d'une fonction, lorsque initData sera utilisé comme fonction d'usine, il renverra un nouvel objet de données
  • Remarque :

  • Les composants en vue sont utilisés pour la réutilisation Afin d'empêcher la réutilisation des données, ils sont définis comme des fonctions. 🎜🎜🎜🎜Les données du composant vue doivent être isolées les unes des autres et ne pas s'influencer les unes les autres. Chaque fois que le composant est réutilisé, les données doivent être copiées une fois. Plus tard, lorsqu'elles sont réutilisées quelque part, les données contenues dans. le composant sera copié. Lors de la modification, les données des autres composants locaux réutilisés ne seront pas affectées, vous devez donc renvoyer un objet comme état du composant via la fonction de données. 🎜🎜🎜🎜Lorsque nous écrivons les données dans le composant en tant que fonction, les données sont définies sous la forme d'une valeur de retour de fonction, de sorte qu'à chaque fois que le composant est réutilisé, une nouvelle donnée sera renvoyée avec sa propre portée, similaire à donner à chaque instance de composant crée un espace de données privé, permettant à chaque instance de composant de conserver ses propres données. 🎜🎜🎜🎜Lorsque la date de notre composant est simplement écrite sous forme d'objet, ces instances utilisent le même constructeur. En raison des caractéristiques de JavaScript, toutes les instances du composant partagent les mêmes données, ce qui entraînera un changement et tous les résultats. 🎜

(Partage de vidéos d'apprentissage : développement web front-end, Vidéo de programmation de base)

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Article précédent:A quoi sert la montre de vue ?Article suivant:A quoi sert la montre de vue ?