将数据从孩子传递给父母,而无需加载事件,这可能在 vue 世界上吗?

Posted

技术标签:

【中文标题】将数据从孩子传递给父母,而无需加载事件,这可能在 vue 世界上吗?【英文标题】:Pass data from child to parent without events just on load, it’s possible on vue world? 【发布时间】:2019-02-06 15:52:35 【问题描述】:

我觉得如果没有 @-click 事件或事件或输入字段或需要交互的东西,就不可能通过使用变量和控件在另一个数据变量中将数据从子数据变量传递到另一个数据变量中的父级进行交互这个来自父变量的数据,只是在加载时,有可能吗?

将 JSON 数据从子级传递给父级并从父级控制它

类似的东西

```

//child.vue
<template>
  <div>
    getData
  </div>
</template>

<script>
export default 
  name: 'Contributors', // this is the name of the component
  data () 
    return 
      getData: null
    
  ,
  mounted () 
    this.$http
      .get('https://api.github.com/repos/moumen-soliman/frontend-helper/stats/contributors')
      .then(response => (this.getData = response.data.reverse()))
      .catch(error => console.log(error.response))
  

</script>


app.vue
<template>
  <div id="app">
    <contributors /> //here just pass json data but I can't control it or make it equal variable in app.vue
    appGetData // i need to make it data equal current variable in parent data

  </div>
</template>
<script>
export default 
  name: 'App',
  data () 
    return 
      appGetData: contributors.getData // I need something like this 
    
  

</script>

```

【问题讨论】:

【参考方案1】:

您可以为此使用sync。流程如下:

在你的父组件中,sync appGetData 属性并将其绑定到子组件:

<contributors :app-get-data:sync="appGetData"/>

现在在我们的子组件中,我们可以将其返回:

this.$emit('update:appGetData', response.data.reverse())

我们可以修改孩子使用property而不是数据:

Props: ['appGetData']

现在您的孩子可以将该道具传递给模板:

 appGetData 

并且您有内聚的 2 路数据同步,其中父级是唯一的事实来源。

【讨论】:

它不起作用,结果是空的,所以如果你能告诉我一个完整的例子【参考方案2】:

@event 是首选方式。

我过去通过将函数作为道具传递来做到这一点,但这是一种反模式,应该避免。无论如何,除了警告之外,你可以这样做。

// child.vue
<template>
  <div>
    getData
  </div>
</template>

<script>
export default 
  name: 'Contributors', // this is the name of the component
  data () 
    return 
      getData: null
    
  ,
  props: 
    setAppGetData: 
      type: Function,
    ,
  ,
  mounted () 
    this.$http
      .get('https://api.github.com/repos/moumen-soliman/frontend-helper/stats/contributors')
      .then(response => (this.getData = response.data.reverse()))
      .then(() => (this.setAppGetData(this.getData) ) // run function here
      .catch(error => console.log(error.response))
  ,

</script>


// app.vue
<template>
  <div id="app">
    <contributors :setAppGetData="setAppGetData"/> //here just pass json data but I can't control it or make it equal variable in app.vue
    appGetData // i need to make it data equal current variable in parent data

  </div>
</template>
<script>
export default 
  name: 'App',
  data () 
    return 
      appGetData: null // I need something like this 
    
  ,
  methods: 
    setAppGetData (data) 
      this.appGetData = data
    
  

</script>

但在我看来,在这种情况下,侦听器可能仍然工作得更好、更容易。您可以添加另一个then 或使用内部watch 来触发该事件

还有一个

  mounted () 
    this.$http
      .get('https://api.github.com/repos/moumen-soliman/frontend-helper/stats/contributors')
      .then(response => (this.getData = response.data.reverse()))
      .then(() => (this.$emit('dataLoaded', this.getData) ) // emit data
      .catch(error => console.log(error.response))
  ,

使用手表

  watch: 
    getData(newValue) 
      this.$emmit('dataUpdated', newValue)
    
  ,

【讨论】:

【参考方案3】:

可能你想试​​试provide/inject。

但是注意

注意:提供和注入绑定不是反应式的。这是 故意的。但是,如果您传递一个观察到的对象,属性 在该对象上保持反应性。

下面是一个简单的演示(父组件提供它的实例给子组件,然后子组件将它的数据添加到父组件的一个数据属性中):

Vue.config.productionTip = false
let test = Vue.component('v-child', 
	template: `<div><button @click="getData()">Get Data</button>I am child: internalData</div>`,
  inject: 
  	_test: 
      default() 
        console.log('child must be inside one parent')
      
    
  ,
  data() 
  	return 
  		internalData: 
    
  ,
  methods: 
  	getData: function () 
    	setTimeout(()=>
      	this.internalData = value: 'Puss In Boots'
        this.$set(this._test.$data.childrenData, this._test.$data.childrenData.length, this.internalData)
      , 1500)
    
  
)

Vue.component('v-parent', 
	template: `<div><h2><button @click="changeData()">Next</button>Parent: childrenData</h2><hr><slot></slot></div>`,
  provide () 
    return 
      _test: this
    
	,
  data() 
  	return 
    	childrenData: []
    
  ,
  methods: 
  	changeData: function () 
      if(this.childrenData.length>0) 
    	  this.$set(this.childrenData[this.childrenData.length-1], 'value', 'So funny...')
       else 
        console.log('Empty...')
      
    
  
)
new Vue(
	el: '#app'
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="app">
  <v-parent><v-child></v-child></v-parent>
</div>

【讨论】:

【参考方案4】:

要将值从子组件传递到父组件,您可以使用同步修饰符。这是同一 link 的 Vue 文档

您可以采取以下措施来达到预期的效果:

在父组件中,将 prop 传递给 Child 组件时,使用 .sync 绑定它,如下所示

<contributors :appGetData.sync="appGetData"/>

现在,在子组件中,您可以使用以下代码 $emit 更新后的 appGetData

this.$emit('update:appGetData', response.data.reverse())

【讨论】:

以上是关于将数据从孩子传递给父母,而无需加载事件,这可能在 vue 世界上吗?的主要内容,如果未能解决你的问题,请参考以下文章

ReactJS:在孩子和父母之间传递数据[重复]

React context api,将数据从孩子传递给父母

Vue.js“超出最大调用堆栈大小”错误。将数据从父母传递给孩子失败

将父母作为孩子传递给函数c ++

Vue - 将数据从孩子传递给父母 - 基本发射不起作用

React,如何从父母那里访问孩子的状态?无需更新父母的状态