Maison  >  Questions et réponses  >  le corps du texte

VueJS ne peut pas mettre à jour le composant

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é :

...forEach((input, index)=>{
    vm.$watch(`object.inputs[${index}].comment`, function(){
            this.$forceUpdate();
        })
}

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 passe update 函数,将 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
    } 
}

P粉517475670P粉517475670206 Il y a quelques jours354

répondre à tous(1)je répondrai

  • P粉198749929

    P粉1987499292024-03-27 12:53:49

    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 :

    objects[index].inputs = {}

    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 :

    • Cet attribut doit être ajouté via Vue.set()this.$set()
    • Toutes les propriétés parentes doivent également être réactives

    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

    this.$set('objects[${index}].inputs', {})

    avant

    this.$set(`objects[${index}].inputs[${input.id}].value`, null)
    this.$set(`objects[${index}].inputs[${input.id}].comment`, null)

    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 :

    répondre
    0
  • Annulerrépondre