【问题标题】:How can I change data value from one component to another component in Vue Js?如何在 Vue Js 中将数据值从一个组件更改为另一个组件?
【发布时间】:2018-03-16 23:30:27
【问题描述】:

我是 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 属性,但我不明白。

【问题讨论】:

  • 你能更新一下组件A和组件B吗?
  • 我更新了我的代码。请查看并回答我。

标签: javascript vue.js vuejs2 vue-component


【解决方案1】:

您正在寻找Vuex

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

看看他们的文档,应该很简单。

【讨论】:

  • 我认为这是对所提出问题的正确答案。另一种解决方案将数据和数据驱动程序移动到组件 A 中,并假设组件 B 只是一个显示组件。我认为这个问题更类似于组件 A 作为可能包含一些操作按钮的布局,而组件 B 是存储所有数据并进行转换的地方。 Vuex 解决了这种情况。
【解决方案2】:

您可以将 props 传递给组件 B。这些 props 可以由父组件更新。您可以将 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>

【讨论】:

    【解决方案3】:

    有几种方法...

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

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

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

    本文档包含您想知道的一切。我不想放任何代码,因为doc很清楚。

    VueX 是最好的方法!非常好用。。

    https://vuejs.org/v2/guide/components.html

    【讨论】:

      【解决方案4】:

      //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

      使用 Props 将数据传递给子组件(Parent to Child)

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

      【讨论】:

        【解决方案5】:

        实际上 props 很糟糕,有时你在 jquyer 中有一些旧的外部库,只需要该死的传递值。在 99% 的时间里,使用的道具能起到作用。

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

        在数据中创建主变量让我知道作为对象{}

        this.$root.letmeknow

        然后在组件代码中的某处

        this.$root.letmeknow = this;

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

        【讨论】:

          猜你喜欢
          • 2018-02-19
          • 2021-09-14
          • 2018-09-24
          • 2021-08-07
          • 2018-11-18
          • 1970-01-01
          • 2018-07-08
          • 2019-02-05
          • 2018-01-12
          相关资源
          最近更新 更多