将数据传递给 vue.js 中的组件

我很难理解如何在 vue.js 中的组件之间传递数据。我已经通读了好几遍这些文档,看了很多与价值相关的问题和教程,但是我还是不明白。

为了理解这一点,我希望能够帮助完成一个非常简单的示例

  1. 在一个组件中显示用户列表(完成)
  2. 当点击一个链接时,将用户数据发送到一个新的组件-参见底部的更新。
  3. 编辑用户数据并将其发送回原始组件(还没有到这一步)

下面是一个小提琴,它在步骤2中失败了: https://jsfiddle.net/retrogradeMT/d1a8hps0/

我知道我需要使用道具来将数据传递给新组件,但是我不确定如何在功能上做到这一点。如何将数据绑定到新组件?

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 用于主要组件:

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);
}
}
})

第二个组成部分:

Vue.component('newtemp', {
template: '#newtemp',
props: 'name',
data: function() {
return {
name: name,
}
},
})

更新

好了,我已经想出了第二步。这里有一个新的小提琴显示的进度: https://jsfiddle.net/retrogradeMT/9pffnmjp/

因为我使用 Vue-router,所以我不使用道具将数据发送到新组件。相反,我需要在 v-link 上设置 params,然后使用一个转换钩子来接受它。

V 型链接变化 查看 vue-router 文档中的命名路由:

<a v-link="{ name: 'new', params: { name: user.name }}"> Show new component</a>

然后在组件上,向路由选项 看过渡挂钩添加数据:

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,
}
},
})
209921 次浏览

I think the issue is here:

<template id="newtemp" :name ="\{\{user.name}}">

When you prefix the prop with : you are indicating to Vue that it is a variable, not a string. So you don't need the \{\{}} around user.name. Try:

<template id="newtemp" :name ="user.name">

EDIT-----

The above is true, but the bigger issue here is that when you change the URL and go to a new route, the original component disappears. In order to have the second component edit the parent data, the second component would need to be a child component of the first one, or just a part of the same component.

-------------Following is applicable only to Vue 1 --------------

Passing data can be done in multiple ways. The method depends on the type of use.


If you want to pass data from your html while you add a new component. That is done using props.

<my-component prop-name="value"></my-component>

This prop value will be available to your component only if you add the prop name prop-name to your props attribute.


When data is passed from a component to another component because of some dynamic or static event. That is done by using event dispatchers and broadcasters. So for example if you have a component structure like this:

<my-parent>
<my-child-A></my-child-A>
<my-child-B></my-child-B>
</my-parent>

And you want to send data from <my-child-A> to <my-child-B> then in <my-child-A> you will have to dispatch an event:

this.$dispatch('event_name', data);

This event will travel all the way up the parent chain. And from whichever parent you have a branch toward <my-child-B> you broadcast the event along with the data. So in the parent:

events:{
'event_name' : function(data){
this.$broadcast('event_name', data);
},

Now this broadcast will travel down the child chain. And at whichever child you want to grab the event, in our case <my-child-B> we will add another event:

events: {
'event_name' : function(data){
// Your code.
},
},

The third way to pass data is through parameters in v-links. This method is used when components chains are completely destroyed or in cases when the URI changes. And i can see you already understand them.


Decide what type of data communication you want, and choose appropriately.

I've found a way to pass parent data to component scope in Vue, i think it's a little a bit of a hack but maybe this will help you.

1) Reference data in Vue Instance as an external object (data : dataObj)

2) Then in the data return function in the child component just return parentScope = dataObj and voila. Now you cann do things like \{\{ parentScope.prop }} and will work like a charm.

Good Luck!

The best way to send data from a parent component to a child is using props.

Passing data from parent to child via props

  • Declare props (array or object) in the child
  • Pass it to the child via <child :name="variableOnParent">

See demo below:

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/vue@2.5.13/dist/vue.min.js"></script>


<div id="app">
<p>At Parent: \{\{ variableAtParent }}<br>And is reactive (edit it) <input v-model="variableAtParent"></p>
<child-comp :message="variableAtParent"></child-comp>
</div>

A global JS variable (object) can be used to pass data between components. Example: Passing data from Ammlogin.vue to Options.vue. In Ammlogin.vue rspData is set to the response from the server. In Options.vue the response from the server is made available 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>

I access main properties using $root.

Vue.component("example", {
template: `<div>$root.message</div>`
});
...
<example></example>

The above-mentioned responses work well but if you want to pass data between 2 sibling components, then the event bus can also be used. Check out this blog which would help you understand better.

supppose for 2 components : CompA & CompB having same parent and main.js for setting up main vue app. For passing data from CompA to CompB without involving parent component you can do the following.

in main.js file, declare a separate global Vue instance, that will be event bus.

export const bus = new Vue();

In CompA, where the event is generated : you have to emit the event to bus.

methods: {
somethingHappened (){
bus.$emit('changedSomething', 'new data');
}
}

Now the task is to listen the emitted event, so, in CompB, you can listen like.

created (){
bus.$on('changedSomething', (newData) => {
console.log(newData);
})
}

Advantages:

  • Less & Clean code.
  • Parent should not involve in passing down data from 1 child comp to another ( as the number of children grows, it will become hard to maintain )
  • Follows pub-sub approach.