繁体   English   中英

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

[英]Passing data to components in vue.js

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

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

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

这是一个小提琴,在第二步失败: 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);
     }
    }
  })

第二个组件的 JS:

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

更新

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

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

V-link 更改参见 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,
        }
   },
})

-------------以下仅适用于 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 发生变化时使用此方法。 我可以看到你已经理解它们了。


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

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

通过props将数据从父级传递给子级

  • 在孩子中声明props (数组或 对象
  • 通过<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 }}<br>And is reactive (edit it) <input v-model="variableAtParent"></p> <child-comp :message="variableAtParent"></child-comp> </div>

我认为问题在这里:

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

当你在 prop 前面加上:时,你是在向 Vue 表明它是一个变量,而不是一个字符串。 所以你不需要user.name周围的{{}} 尝试:

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

编辑 - - -

以上是真的,但这里更大的问题是,当你更改 URL 并转到新路由时,原来的组件会消失。 为了让第二个组件编辑父数据,第二个组件需要是第一个组件的子组件,或者只是同一组件的一部分。

我找到了一种在 Vue 中将父数据传递给组件范围的方法,我认为这有点像 hack,但也许这会对你有所帮助。

1)Vue Instance中的数据作为外部对象引用(data : dataObj)

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

祝你好运!

上述响应效果很好,但如果你想在 2 个兄弟组件之间传递数据,那么也可以使用事件总线。 看看这个博客,它会帮助你更好地理解。

假设有 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);
    })
  }

优点:

  • 更少和清洁代码。
  • 父母不应参与将数据从 1 个子组件传递给另一个(随着子组件数量的增加,将变得难以维护)
  • 遵循发布-订阅方法。

我使用$root访问主要属性。

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

全局 JS 变量(对象)可用于在组件之间传递数据。 示例:将数据从 Amlogin.vue 传递到 Options.vue。 在 Ammlogin.vue 中,rspData 被设置为来自服务器的响应。 在 Options.vue 中,来自服务器的响应通过 rspData 提供。

索引.html:

<script>
    var rspData; // global - transfer data between components
</script>

登录.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;
            });
    },
....

选项.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>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM