【问题标题】:VueJS access child component's data from parentVueJS 从父组件访问子组件的数据
【发布时间】:2017-03-17 13:25:01
【问题描述】:

我正在使用vue-cli scaffold for webpack

我的 Vue 组件结构/层次结构目前如下所示:

  • 应用程序
    • PDF 模板
      • 背景
      • 动态模板图片
      • 静态模板图片
      • 降价

在应用程序级别,我想要一个 vuejs 组件方法,它可以将所有子组件的数据聚合成一个可以发送到服务器的 JSON 对象。

有没有办法访问子组件的数据?具体来说,多层深度?

如果不是,那么传递可观察数据/参数的最佳做法是什么,以便当它被子组件修改时,我可以访问新值?我试图避免组件之间的硬依赖,因此到目前为止,使用组件属性传递的唯一内容是初始化值。

更新:

可靠的答案。查看两个答案后,我发现有用的资源:

【问题讨论】:

    标签: vue.js vue-component vuex


    【解决方案1】:

    在我的子组件中,没有按钮可以发出更改的数据。这是一个有 5~10 个输入的表格。单击另一个组件中的处理按钮后,数据将被提交。所以,当它发生变化时,我不能发出每个属性。

    那么,我做了什么,

    在我的父组件中,我可以从“ref”访问孩子的数据

    例如

    <markdown ref="markdowndetails"></markdown>
    <app-button @submit="process"></app-button>
    
    // js
    methods:{
        process: function(){
            // items is defined object inside data()
            var markdowns = this.$refs.markdowndetails.items 
        }
    }
    

    注意:如果你在整个应用程序中都这样做,我建议改为使用 vuex。

    【讨论】:

    • 在哪里可以找到相关文档?
    • 对我来说效果很好 - 谢谢@PJ3
    • 从child传给parent的方法很简单,emit比较复杂。谢谢
    • @BesLey 我认为他们有不同的用例。如果组件被设计为另一个特定组件的子组件,那么直接访问其内部数据可能是正确的选择,例如面向对象编程中的 getter/setter。但是如果要在不同的地方使用组件,那么事件方法是更合适的方法。
    【解决方案2】:

    对于这种结构,有某种Store就好了。

    VueJS为此提供了解决方案,它被称为Vuex。如果你还没有准备好使用Vuex,你可以创建自己的简单商店。

    让我们试试这个

    MarkdownStore.js

    export default {
    
     data: {
       items: []
     },
    
     // Methods that you need, for e.g fetching data from server etc.
    
     fetchData() {
       // fetch logic
     }
    
    }
    

    现在您可以在任何地方使用这些数据,只需导入此商店文件

    HomeView.vue

    import MarkdownStore from '../stores/MarkdownStore'
    
    export default {
    
     data() {
       sharedItems: MarkdownStore.data
     },
    
     created() {
       MarkdownStore.fetchData()
     }
    
    }
    

    如果你不想使用 Vuex,这就是你可以使用的基本流程。

    【讨论】:

    • Documentation 解释得也很好。
    • 如果我想在 MarkdownStore 中移动 fetchData() 逻辑怎么办。将所有组件逻辑放在组件内是有意义的。
    • 这个解决方案几乎对我有用。我可以访问 fetchData() 方法,但该方法无法访问 MarkdownStore 视图中的数据。 this.data.items 或 this.$data.items 不起作用
    • @YeeHaw1234 你应该从你的组件通过this.items 访问它。
    • @Toast 我真的相信文档可以(必须)详细说明此事。
    【解决方案3】:

    传递可观察数据/参数的最佳做法是什么,以便在子组件修改它时我可以访问新值?

    道具的流程是单向的,孩子不应该直接修改它的道具。

    对于复杂的应用程序,vuex 是解决方案,但对于简单的情况,vuex 是多余的。正如@Belmin 所说,您甚至可以使用纯 JavaScript 对象,这要归功于反应系统。

    另一种解决方案是使用事件。 Vue 已经实现了 EventEmitter 接口,子节点可以使用this.$emit('eventName', data) 与父节点通信。

    父母会像这样监听事件:(@updatev-on:update的简写)

    <child :value="value" @update="onChildUpdate" />
    

    并更新事件处理程序中的数据:

    methods: {
      onChildUpdate (newValue) {
        this.value = newValue
      }
    }
    

    下面是 Vue 中自定义事件的简单示例:
    http://codepen.io/CodinCat/pen/ZBELjm?editors=1010

    这只是父子通信,如果一个组件需要与它的兄弟通信,那么你将需要一个全局事件总线,在 Vue.js 中,你可以只使用一个空的 Vue 实例:

    const bus = new Vue()
    
    // In component A
    bus.$on('somethingUpdated', data => { ... })
    
    // In component B
    bus.$emit('somethingUpdated', newData)
    

    【讨论】:

      【解决方案4】:

      您可以将 ref 引用到子组件并将其用作 this this.$refs.refComponentName.$data

      父组件

      <template>
         <section>
            <childComponent ref="nameOfRef" />
         </section>
      </template>
      
       methods: {
        save() {
         let Data = this.$refs.nameOfRef.$data;
       }
      },
      

      【讨论】:

        【解决方案5】:

        就我而言,我有一个注册表单,我已将其分解为多个组件。

        如上所述,我使用了 $refs,例如,在我的父母中:

        在模板中:

        <Personal ref="personal" />
        

        脚本 - 父组件

        export default {
          components: {
            Personal,
            Employment
          },
          data() {
            return {
                personal: null,
                education: null
            }
          },
          mounted: function(){
               this.personal = this.$refs.personal.model
               this.education = this.$refs.education.model
          }
        }
        

        这很有效,因为数据是反应性的。

        【讨论】:

          猜你喜欢
          • 2018-07-20
          • 1970-01-01
          • 2020-04-14
          • 2020-10-16
          • 2017-04-16
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多