最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Pass data from child to parent without events just on load, it’s possible on vue world? - Stack Overflow

programmeradmin2浏览0评论

I feel that impossible to pass data from child to parent without @- click event or events or input fields or something need to interaction just on load pass data from child data variable to parent in another data variable by using variable and control in this data from the parent variable, just on load, it’s possible?

Pass JSON data from child to parent and control it from the parent

something like this

```

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

<script>
export default {
  name: 'Contributors', // this is the name of the ponent
  data () {
    return {
      getData: null
    }
  },
  mounted () {
    this.$http
      .get('')
      .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>

```

I feel that impossible to pass data from child to parent without @- click event or events or input fields or something need to interaction just on load pass data from child data variable to parent in another data variable by using variable and control in this data from the parent variable, just on load, it’s possible?

Pass JSON data from child to parent and control it from the parent

something like this

```

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

<script>
export default {
  name: 'Contributors', // this is the name of the ponent
  data () {
    return {
      getData: null
    }
  },
  mounted () {
    this.$http
      .get('https://api.github./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>

```

Share Improve this question asked Aug 31, 2018 at 15:14 Moumen SolimanMoumen Soliman 1,6841 gold badge16 silver badges21 bronze badges
Add a ment  | 

4 Answers 4

Reset to default 1

@event is the preferred way.

I've done this in the past by passing a function as a prop, but this is an antipattern, and should be avoided. Anyway that warning aside, here's how you could do it.

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

<script>
export default {
  name: 'Contributors', // this is the name of the ponent
  data () {
    return {
      getData: null
    }
  },
  props: {
    setAppGetData: {
      type: Function,
    },
  },
  mounted () {
    this.$http
      .get('https://api.github./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>

But it seems to me that in this case, a listener may still work better and be easier. You can just add another then or use an internal watch to trigger that event

one more then

  mounted () {
    this.$http
      .get('https://api.github./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))
  },

using watch

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

You can use sync for this. Here's the flow:

In your parent, sync the appGetData property and bind it to the child ponent:

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

Now in our child ponent we can just emit this back:

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

And we can modify the child to use a property and not data:

Props: ['appGetData']

Now your child can just pass that prop to the template:

{{ appGetData }}

And you have cohesive 2 way data synchronization where the parent is the single source of truth.

To pass values from Child ponent to Parent ponent you can use the Sync Modifier. Here's the Vue documentation for the same link

Here's what you can do to achieve the desired result:

In the parent, while passing a prop to your Child ponent, bind it using the .sync as shown below

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

Now, in the Child ponet you can $emit the updated appGetData using the below code:

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

Probably you want to try provide/inject.

But pay an attention on:

Note: the provide and inject bindings are NOT reactive. This is intentional. However, if you pass down an observed object, properties on that object do remain reactive.

Below is one simple demo (parent ponent provide its instance to child, then children add its data to one data property of parent ponent):

Vue.config.productionTip = false
let test = Vue.ponent('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.ponent('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./ajax/libs/vue/2.5.16/vue.js"></script>
<div id="app">
  <v-parent><v-child></v-child></v-parent>
</div>

发布评论

评论列表(0)

  1. 暂无评论