VueJS从父级访问子级组件的数据


74

我正在将vue-cli支架用于Webpack

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

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

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

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

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

更新:

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

Answers:


52

对于这种结构,最好拥有某种商店。

VueJS为此提供了解决方案,称为Vuex。如果您不准备使用Vuex,则可以创建自己的简单商店。

让我们尝试一下

MarkdownStore.js

export default {

 data: {
   items: []
 },

 // Methods that you need, for e.g fetching data from server etc.

 fetchData() {
   // fetch logic
 }

}

现在您可以在任何地方使用这些数据,并导入此Store文件

HomeView.vue

import MarkdownStore from '../stores/MarkdownStore'

export default {

 data() {
   sharedItems: MarkdownStore.data
 },

 created() {
   MarkdownStore.fetchData()
 }

}

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


文档也解释得很好。
吐司

如果我想在MarkdownStore中移动fetchData()逻辑怎么办。将所有组件逻辑放在组件内部是有意义的。
PJ3

这个解决方案几乎对我有用。我可以访问fetchData()方法,但是该方法无法访问MarkdownStore视图中的数据。this.data.items或this。$ data.items无效
YeeHaw1234

1
@ YeeHaw1234,您应该通过this.items组件从中访问它。
Belmin Bedak

43

我不确定这是否是个好习惯。

在我的子组件中,没有按钮可发出更改的数据。它的形式大约有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。


1
在哪里可以找到此文档?


为我工作得很好-谢谢@ PJ3
Zeshan

28

传递可观察的数据/参数的最佳实践是什么,以便在被子组件修改后可以访问新值?

道具的流动性是下降的一种方式,儿童切勿直接修改其道具。

对于复杂的应用程序,vuex是解决方案,但对于简单的情况,vuex是一个过大的选择。就像@Belmin所说的一样,由于有了反应系统,您甚至可以为此使用普通的JavaScript对象。

另一个解决方案是使用事件。Vue已经实现了EventEmitter接口,孩子可以使用this.$emit('eventName', data)它与父对象进行通信。

父母会听这样的事件:(@update是的简写v-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)

5

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

父组件

<template>
   <section>
      <childComponent ref="nameOfRef" />
   </section>
</template>

 methods: {
  save() {
   let Data = this.$refs.nameOfRef.$data;
 }
},

1

就我而言,我有一份注册表,已将其细分为各个部分。

如上所述,我使用了$ 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
  }
}

由于数据是反应性的,因此效果很好。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.