如何在Vue Js中将数据值从一个组件更改为另一个组件?

时间:2017-10-05 10:59:56

标签: javascript vue.js vuejs2 vue-component

我是Vue Js的新人。因此,我面临着从另一个组件更改数据值的问题。

我有一个组件A:

<template>
   <div id="app">
      <p v-on:click="test ()">Something</p>
   </div>
</template>

import B from '../components/B.vue';
export default {
    components: {
        B
    },
    methods: {
        test: function() {
            B.data().myData = 124
            B.data().isActive = true
            console.log(B.data().myData);
            console.log(B.data().isActive);
        }
    }
}

组件B:

export default {
    data() {
        return {
            myData: 123,
            isActive: false

        }
    }

}

它仍然是组件B数据。 但它不能影响组件B的数据。我想从组件A更改组件B的数据。我该怎么做?

请详细解释我。我见过vue js props属性,但我不明白。

5 个答案:

答案 0 :(得分:2)

您可以将道具传递给组件B.这些道具可以由父组件更新。您可以将B视为一个愚蠢的组件,只是呈现父母告诉它的现实。例如:

// Component A
<template>
   <div id="app">
      <p v-on:click="test ()">Something</p>
      <b data="myData" isActive="myIsActive"></b>
   </div>
</template>

<script>
import B from '../components/B.vue';
export default {
  components: {
    B
  },
  data() {
    return {
      myData: 0,
      myIsActive: false,
    };
  },
  methods: {
    test: function() {
      this.myData = 123
      this.myIsActive = true
    }
  }
}
</script>

// Component B
<template>
  <div>{{ data }}{{ isActive }}</div>
</template>

<script>
export default {
  props: {
    data: Number,
    isActive: Boolean
};
</script>

答案 1 :(得分:1)

您正在寻找Vuex

它是应用程序中所有数据的集中存储。

看看他们的文档,它应该非常简单。

答案 2 :(得分:0)

有几种方法......

  1. 如果您的组件具有父子关系,则可以将数据值从父级传递给子级。

  2. 如果您希望在子组件发生更改时与父组件进行通信,则可以使用vuejs事件发射器(自定义事件)在数据值更改时发出事件,并且可以在另一个组件中侦听该事件做你想做的事。

  3. 如果您的组件没有关系,那么您必须使用除上述内容之外的其他内容。你可以使用两个东西。一个是事件总线,另一个是状态管理库。对于vue,有一个名为VueX.it的官方状态管理库非常容易使用。如果你想使用除了vuex以外的东西,你可以使用它如redux,mobx等。

  4. 此文档包含您想要了解的所有内容。我不想放任何代码,因为doc很清楚。

    VueX是最好的方法!非常容易使用..

    column()

答案 3 :(得分:0)

//component A
Vue.component('my-button', {
  props: ['title'],
  template: `<button v-on:click="$emit('add-value')">{{title}}</button>`
});


Vue.component('my-viewer', {
  props: ['counter'],
  template: `<button>{{counter}}</button>`
});

new Vue({
  el: '#app',
  data: {
    counter: 0,
  },
  methods: {
    doSomething: function() {
      this.counter++;
    }
  }
})


Vue.component('blog-post', {
  props: ['title'],
  template: '<h3>{{ title }}</h3>'
});

//parent
new Vue({
  el: '#blog-post-demo',
  data: {
    posts: [{
        id: 1,
        title: 'My journey with Vue'
      },
      {
        id: 2,
        title: 'Blogging with Vue'
      },
      {
        id: 3,
        title: 'Why Vue is so fun'
      }
    ]
  }
});


Vue.component('blog-post2', {
  props: ['post'],
  template: `
                  <div class="blog-post">
                     <h3>{{ post.title }}</h3>
                     <button v-on:click="$emit('enlarge-text')">
                         Enlarge text
                     </button>
                     <div v-html="post.content"></div>
                 </div>`
})

new Vue({
  el: '#blog-posts-events-demo',
  data: {
    posts: [{
        id: 1,
        title: 'My journey with Vue'
      },
      {
        id: 2,
        title: 'Blogging with Vue'
      },
      {
        id: 3,
        title: 'Why Vue is so fun'
      }
    ],
    postFontSize: 1
  },
  methods: {
    onEnlargeText: function() {
      this.postFontSize++;
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<p>Two components adding & viewing value</p>
<div id="app">
  <my-button :title="'Add Value'" v-on:add-value="doSomething"></my-button>
  <my-viewer :counter="counter"></my-viewer>
</div>
<br>
<br>
<p>Passing Data to Child Components with Props (Parent to Child)</p>
<div id="blog-post-demo">
  <blog-post v-for="post in posts" v-bind:key="post.id" v-bind:title="post.title"></blog-post>
</div>

<p>Listening to Child Components Events (Child to Parent)</p>
<div id="blog-posts-events-demo">
  <div :style="{ fontSize: postFontSize + 'em' }">
    <blog-post2 v-for="post in posts" v-bind:key="post.id" v-bind:post="post" v-on:enlarge-text="onEnlargeText"></blog-post2>
  </div>
</div>

首先,您需要一个父级,以便两个组件可以通信。单击my-button组件时会触发事件add-value,该事件将调用doSomething()函数,然后更新该值并将其显示给my-viewer组件。

HTML

     <!--PARENT-->
     <div id="app"> 
          <!--CHILD COMPONENTS-->
          <my-button :title="'Add Value'" v-on:add-value="doSomething"></my-button>
          <my-viewer :counter="counter"></my-viewer>
     </div>

VUE.JS

     //component A
     Vue.component('my-button',{
         props:['title'],
         template:`<button v-on:click="$emit('add-value')">{{title}}</button>`
     });

     //Component B
     Vue.component('my-viewer',{
        props:['counter'],
        template:`<button>{{counter}}</button>`
     });

     //Parent
     new Vue({
         el: '#app',
         data:{
            counter:0,
         },
         methods:{
             doSomething:function(){
               this.counter++;
             }
        }
     })

这是基于Vue Components Guide

通过道具将数据传递到子组件(父级为子级)

VUE.JS

         //component (child)
         //Vue component must come first, else it won't work
         Vue.component('blog-post', {
             /*Props are custom attributes you can register on a component. When a 
               value is passed to a prop attribute, it becomes a property on that 
               component instance*/
             props: ['title'],
             template: '<h3>{{ title }}</h3>'
         });

         //parent
         new Vue({
            el: '#blog-post-demo',
            data: {
              posts: [
                 { id: 1, title: 'My journey with Vue' },
                 { id: 2, title: 'Blogging with Vue' },
                 { id: 3, title: 'Why Vue is so fun' }
              ]
            }
         });

HTML:

v-for将在帖子上循环并将数据传递到blog-post组件

         <div id="blog-post-demo">
             <blog-post  v-for="post in posts"
                         v-bind:key="post.id"
                         v-bind:title="post.title"></blog-post>
         </div>

收听子组件事件(子对父)

HTML

您必须先通过v-on:enlarge-text="onEnlargeText"注册事件才能使用$emit,并确保将其始终设置为小写,否则将无法正常工作。示例enlargeTextEnlargetext将始终转换为enlargetext,因此请使用扩大文本,因为它易于阅读且有效,有关$emit的简要说明,您可以读here

         <div id="blog-posts-events-demo">
            <div :style="{ fontSize: postFontSize + 'em' }">
                 <blog-post
                          v-for="post in posts"
                          v-bind:key="post.id"
                          v-bind:post="post"
                          v-on:enlarge-text="onEnlargeText"></blog-post>
            </div>
         </div>

VUE.JS

当用户单击button时,v-on:click="$emit('enlarge-text')"将触发,然后在父级中调用函数onEnlargeText()

         //component (child)
         Vue.component('blog-post', {
             props: ['post'],
             template: `
              <div class="blog-post">
                 <h3>{{ post.title }}</h3>
                 <button v-on:click="$emit('enlarge-text')">
                     Enlarge text
                 </button>
                 <div v-html="post.content"></div>
             </div>`
         })

         //parent
         new Vue({
            el: '#blog-posts-events-demo',
            data: {
               posts: [
                    { id: 1, title: 'My journey with Vue' },
                    { id: 2, title: 'Blogging with Vue' },
                    { id: 3, title: 'Why Vue is so fun' }
               ],
            postFontSize: 1
         },
         methods:{
            onEnlargeText:function(){
               this.postFontSize++;
            }
          }
        })

答案 4 :(得分:0)

实际上道具很糟糕,有时您在 jquyer 中有一些旧的外部库,并且只需要该死的传递值。在 99% 的时间里使用可以工作的道具。

A) 花费大量时间来调试不断变化的代码色调以传递变量 B) 单线解决方案

在数据 letmeknow 中创建主变量作为对象 {}

<块引用>

this.$root.letmeknow

然后在组件代码中的某处

<块引用>

this.$root.letmeknow = this;

然后我得到了组件 console.log(this.$root.letmeknow),现在看看可以改变一些值