J'ai ce Vue 1
composant qui obtient un objet comme accessoire qui doit être rempli par l'utilisateur.
L'objet a la structure suivante :
{ property1: ..., property2: ..., inputs: { 2130: { value: ..., comment: ... }, 2131: { ... }, ..., } }
Le composant est un simple modal avec un formulaire contenant toutes les entrées nécessaires. Je souhaite vérifier du contenu, effectuer des calculs et modifier les styles de cellule en fonction des entrées de l'utilisateur.
Lorsque le modal se charge, je construis la page, en définissant le modèle pour ces entrées en utilisant leurs identifiants :
v-model="object.inputs[subgroup[1].dx.mob.id].comment"
(Remarque : subgroup[1]
是包含表结构“定义”的另一个对象的一部分,通过执行 inputs[subgroup[1].dx.mob.id]
J'attends les champs du tableau lié aux entrées correspondantes de l'objet)
Le problème est que peu importe ce que j'essaye, la page ne s'affiche pas à nouveau. <input>
Le champ ne contient même pas la valeur, il disparaît dès que je clique dessus.
Ce qui est encore plus étrange, c'est que les valeurs sont réellement définies, mais la seule façon d'obtenir le rendu du composant et de faire toutes les bonnes vérifications et styles dont j'ai besoin est de fermer et de rouvrir le modal ou de le définir sur le parent de la table v-if
.
Ce ne sont évidemment pas des options réalisables
Voici ce que j'ai essayé :
vm.$watch
l'objet est introuvable pour une raison quelconque. ...forEach((input, index)=>{ vm.$watch(`object.inputs[${index}].comment`, function(){ this.$forceUpdate(); }) }
Renvoyer l'entrée dans la propriété calculée et observer
Démarrer manuellement sur les événements @change et @input this.$forceUpdate()
$forceUpdate
n'est pas une fonctionDéclarez un compteur dans data et incrémentez-le sur les événements @change et @input.
Mettez v-if
sur des objets invisibles
Utilisez l'attribut data pour modifier l'attribut :key du composant
Comme prévu, la seule façon de procéder est de détruire et de recréer le composant.
Quelqu'un a-t-il une solution ?
La vilaine solution : Après quelques tentatives infructueuses, j'ai trouvé quelque chose qui fonctionne, même de manière incorrecte. tout réel Les réponses sont toujours les bienvenues.
Essentiellement, j'ai réussi à forcer le rendu du composant :
- Déclarez une nouvelle variable dans data, je l'ai nommée
key
(dans mon cas c'est un nombre, mais tout fera l'affaire)- Créez une fonction
update
qui passeupdate
函数,将key
de 1 à 0 et vice versa.- Liez cette fonction à chaque entrée ou sélection
@blur
événement- Puisque mon modal entier est rendu basé sur une propriété calculée, j'effectue quelques lectures sur
key
à l'intérieur de cette fonction (dans Mon cas est que j'attribue sa valeur à une nouvelle variable, puis je l'enregistre (pas Détermine lequel des deux déclenche le rendu, mais je suppose que le premier est Assez))... data: function() { return { ... , key: 0 }; }, ... methods: { ... , update: function(){ this.key = this.key == 0 ? 1 : 0 } }, computed: { ... , testData: function () { //this functions builds an object that is used to render the page var data = [] var __self = this var blu = this.key // This is the line where i read key console.log(blu) this.test.inputs.forEach(function(input){ var slug = input.slug.replaceAll('#', '').split('-') __self.setItem(data, slug, input) }) console.log('data', data) return data // this value gets then passed to Object.entries() to get an iterable object I build the page with } }
Meilleure réponse
Après un débogage en douceur, j’ai réussi à résoudre ce problème.
Essentiellement, le composant que je décris dans la question est utilisé pour deux pages différentes : la page « Créer » et la page « Modifier ». Mon cœur a fait un bond lorsque j'ai vu que tout fonctionnait comme prévu dans la page d'édition.
Que s'est-il passé :
La seule différence entre la façon dont le composant est utilisé dans les deux pages réside dans les données qui lui sont transmises. Dans la page Modifier, chaque objet est renseigné car les données sont déjà là, alors que dans la page Créer, chaque objet est évidemment vide.
Comme j'ai besoin d'un objet utilisable, je dois le remplir avec des entrées vides pour pouvoir y accéder plus tard.
J'ai bêtement essayé de définir la propriété manuellement comme ceci :
Attendez-vous à ce que l'attribution d'une propriété à un objet réactif rende automatiquement cette propriété également réactive. Oh mon Dieu, avais-je tort.
Getters et setters réactifs Vue :
Pour rendre les choses réactives, vue remplace les getters et setters de classe Object par défaut. Mais cela n'arrive que sous certaines conditions :
Vue.set()
或this.$set()
Par exemple, après quelques essais, paramètre
objects[index].inputs = {}
后,我尝试使用this.$set()
pour remplir ma saisie.Cela ne fonctionne pas car je n'ai pas non plus rendu
.inputs
réactif.J'ai donc dû le faire
avant
Conclusion :
Si vous rencontrez des problèmes de réactivité, mon conseil est de connecter ledit objet et de vérifier que lui et son objet parent ont les bons getters et setters.
N'oubliez pas que si vous souhaitez ajouter une nouvelle propriété à un objet réactif, vous devez la
$set()
.Objet de réaction :
Objets non réactifs :