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.
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"
. JSON.parse(JSON.stringify(obj))
deepClone(obj)function data() { return { link: '//sinker.club' } } var obj = test() var obj2 = test() obj2.link ="//gitlab.sinker.club" console.log(obj.link) '//sinker.club'
Connaissances étendues :
Lors de la définition de l'instance de vue, l'attribut data peut être soit un objet, soit une fonctionconst app = new Vue({ el:"#app", // 对象格式 data:{ foo:"foo" }, // 函数格式 data(){ return { foo:"foo" } } })
Si si les données du composant sont directement définies comme un objet 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 . 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. 【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!Vue.component('component1',{
template:`<div>组件</div>`,
data:{
foo:"foo"
}})