10

I want to update data in a component from my Vue instance. Finding plenty of examples on how to do the opposite, but nothing on this.

Say I have:

Vue.component('component', {
props: {
    prop: {
        default: null
    }
},
template: '#template',
data: function () {
    return {
        open: false
    };
}
});

Now I would like to set open to true from my Vue instance:

var root = new Vue({
    el: '#root',
    data: {},
    methods: { updateComponentData: function() {//set open to true} } });
7
  • 1
    Are you trying to use a parent component (root in your example) to update a child component (component in your example)? If so, it's highly recommended to follow a pattern where data is passed down from the parent to the child and events are passed up from the child to the parent (more in Vue's documentation). In your example, your child would have a prop called open and your parent would bind the value representing the open state to the child component. Commented Nov 14, 2017 at 10:38
  • If your component relationship is more complicated than parent-child, you may want to explore patterns revolving around state management. Commented Nov 14, 2017 at 10:40
  • The thing is, if you set open to be a prop you actually get a vue warning telling you it should be data. Either way, as you say I try to pass data from instance (root) to component (component). But they are seperate, so not sure if it counts as parent-child. i.e the component does not exist inside the vue instance. If you think you have a solution please post an answer because I've spent hours in the docs you linked with no real success. Commented Nov 14, 2017 at 10:43
  • 1
    "if you set open to be a prop you actually get a vue warning telling you it should be data" – would you expand your question to include this attempt? I would not expect Vue attempting to warn you regarding this. Commented Nov 14, 2017 at 10:47
  • "I try to pass data from instance (root) to component (component). But they are seperate, so not sure if it counts as parent-child. i.e the component does not exist inside the vue instance." – not too sure what you mean by this, you could expand your question to include an example more representative of your component hierarchy. A parent-child relationship between components is where the child is a direct descendent of the parent; in the parent's template, it could look something like this: <div>...<child-component>...</child-component>...</div>. Commented Nov 14, 2017 at 10:50

2 Answers 2

16

You should be able to do it with a Child Component Ref.

<script type="text/x-template" id="template" ref="component">
    <div>Hello, {{ name }}!</div>
</script>
var root = new Vue({
  el: '#root',
  data: {},
  methods: { 
    updateComponentData: function() {
      this.$refs.component.open = true
    } 
  } 
});

Working example

const Child = Vue.component('child', {
  template: `
    <div>
      <h2>Component1</h2>
      <div>Hello, {{ title }}! <strong>{{ open }}<strong></div>
    </div>
  `,
  data() {
    return {
      title: 'component',
      open: false
    }
  }
});

var root = new Vue({
  el: '#app',
  components: {
    Child
  },
  methods: { 
    updateComponentData: function() {
      //console.log('updateComponentData', this.$refs)
      this.$refs.component1.open = true
    } 
  } 
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.4/vue.min.js"></script>

<div id="app">
  <h2>Parent</h2>
  <button v-on:click="updateComponentData">Click me true</button>
  <child ref="component1"></child>
</div>

Sign up to request clarification or add additional context in comments.

4 Comments

It's Vue, see link to docs above, they use root.$refs.component outside the parent, so I assumed this.$refs.component inside. I'll check it out.
Thanks, as far as I can tell it does not work. I think because we are setting the ref inside a component, not the Vue Instance. So when we say this.$refs it does not find the ref we are talking about, because it is not in the instance itself
You're correct, the ref goes on the parent template. I've got a working sample now.
Thanks, I'm trying your example but adding components to my instance leads to entire page not compiling properly. Ill keep trying maybe im missing something
1

I just played with your code and the following codes works perfect please do try that. I have used Vue 'ref'. Add ref attribute in your component and then you can access that specific components data from parent.

Vue.component('component', {
    props: {
        prop: {
            default: null
        }
    },
    template: '#template',
    data: () => ({
        open: false
    })
});
var root = new Vue({
    el: '#root',
    data: () => ({}),
    methods: {
        updateComponentData: function() {
			      this.$refs.myComponent.open = true
        }
    },
});
<script src="https://unpkg.com/vue"></script>
<div id="root">
	  <button @click="updateComponentData">Change</button>
    <hr>
    <component ref='myComponent'></component>
</div>
<script type="text/x-template" id="template" ref="component">
    <div>Open: {{ open }}!</div>
</script>

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.