J'ai un composant VueJS comme celui-ci
const MyComponent = Vue.extend({
props: ["myHandle"],
computed: {
name: {
get: function() { return myHandle.getName() },
set: function(newName) { myHandle.setName(newName) },
}
}
})
Le problème est que la définition de la propriété calculée name ne déclenche pas VueJs pour mettre à jour la propriété. Ce qui signifie que l'ancien nom est ce qui s'affiche lors du rendu.
Maintenant, je suis assez nouveau dans VueJS et je peux voir à quel point cela pourrait être une odeur de code, mais le fait est que le myHandle est en fait un handle pour accéder aux données dans un module WebAssembly écrit en rust. Le code rust est l'endroit où la plupart de mon état / modèle / source de vérité réside.
Les deux solutions insatisfaisantes que j'ai trouvées jusqu'à présent sont:
Utilisez une méthode pour récupérer le nom au lieu d'une propriété calculée. En gros, ajoutez une méthode Votre nom est {{name}} Votre nom est {{getName ()}} getName à mon composant et changez le code de mon modèle de en . Ce qui empêchera VueJs de mettre en cache. À l'avenir, je prévois de faire des calculs coûteux, ce qui entraînera des coûts de performance inutiles
Copie l'état du côté rouillé vers mon composant. Je ne veux pas faire cela car j'aurais plusieurs sources de vérité.
Existe-t-il donc un moyen de:
A : Faire comprendre à VueJS que myHandle.setName est une méthode de mutation qui devrait provoquer la mise à jour de la propriété calculée de name .
B : déclencher manuellement une mise à jour.
C Le résoudre d'une autre manière?
4 Réponses :
J'espère que cet exemple vous aidera
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Page Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<div id="app">
<my-component :myhandle="myhandle">
</my-component>
<h2>Vue app Object: {{myhandle.name}}</h2>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.22/dist/vue.js"></script>
<script>
Vue.component('my-component', Vue.extend({
props: ["myhandle"],
data () {
return {
name:""
}
},
watch: {
myhandle:{
handler (val, oldVal) {
console.log('Prop changed');
// do your stuff
},
deep: true, // nested data
}
},
methods: {
chName(){
this.myhandle.name = "Henry";
}
},
template:'<div><h1>{{myhandle.name }}</h1><br><button @click="chName()">Cahnge name</button></div>',
}),
);
var app = new Vue({
el:'#app',
data (){
return {
myhandle:{
name:'Jack'
}
}
}
});
</script>
</body>
</html>
Les propriétés calculées sont mises en cache en fonction de leurs dépendances (données, accessoires et autres propriétés calculées). Si j'ai bien compris, votre propriété calculée ne sera pas réactive car la seule dépendance est myHandle, et je suppose que cela ne changera jamais. Regardez les choses de cette façon, Vue ne peut vérifier que getName renvoie une valeur différente en appelant réellement la méthode, donc il n'y a rien à mettre en cache.
Si le nom ne peut être modifié qu'à partir de votre composant Vue, vous pouvez le définir comme champ de données et ajouter un observateur pour mettre à jour la valeur WebAssembly. Sinon, si le nom peut être changé à partir de sources non-Vue et que vous devez appeler la méthode getName à partir du gestionnaire à chaque fois, vous devrez créer votre propre mécanisme (peut-être en utilisant une fonction anti-rebond pour limiter le nombre d'appels).
Je ne sais pas comment est votre implémentation de setName (), mais si c'est le cas
setName (nouveauNom) {this.name = nouveauNom; }
vous avez peut-être rencontré le problème décrit ici: https://vuejs.org/v2/guide/reactivity.html# Mises en garde de détection de changement
Je voudrais ajouter que ce n'est probablement pas une bonne idée de faire muter myHandle comme accessoire, donc je suggère que si vous pouvez refactoriser votre code pour utiliser myHandle comme propriété de données, de le faire.
Il existe une astuce simple - dummy_toogle - placez-la simplement dans vos données de composant: {toggle: false} et dans votre getter / setter: get: function () {this.toggle; ...} set: fonction (nom) {...; this.toggle =! this.toggle;} Maintenant, vue pensera que la propriété calculée dépend de la bascule et la recalculera si la bascule est modifiée + vous pouvez faire un rappel très stupide et le transmettre à une partie non vue de votre application comme déclencheur de mise à jour