将数据传递给 vue.js 中的组件
Passing data to components in vue.js
我很难理解如何在 vue.js 中的组件之间传递数据。我已经多次通读文档并查看了许多与 vue 相关的问题和教程,但我仍然没有得到它。
为了解决这个问题,我希望得到帮助来完成一个非常简单的示例
- 在一个组件中显示用户列表(完成)
- 单击 link 时将用户数据发送到新组件(完成)- 请参阅底部的更新。
- 编辑用户数据并将其发送回原始组件(还没到这一步)
这是一个 fiddle,它在第二步失败:https://jsfiddle.net/retrogradeMT/d1a8hps0/
我知道我需要使用 props 将数据传递给新组件,但我不确定如何在功能上做到这一点。如何将数据绑定到新组件?
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);
}
}
})
第二个组件的 JS:
Vue.component('newtemp', {
template: '#newtemp',
props: 'name',
data: function() {
return {
name: name,
}
},
})
更新
好的,我已经弄清楚了第二步。这是显示进度的新 fiddle:https://jsfiddle.net/retrogradeMT/9pffnmjp/
因为我使用的是 Vue-router,所以我不使用 props 将数据发送到新组件。相反,我需要在 v-link 上设置参数,然后使用转换挂钩来接受它。
V-link 变化 see named routes in vue-router docs:
<a v-link="{ name: 'new', params: { name: user.name }}"> Show new component</a>
然后在组件上,添加数据到路由选项see transition hooks:
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,
}
},
})
我认为问题出在这里:
<template id="newtemp" :name ="{{user.name}}">
当您在 prop 前加上 :
前缀时,您向 Vue 表明它是一个变量,而不是一个字符串。所以你不需要 user.name
周围的 {{}}
。尝试:
<template id="newtemp" :name ="user.name">
编辑-----
以上是对的,但这里更大的问题是当你改变URL并转到新路线时,原来的组件消失了。为了让第二个组件编辑父数据,第二个组件需要是第一个组件的子组件,或者只是同一组件的一部分。
------------以下仅适用于Vue 1 --------------
可以通过多种方式传递数据。该方法取决于使用类型。
如果您想在添加新组件时从 html 传递数据。这是使用道具完成的。
<my-component prop-name="value"></my-component>
仅当您将道具名称 prop-name
添加到您的 props
属性时,此道具值才可用于您的组件。
当数据由于某些动态或静态事件而从一个组件传递到另一个组件时。这是通过使用事件调度程序和广播程序来完成的。因此,例如,如果您有这样的组件结构:
<my-parent>
<my-child-A></my-child-A>
<my-child-B></my-child-B>
</my-parent>
并且您想将数据从 <my-child-A>
发送到 <my-child-B>
,然后在 <my-child-A>
中您必须发送一个事件:
this.$dispatch('event_name', data);
此事件将沿着 parent 链向上传播。从任何一个 parent 分支到 <my-child-B>
,您都可以将事件与数据一起广播。所以在 parent:
events:{
'event_name' : function(data){
this.$broadcast('event_name', data);
},
现在这个广播将沿着 child 链传播。在任何 child 你想抓取事件,在我们的例子中 <my-child-B>
我们将添加另一个事件:
events: {
'event_name' : function(data){
// Your code.
},
},
第三种传递数据的方式是通过v-links中的参数。当组件链被完全破坏或 URI 更改时使用此方法。而且我可以看到你已经理解了它们。
决定你想要什么类型的数据通信,然后选择合适的。
我找到了一种在 Vue 中将父数据传递到组件范围的方法,我认为这有点 hack,但也许这会对你有所帮助。
1) Vue实例中作为外部对象引用数据(data : dataObj)
2) 然后在子组件的数据 return 函数中只是 return parentScope = dataObj
瞧。现在你可以做 {{ parentScope.prop }}
之类的事情了,而且会很有魅力。
祝你好运!
将数据从 parent 组件发送到 child 的最佳方法是使用 props。
通过 props
将数据从 parent 传递到 child
- 在child
中声明props
(数组或object)
- 通过
<child :name="variableOnParent">
传递给child
参见下面的演示:
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>
一个全局的JS变量(对象)可以用来在组件之间传递数据。示例:将数据从 Ammlogin.vue 传递到 Options.vue。在 Ammlogin.vue 中,rspData 设置为来自服务器的响应。在 Options.vue 中,服务器的响应可通过 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>
我使用 $root
访问主要属性。
Vue.component("example", {
template: `<div>$root.message</div>`
});
...
<example></example>
上面提到的响应效果很好,但是如果你想在两个兄弟组件之间传递数据,那么也可以使用事件总线。
查看此博客,这将帮助您更好地理解。
假设有 2 个组件:CompA 和 CompB 具有相同的父组件和 main.js 用于设置主 vue 应用程序。要在不涉及父组件的情况下将数据从 CompA 传递到 CompB,您可以执行以下操作。
在 main.js 文件中,声明一个单独的全局 Vue 实例,这将是事件总线。
export const bus = new Vue();
在生成事件的 CompA 中:您必须将事件发送到总线。
methods: {
somethingHappened (){
bus.$emit('changedSomething', 'new data');
}
}
现在的任务是监听发出的事件,所以,在 CompB 中,你可以像这样监听。
created (){
bus.$on('changedSomething', (newData) => {
console.log(newData);
})
}
优点:
- 更少和更干净的代码。
- 父级不应参与将数据从一个子组件传递给另一个子组件(随着子组件数量的增加,它将变得难以维护)
- 遵循 pub-sub 方法。
我很难理解如何在 vue.js 中的组件之间传递数据。我已经多次通读文档并查看了许多与 vue 相关的问题和教程,但我仍然没有得到它。
为了解决这个问题,我希望得到帮助来完成一个非常简单的示例
- 在一个组件中显示用户列表(完成)
- 单击 link 时将用户数据发送到新组件(完成)- 请参阅底部的更新。
- 编辑用户数据并将其发送回原始组件(还没到这一步)
这是一个 fiddle,它在第二步失败:https://jsfiddle.net/retrogradeMT/d1a8hps0/
我知道我需要使用 props 将数据传递给新组件,但我不确定如何在功能上做到这一点。如何将数据绑定到新组件?
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);
}
}
})
第二个组件的 JS:
Vue.component('newtemp', {
template: '#newtemp',
props: 'name',
data: function() {
return {
name: name,
}
},
})
更新
好的,我已经弄清楚了第二步。这是显示进度的新 fiddle:https://jsfiddle.net/retrogradeMT/9pffnmjp/
因为我使用的是 Vue-router,所以我不使用 props 将数据发送到新组件。相反,我需要在 v-link 上设置参数,然后使用转换挂钩来接受它。
V-link 变化 see named routes in vue-router docs:
<a v-link="{ name: 'new', params: { name: user.name }}"> Show new component</a>
然后在组件上,添加数据到路由选项see transition hooks:
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,
}
},
})
我认为问题出在这里:
<template id="newtemp" :name ="{{user.name}}">
当您在 prop 前加上 :
前缀时,您向 Vue 表明它是一个变量,而不是一个字符串。所以你不需要 user.name
周围的 {{}}
。尝试:
<template id="newtemp" :name ="user.name">
编辑-----
以上是对的,但这里更大的问题是当你改变URL并转到新路线时,原来的组件消失了。为了让第二个组件编辑父数据,第二个组件需要是第一个组件的子组件,或者只是同一组件的一部分。
------------以下仅适用于Vue 1 --------------
可以通过多种方式传递数据。该方法取决于使用类型。
如果您想在添加新组件时从 html 传递数据。这是使用道具完成的。
<my-component prop-name="value"></my-component>
仅当您将道具名称 prop-name
添加到您的 props
属性时,此道具值才可用于您的组件。
当数据由于某些动态或静态事件而从一个组件传递到另一个组件时。这是通过使用事件调度程序和广播程序来完成的。因此,例如,如果您有这样的组件结构:
<my-parent>
<my-child-A></my-child-A>
<my-child-B></my-child-B>
</my-parent>
并且您想将数据从 <my-child-A>
发送到 <my-child-B>
,然后在 <my-child-A>
中您必须发送一个事件:
this.$dispatch('event_name', data);
此事件将沿着 parent 链向上传播。从任何一个 parent 分支到 <my-child-B>
,您都可以将事件与数据一起广播。所以在 parent:
events:{
'event_name' : function(data){
this.$broadcast('event_name', data);
},
现在这个广播将沿着 child 链传播。在任何 child 你想抓取事件,在我们的例子中 <my-child-B>
我们将添加另一个事件:
events: {
'event_name' : function(data){
// Your code.
},
},
第三种传递数据的方式是通过v-links中的参数。当组件链被完全破坏或 URI 更改时使用此方法。而且我可以看到你已经理解了它们。
决定你想要什么类型的数据通信,然后选择合适的。
我找到了一种在 Vue 中将父数据传递到组件范围的方法,我认为这有点 hack,但也许这会对你有所帮助。
1) Vue实例中作为外部对象引用数据(data : dataObj)
2) 然后在子组件的数据 return 函数中只是 return parentScope = dataObj
瞧。现在你可以做 {{ parentScope.prop }}
之类的事情了,而且会很有魅力。
祝你好运!
将数据从 parent 组件发送到 child 的最佳方法是使用 props。
通过 props
将数据从 parent 传递到 child
- 在child 中声明
- 通过
<child :name="variableOnParent">
传递给child
props
(数组或object)
参见下面的演示:
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>
一个全局的JS变量(对象)可以用来在组件之间传递数据。示例:将数据从 Ammlogin.vue 传递到 Options.vue。在 Ammlogin.vue 中,rspData 设置为来自服务器的响应。在 Options.vue 中,服务器的响应可通过 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>
我使用 $root
访问主要属性。
Vue.component("example", {
template: `<div>$root.message</div>`
});
...
<example></example>
上面提到的响应效果很好,但是如果你想在两个兄弟组件之间传递数据,那么也可以使用事件总线。 查看此博客,这将帮助您更好地理解。
假设有 2 个组件:CompA 和 CompB 具有相同的父组件和 main.js 用于设置主 vue 应用程序。要在不涉及父组件的情况下将数据从 CompA 传递到 CompB,您可以执行以下操作。
在 main.js 文件中,声明一个单独的全局 Vue 实例,这将是事件总线。
export const bus = new Vue();
在生成事件的 CompA 中:您必须将事件发送到总线。
methods: {
somethingHappened (){
bus.$emit('changedSomething', 'new data');
}
}
现在的任务是监听发出的事件,所以,在 CompB 中,你可以像这样监听。
created (){
bus.$on('changedSomething', (newData) => {
console.log(newData);
})
}
优点:
- 更少和更干净的代码。
- 父级不应参与将数据从一个子组件传递给另一个子组件(随着子组件数量的增加,它将变得难以维护)
- 遵循 pub-sub 方法。