Maison  >  Article  >  interface Web  >  Quelles sont les méthodes d’initialisation des données dans Vue ?

Quelles sont les méthodes d’initialisation des données dans Vue ?

青灯夜游
青灯夜游original
2022-12-26 18:09:353588parcourir

Vue propose deux manières d'initialiser les données : 1. Mode objet, syntaxe "var data = {paire clé-valeur }" ; 2. Mode fonction, syntaxe "data : function () {return {paire clé-valeur }}" . Il est à noter que l'initialisation des données dans les composants et l'extension ne peut pas être un objet, sinon une erreur sera signalée. L'objectif de l'utilisation du mode fonction pour les données dans les composants 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.

Quelles sont les méthodes d’initialisation des données dans Vue ?

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

Les données Vue ont deux manières de les initialiser, fonction et objet, mais quels sont les scénarios applicables pour ces deux situations ? Est-ce que cela peut être universel ? Avec ces deux questions, analysons-les ensemble

initialisation des données

// 代码来源于官网示例

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

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

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

Le code ci-dessus décrit simplement les deux manières de définir les données

  • fonction

  • objet

Il est également dans le démo du site officiel Il est souligné que l'objet ne peut pas être utilisé pour l'initialisation des données dans une certaine mesure. Alors pourquoi ?

Analyse du code source

Selon la démo du site officiel, l'initialisation des données dans Vue.extend ne peut pas être un objet. Que se passera-t-il si nous forçons à l'écrire en tant qu'objet ?

var Component = Vue.extend({
  data: { a: 1 }
})

Après l'exécution, la console de Chrome signale directement une erreur, les informations sont les suivantes

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

En analysant le code source et le message d'erreur, lorsque Vue.extend est déclenché, il effectuera une opération de fusion et combinera un composant de base (à l'intérieur vmode, traduction, etc.) avec Les informations que vous définissez dans extend sont fusionnées en options via mergeField. Une fois fusionnées avec les données, elles déclencheront strats.data, qui vérifiera si les données sont une fonction à laquelle il faut prêter attention. voici les filtres, les composants, etc. Les données suivent deux ensembles de processus de fusion. Veuillez consulter les commentaires du code pour plus de détails, comme suit

// 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)
};

Autres situations

En fait, notre code ci-dessus n'est qu'un processus simple. développement réel, des situations similaires incluent : dans les sous-composants, Data ne peut pas être défini comme un objet dans la route, car ils appellent tous la méthode mergeOptions en bas. Quand peut-il être défini comme un objet Lorsque vue est initialisée ? est la signification de

new Vue({
  data: {
    linke: '//sinker.club'
  }
})

ok, tant de choses ont été dites ci-dessus, alors à quoi ça sert de faire ça ? Pourquoi ces situations ne peuvent-elles pas être définies comme des objets ? En fait, pour répondre à cette question, vous devez revenir à js lui-même. Comme nous le savons tous, les types de données js sont divisés en types de référence et de base. Les types de référence incluent Object, Array et Function. expliqué ici

  var obj = {link: '//www.sinker.club'}
  var obj2 = obj
  var obj3 = obj
  obj2.link = "//gitlab.sinker.club"
  console.log(obj3.link) // "//gitlab.sinker.club"

Le code ci-dessus reflète un problème, car obj3 et obj2 pointent tous deux vers une adresse en mémoire, donc la modification d'obj2 affectera obj3. Bien sûr, la copie profonde peut être utilisée pour résoudre ce problème

. JSON.parse(JSON.stringify(obj))

deepClone(obj)

  • Mais ces deux méthodes nécessitent à chaque fois un développement ou une copie approfondie du framework. Lorsque la quantité de données est importante, ce n'est pas le cas. convivial pour les performances. Alors, comment Vue fait-il ? Définir les données comme une fonction

    function data() {
      return {
       link: '//sinker.club'
      }
    }
    
    var obj = test()
    var obj2 = test()
    
    obj2.link ="//gitlab.sinker.club"
    console.log(obj.link) '//sinker.club'

  • Pourquoi fais-tu ça ? Quel est le scénario de solution ?

Par exemple, si je définis un sous-composant, les données sont définies comme un objet. Ce composant est référencé à plusieurs endroits. Si l'une des données référençant ce composant est modifiée, les autres données référençant ce composant le seront. être modifié en même temps. Changer, terminer.

Connaissances étendues :

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

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

L'attribut data défini dans le composant peut être uniquement une fonction

Si 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

Explication :

Les composants Vue sont utilisés pour être réutilisés. empêcher la réutilisation des données, définissez-la comme une fonction . Quelles sont les méthodes d’initialisation des données dans Vue ?

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.

【Recommandations associées : tutoriel vidéo vuejs, développement web front-end

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