Claudio Marzella
Claudio Marzella

Reputation: 15

Use method in template, out of instance vue

This is warning when i click on go to contact in tab about: "Property or method "switchTo" is not defined on the instance but referenced during render. Make sure to declare reactive data properties in the data option. (found in component )."

How do I fix this?

new Vue({
  el: '#app',
  data: {
    currentPage: 'home',
  },
  methods: {
     switchTo: function(page) {
            this.currentPage = page;
     }
  },
  components: {
    home: {
      template: `#home`,
     },
    about: {
      template: `#about`,  
    },
    contact: {
      template: '#contact'

    }
  }
})
.navigation {
  margin: 10px 0;
}

.navigation ul {
  margin: 0;
  padding: 0;
}

.navigation ul li {
  display: inline-block;
  margin-right: 20px;
}

input, label, button {
  display: block
}

input, textarea {
  margin-bottom: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.10/vue.js"></script>


<div id="app">
  <div class="navigation">
    <ul>
      <li><a href="#home" @click="switchTo('home')">Home</a></li>
      <li><a href="#about" @click="switchTo('about')">About</a></li>

    </ul>
  </div>

  <div class="pages">
    <keep-alive>
      <component v-bind:is="currentPage">
      </component>
    </keep-alive>
  </div>
</div>

<template id="home">
<p>home</p>
</template>

<template id="about">
<p>about <a href="#contact" @click="switchTo('contact')">go to contact</a></p>

</template>

<template id="contact">
<p>contact</p>
</template>

Upvotes: 0

Views: 3832

Answers (2)

AldoRomo88
AldoRomo88

Reputation: 2076

Just change your about template to this

<template id="about">
    <p>about <a href="#contact" @click="$root.switchTo('contact')">go to contact</a></p>
</template>

new Vue({
  el: '#app',
  data: {
    currentPage: 'home',
  },
  methods: {
     switchTo: function(page) {
            this.currentPage = page;
     }
  },
  components: {
    home: {
      template: `#home`,
     },
    about: {
      template: `#about`,  
    },
    contact: {
      template: '#contact'

    }
  }
})
.navigation {
  margin: 10px 0;
}

.navigation ul {
  margin: 0;
  padding: 0;
}

.navigation ul li {
  display: inline-block;
  margin-right: 20px;
}

input, label, button {
  display: block
}

input, textarea {
  margin-bottom: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.10/vue.js"></script>


<div id="app">
  <div class="navigation">
    <ul>
      <li><a href="#home" @click="switchTo('home')">Home</a></li>
      <li><a href="#about" @click="switchTo('about')">About</a></li>

    </ul>
  </div>

  <div class="pages">
    <keep-alive>
      <component v-bind:is="currentPage">
      </component>
    </keep-alive>
  </div>
</div>

<template id="home">
<p>home</p>
</template>

<template id="about">
<p>about <a href="#contact" @click="$root.switchTo('contact')">go to contact</a></p>

</template>

<template id="contact">
<p>contact</p>
</template>

Upvotes: 2

Potray
Potray

Reputation: 1998

I already solved a problem like this in this question: Calling methods in Vue build

It's not the same problem so it's not a repeated question, but the answer is the same:

In the created hook, add the component to window.componentInstance like this:

methods: {
  foo () {
    console.log('bar')
  }
}, 
created () {
  window.componentInstance = this
}

Then you can call the method anywhere like this:

window.componentInstance.foo()

Upvotes: 1

Related Questions