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

Posted

技术标签:

【中文标题】如何在 Vue Js 中将数据值从一个组件更改为另一个组件?【英文标题】:How can I change data value from one component to another component in 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吗? 我更新了我的代码。请查看并回答我。 【参考方案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】:

有几种方法...

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

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

    如果您的组件没有关系,那么您必须使用除上述内容之外的其他内容。你可以用两个东西。一个是事件总线,一个是状态管理库。对于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),现在看到可以更改一些值

【讨论】:

以上是关于如何在 Vue Js 中将数据值从一个组件更改为另一个组件?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 vue.js 中将卡片数据从一个组件绑定到另一个组件卡片?

如何在 vue.js 中将类型数组对象更改为格式对象而不使用循环方法?

在 C++ 中将值从 X 更改为 X 会导致数据竞争吗?

Vue JS - 如何在父组件中获取道具值

如何在 Vue.js 中将实例化的 Vue 组件作为道具传递?

在Vuetify和Vue JS中将道具传递给父母