J'ai du mal à comprendre comment transmettre des données entre composants dans vue.js. J'ai lu plusieurs fois la documentation et consulté de nombreuses questions et tutoriels liés à vue, mais je ne comprends toujours pas.
En résumé, j’espère avoir de l’aide pour compléter un exemple assez simple.
Voici un violon qui échoue à la deuxième étape: https://jsfiddle.net/retrogradeMT/d1a8hps0/
Je comprends que je dois utiliser des accessoires pour transmettre des données au nouveau composant, mais je ne sais pas comment le faire fonctionnellement. Comment lier les données au nouveau composant?
HTML:
<div id="page-content">
<router-view></router-view>
</div>
<template id="userBlock" >
<ul>
<li v-for="user in users">{{user.name}} - <a v-link="{ path: '/new' }"> Show new component</a>
</li>
</ul>
</template>
<template id="newtemp" :name ="{{user.name}}">
<form>
<label>Name: </label><input v-model="name">
<input type="submit" value="Submit">
</form>
</template>
js pour composant principal:
Vue.component('app-page', {
template: '#userBlock',
data: function() {
return{
users: []
}
},
ready: function () {
this.fetchUsers();
},
methods: {
fetchUsers: function(){
var users = [
{
id: 1,
name: 'tom'
},
{
id: 2,
name: 'brian'
},
{
id: 3,
name: 'sam'
},
];
this.$set('users', users);
}
}
})
JS pour le deuxième composant:
Vue.component('newtemp', {
template: '#newtemp',
props: 'name',
data: function() {
return {
name: name,
}
},
})
UPDATE
Ok, j'ai la deuxième étape calculée. Voici un nouveau violon montrant les progrès: https://jsfiddle.net/retrogradeMT/9pffnmjp/
Parce que j'utilise Vue-router, je n'utilise pas d'accessoires pour envoyer les données à un nouveau composant. Au lieu de cela, j'ai besoin de définir des paramètres sur le v-link, puis d'utiliser un crochet de transition pour l'accepter.
Modifications de la liaison virtuelle voir les routes nommées dans la documentation de vue-router :
<a v-link="{ name: 'new', params: { name: user.name }}"> Show new component</a>
Ensuite, sur le composant, ajoutez des données aux options de route voir crochets de transition :
Vue.component('newtemp', {
template: '#newtemp',
route: {
data: function(transition) {
transition.next({
// saving the id which is passed in url
name: transition.to.params.name
});
}
},
data: function() {
return {
name:name,
}
},
})
------------- Ce qui suit s’applique uniquement à Vue 1 --------------
La transmission de données peut être effectuée de plusieurs manières. La méthode dépend du type d'utilisation.
Si vous souhaitez transmettre des données de votre code HTML pendant que vous ajoutez un nouveau composant. Cela se fait à l'aide d'accessoires.
<my-component prop-name="value"></my-component>
Cette valeur de prop n'est disponible pour votre composant que si vous ajoutez le nom de prop prop-name
à votre attribut props
.
Lorsque des données sont transmises d'un composant à un autre composant en raison d'un événement dynamique ou statique. Cela se fait en utilisant des répartiteurs d’événements et des diffuseurs. Donc, par exemple, si vous avez une structure de composant comme celle-ci:
<my-parent>
<my-child-A></my-child-A>
<my-child-B></my-child-B>
</my-parent>
Et vous voulez envoyer des données de <my-child-A>
à <my-child-B>
, puis dans <my-child-A>
, vous devrez envoyer un événement:
this.$dispatch('event_name', data);
Cet événement voyagera tout au long de la chaîne parente. Et quel que soit le parent sur lequel vous avez une branche vers <my-child-B>
vous diffusez l’événement avec les données. Donc dans le parent:
events:{
'event_name' : function(data){
this.$broadcast('event_name', data);
},
Maintenant, cette émission voyagera dans la chaîne enfant. Et quel que soit l'enfant que vous souhaitez saisir, dans notre cas <my-child-B>
nous ajouterons un autre événement:
events: {
'event_name' : function(data){
// Your code.
},
},
La troisième façon de transmettre des données est d'utiliser des paramètres dans v-links. Cette méthode est utilisée lorsque les chaînes de composants sont complètement détruites ou lorsque l'URI change. Et je peux voir que vous les comprenez déjà.
Décidez du type de communication de données que vous souhaitez et choisissez en conséquence.
Le meilleur moyen d'envoyer des données d'un composant parent à un enfant est d'utiliser props .
props
props
(tableau ou objet ) dans l'enfant<child :name="variableOnParent">
Voir la démo ci-dessous:
Vue.component('child-comp', {
props: ['message'], // declare the props
template: '<p>At child-comp, using props in the template: {{ message }}</p>',
mounted: function () {
console.log('The props are also available in JS:', this.message);
}
})
new Vue({
el: '#app',
data: {
variableAtParent: 'DATA FROM PARENT!'
}
})
<script src="https://unpkg.com/[email protected]/dist/vue.min.js"></script>
<div id="app">
<p>At Parent: {{ variableAtParent }}</p>
<child-comp :message="variableAtParent"></child-comp>
</div>
Je pense que le problème est ici:
<template id="newtemp" :name ="{{user.name}}">
Lorsque vous préfixez l'accessoire avec :
, vous indiquez à Vue qu'il s'agit d'une variable et non d'une chaîne. Donc, vous n'avez pas besoin du {{}}
autour de user.name
. Essayer:
<template id="newtemp" :name ="user.name">
MODIFIER-----
Ce qui précède est vrai, mais le problème majeur est que lorsque vous modifiez l'URL et accédez à un nouvel itinéraire, le composant d'origine disparaît. Pour que le deuxième composant modifie les données parent, le deuxième composant doit être un composant enfant du premier ou juste une partie du même composant.
J'ai trouvé un moyen de passer des données parent à la portée du composant dans Vue. Je pense que c'est un peu un bidouillage, mais peut-être que cela vous aidera.
1) Données de référence dans Vue Instance en tant qu'objet externe (data : dataObj)
2) Ensuite, dans la fonction de retour des données du composant enfant, il suffit de renvoyer parentScope = dataObj
et le tour est joué. Maintenant, vous pouvez faire des choses comme {{ parentScope.prop }}
et vous ferez comme un charme.
Bonne chance!
Une variable JS globale (objet) peut être utilisée pour transmettre des données entre des composants. Exemple: transmission de données d'Ammlogin.vue à Options.vue. Dans Ammlogin.vue, rspData est défini sur la réponse du serveur. Dans Options.vue, la réponse du serveur est rendue disponible via rspData.
index.html:
<script>
var rspData; // global - transfer data between components
</script>
Ammlogin.vue:
....
export default {
data: function() {return vueData},
methods: {
login: function(event){
event.preventDefault(); // otherwise the page is submitted...
vueData.errortxt = "";
axios.post('http://vueamm...../actions.php', { action: this.$data.action, user: this.$data.user, password: this.$data.password})
.then(function (response) {
vueData.user = '';
vueData.password = '';
// activate v-link via JS click...
// JSON.parse is not needed because it is already an object
if (response.data.result === "ok") {
rspData = response.data; // set global rspData
document.getElementById("loginid").click();
} else {
vueData.errortxt = "Felaktig avändare eller lösenord!"
}
})
.catch(function (error) {
// Wu oh! Something went wrong
vueData.errortxt = error.message;
});
},
....
Options.vue:
<template>
<main-layout>
<p>Alternativ</p>
<p>Resultat: {{rspData.result}}</p>
<p>Meddelande: {{rspData.data}}</p>
<v-link href='/'>Logga ut</v-link>
</main-layout>
</template>
<script>
import MainLayout from '../layouts/Main.vue'
import VLink from '../components/VLink.vue'
var optData = { rspData: rspData}; // rspData is global
export default {
data: function() {return optData},
components: {
MainLayout,
VLink
}
}
</script>