J'ai un problème très commun avec la mise à niveau vers Vue 2.0
Je reçois un avertissement:
Évitez de muter directement un accessoire car la valeur sera écrasée chaque fois que le composant parent est rendu. Au lieu de cela, utilisez une donnée ou propriété calculée en fonction de la valeur de l'accessoire. Prop étant muté: "nom d'utilisateur" (trouvé dans le composant)
J'ai lu la documentation plusieurs fois mais je ne comprends toujours pas comment le corriger.
username
et password
sont déclarés dans l'application Vue principale.
Voici mon code:
var GuestMenu = Vue.extend({
props : ['username', 'password'],
template: `
<div id="auth">
<form class="form-inline pull-right">
<div class="form-group">
<label class="sr-only" for="UserName">User name</label>
<input type="username" v-model="username" class="form-control" id="UserName" placeholder="username">
</div>
<div class="form-group">
<label class="sr-only" for="Password">Password</label>
<input type="password" v-model="password" class="form-control" id="Password" placeholder="Password">
</div>
</form>
</div>`,
});
App = new Vue ({
el: '#app',
data:
{
topMenuView: "guestmenu",
contentView: "guestcontent",
username: "",
password: "",
}
})
J'ai essayé v-bind
mais cela ne semble pas fonctionner et je ne comprends pas pourquoi. Il devrait lier la valeur au parent (l’application Vue principale)
Depuis Vue 2.3.0, vous pouvez utiliser le modificateur .sync
:
Exemple vom https://vuejs.org/v2/guide/components-custom-events.html#sync-Modifier :
<text-document :title.sync="title"></text-document>
et dans votre contrôleur ...
this.$emit('update:title', newTitle)
Vue.js considère cela comme un anti-motif. Par exemple, en déclarant et en définissant des accessoires comme
this.propsVal = 'new Props Value'
Donc, pour résoudre ce problème, vous devez prendre la valeur des accessoires aux données ou à la propriété calculée de l’instance Vue. comme...
props: ['propsVal'],
data: function() {
return {
propVal: this.propsVal
};
},
methods: {
...
}
et vous pouvez utiliser votre valeur d'accessoire comme d'habitude.
Vous devez créer une propriété calculée avec un getter et un setter, puis utiliser $emit
pour mettre à jour la propriété, par exemple:
var GuestMenu = Vue.extend({
props: ['username', 'password'],
template: `
<div id="auth">
<form class="form-inline pull-right">
<div class="form-group">
<label class="sr-only" for="UserName">User name</label>
<input type="username" v-model="usernameInput" class="form-control" id="UserName" placeholder="username">
</div>
<div class="form-group">
<label class="sr-only" for="Password">Password</label>
<input type="password" v-model="passwordInput" class="form-control" id="Password" placeholder="Password">
</div>
</form>
</div>`,
computed: {
usernameInput: {
get: function(){
return this.username;
},
set: function(newValue){
this.$emit('update:username', newValue)
}
},
passwordInput: {
get: function(){
return this.password;
},
set: function(newValue){
this.$emit('update:password', newValue)
}
},
}
});
Je ne sais pas exactement ce que vous voulez réaliser, mais je vais prendre deux options.
Premier point: il s'agit de se débarrasser de cet avertissement.
data () {
return {
childVal: this.parentVal
}
}
Deuxième question: vous souhaitez communiquer entre parent et enfant.
Si j'ai bien compris, il s'agit d'un exemple de base d'un <input>
dans un composant enfant communiquant avec son parent.
HTML parent:
<p>{{ user }}</p>
<child-component v-model="user">
Parent JS:
data () {
return {
user: 'John'
}
}
HTML enfant:
<input v-bind:value="value" @input="$emit('input', $event.target.value)">
Enfant JS:
props: ['value']
Exemple de travail: http://jsfiddle.net/kf3aLr1u/
Vous pouvez également en savoir plus à ce sujet dans docs https://vuejs.org/v2/guide/components.html .
Une propriété computed
avec les get
et set
appropriés a fonctionné pour moi:
computed: {
dialogDataProp: {
get: function() {
return this.dialog;
},
set: function() {}
}
}
Code ci-dessus pour basculer une boîte de dialogue.
si vous voulez muter les accessoires - utilisez object.
<component :user="global.user"></component>
composant:
props: ['user'],
methods: {
setUser: function() {
this.user.username= "User";
this.user.password= "myPass123";
}
}
Lorsque vous utilisez v-bind
la propriété est liée en utilisant deux directions, c'est pourquoi vous obtenez l'avertissement.
Si vous devez transmettre le nom d'utilisateur initial du composant Vue parent, vous pouvez utiliser v-bind
avec une autre propriété de données telle que _username
et copier la valeur initiale de la propriété dans les données internes lors de la création du composant:
props : ['username', 'password'],
data () {
return {
_username: this.username,
_password: this.password
}
}
Edit: vous pouvez également utiliser une surveillance $ pour mettre à jour les données du composant _username/_password lorsque les propriétés changent.