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

时间:2015-12-30 17:24:55

标签: vue.js

我很难理解如何在vue.js中的组件之间传递数据。我已经多次阅读过这些文档并查看了许多与vue相关的问题和教程,但我仍然没有得到它。

为了解决这个问题,我希望能帮助我们完成一个非常简单的例子

  1. 在一个组件中显示用户列表(已完成)
  2. 在点击(完成)链接时将用户数据发送到新组件 - 请参阅底部的更新。
  3. 编辑用户数据并将其发送回原始组件(尚未到目前为止)
  4. 这是一个小提琴,在第二步失败: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,
            }
       },
    })
    

    更新

    好的,我已经弄清楚了第二步。这是一个显示进展的新小提琴:https://jsfiddle.net/retrogradeMT/9pffnmjp/

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

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

7 个答案:

答案 0 :(得分:35)

-------------以下内容仅适用于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);

此活动将一直沿着母链传递。从您有<my-child-B>分支的父母那里,您可以将数据与数据一起广播。所以在父母:

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

现在这个广播将沿着子链传播。在您想要抓住活动的任何一个孩子的情况下,在我们的案例<my-child-B>中,我们将添加另一个活动:

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

传递数据的第三种方法是通过v-links中的参数。当组件链被完全销毁或URI发生变化时,使用此方法。我可以看到你已经理解了它们。

确定您想要的数据通信类型,并进行适当选择。

答案 1 :(得分:11)

我认为问题在于:

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

当您使用:为道具添加前缀时,您向Vue指示它是变量,而不是字符串。因此,您不需要{{}} user.name左右。尝试:

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

EDIT -----

以上是正确的,但更大的问题是,当您更改URL并转到新路线时,原始组件将消失。为了让第二个组件编辑父数据,第二个组件需要是第一个组件的子组件,或者只是同一组件的一部分。

答案 2 :(得分:10)

将数据从父组件发送到子组件的最佳方法是使用props

通过props

将数据从父级传递给子级
  • 在孩子
  • 中声明props(数组或object
  • 通过<child :name="variableOnParent">
  • 将其传递给孩子

见下面的演示:

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 }}</p>
  <child-comp :message="variableAtParent"></child-comp>
</div>

答案 3 :(得分:2)

我找到了一种方法将父数据传递到Vue中的组件范围,我认为这有点像黑客,但这可能会对你有帮助。

1)将Vue Instance中的参考数据作为外部对象(data : dataObj)

2)然后在子组件的数据返回函数中返回parentScope = dataObj并瞧。现在你可以做{{ parentScope.prop }}这样的事情,并且会像魅力一样。

祝你好运!

答案 4 :(得分:1)

上面提到的响应效果很好,但是如果您想在2个同级组件之间传递数据,那么也可以使用事件总线。 查看此博客,它可以帮助您更好地理解。

提供两个组件:CompA和CompB具有相同的parent和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);
    })
  }

优势:

  • 更少和干净的代码。
  • 父级不应参与将数据从一个子对象传给另一个子对象(随着孩子数量的增加,将变得难以维护)
  • 遵循发布-订阅方法。

答案 5 :(得分:0)

全局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>

答案 6 :(得分:0)

我使用"The latest supported Visual C++ downloads"访问主要属性。

$root