Je veux donc passer des accessoires à un composant Vue, mais je m'attends à ce que ces accessoires changent à l'avenir de l'intérieur de ce composant, par exemple lorsque je mets à jour ce composant Vue de l'intérieur en utilisant AJAX. Donc, ils ne servent qu'à l'initialisation du composant.
Mon cars-list
élément de composant Vue où je passe des accessoires avec des propriétés initiales à single-car
:
// cars-list.vue
<script>
export default {
data: function() {
return {
cars: [
{
color: 'red',
maxSpeed: 200,
},
{
color: 'blue',
maxSpeed: 195,
},
]
}
},
}
</script>
<template>
<div>
<template v-for="car in cars">
<single-car :initial-properties="car"></single-car>
</template>
</div>
</template>
La façon dont je le fais en ce moment ce que l' intérieur de mon single-car
élément j'assignant this.initialProperties
à mon this.data.properties
sur le created()
crochet d'initialisation. Et cela fonctionne et est réactif.
// single-car.vue
<script>
export default {
data: function() {
return {
properties: {},
}
},
created: function(){
this.data.properties = this.initialProperties;
},
}
</script>
<template>
<div>Car is in {{properties.color}} and has a max speed of {{properties.maxSpeed}}</div>
</template>
Mais mon problème avec cela est que je ne sais pas si c'est une bonne façon de le faire? Cela ne me causera-t-il pas des ennuis sur la route? Ou y a-t-il une meilleure façon de le faire?
la source
data
esttwo-way
lié, mais vous ne pouvez pas passerdata
aux composants, vous passezprops
, mais vous ne pouvez pas changer le reçuprops
ni le convertirprops
endata
. Alors quoi? Une chose que j'ai apprise est que vous devez transmettreprops
et déclencher des événements. C'est-à-dire que si le composant souhaite modifier ceprops
qu'il a reçu, il doit appeler un événement et être «rendu». Mais ensuite, il vous reste uneone-way
liaison exactement comme React et je ne vois pas l'utilité pour celadata
. Assez déroutant.Réponses:
Merci à ce https://github.com/vuejs/vuejs.org/pull/567 je connais la réponse maintenant.
Méthode 1
Passez l'accessoire initial directement aux données. Comme l'exemple dans les documents mis à jour:
Mais gardez à l'esprit que si le prop passé est un objet ou un tableau utilisé dans l'état du composant parent, toute modification de cet accessoire entraînera le changement de cet état du composant parent.
Attention : cette méthode n'est pas recommandée. Cela rendra vos composants imprévisibles. Si vous avez besoin de définir des données parentes à partir de composants enfants, utilisez la gestion d'état comme Vuex ou utilisez "v-model". https://vuejs.org/v2/guide/components.html#Using-v-model-on-Components
Méthode 2
Si votre accessoire initial est un objet ou un tableau et si vous ne voulez pas que les modifications de l'état des enfants se propagent à l'état parent, utilisez simplement par exemple
Vue.util.extend
[1] pour faire une copie des accessoires au lieu de les pointer directement vers les données des enfants, comme ceci:Méthode 3
Vous pouvez également utiliser l'opérateur de propagation pour cloner les accessoires. Plus de détails dans la réponse Igor: https://stackoverflow.com/a/51911118/3143704
Mais gardez à l'esprit que les opérateurs de diffusion ne sont pas pris en charge dans les anciens navigateurs et pour une meilleure compatibilité, vous devrez transpiler le code, par exemple en utilisant
babel
.Notes de bas de page
[1] Gardez à l'esprit qu'il s'agit d'un utilitaire Vue interne et qu'il peut changer avec les nouvelles versions. Vous souhaiterez peut-être utiliser d'autres méthodes pour copier cet accessoire, voir " Comment cloner correctement un objet JavaScript? ".
Mon violon là où je le testais: https://jsfiddle.net/sm4kx7p9/3/
la source
{ ok: 1, notOk: { meh: 2 } }
s'il est défini sur une donnée interne avec l'une des méthodes de clonage précédentes, cela changerait toujours l'accessoirenotOk.meh
initial
juste pour pouvoir les utiliser dans mon ordinateur. Ce serait tellement plus propre si nous pouvions simplement passer un accessoire appelédata
à n'importe quel ordinateur et le faire propager automatiquement les données localisées à l'intérieur sans toute cetteinitialPropName
folie.prop --> comp.data
à utiliser Vue-Stash pour toutes les données (ou Vuex fonctionnerait aussi). Mais maintenant, je ne fais que rebondir mes données sur l'window
objet, comme je le faisais avant que les frameworks JS «modernes» ne m'imposent leur opinion. Cela pose donc la question suivante: quel est l'intérêt de la propriété comp.data?En complément de la réponse de @ dominik-serafin:
Si vous passez un objet, vous pouvez facilement le cloner à l'aide de l'opérateur de propagation (syntaxe ES6):
Mais le plus important est de ne pas oublier d'utiliser opt. 2 au cas où vous transmettriez une valeur calculée, ou plus qu'une valeur asynchrone. Sinon, la valeur locale ne sera pas mise à jour.
Démo:
https://jsfiddle.net/nomikos3/eywraw8t/281070/
la source
recordLocal: [...this.record]
(dans mon cas, l'enregistrement est un tableau) ne fonctionnait pas pour moi - après le chargement et l'inspection du composant vue,record
contient les éléments etrecordLocal
était un tableau vide.computed
Je pense que vous le faites bien parce que c'est ce qui est indiqué dans la documentation.
https://vuejs.org/guide/components.html#One-Way-Data-Flow
la source
window
objet.