Chances are if you've been developing with Vue for any amount of time, you've gotten this error:
Most of the time this error is because you misspelled a variable name somewhere.
But there are other causes as well.
I've gotten this one so many times, because it's a fairly easy mistake to make. Luckily, fixing it is pretty easy too, and I'm no longer stumped by it like I was when I first encountered it.
The full message is this:
Vue warn: Property or method "prop" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.
This gist of the error is this.
Vue is trying to render your component, and your component wants to use the property prop
, but Vue can't find prop
anywhere.
You don't need to worry about the reactive properties part of the error for now. As long as you define things in data
you'll be okay (but it is good to understand how reactivity works).
So, let's take a look at the 2 main problems that can cause this warning!
This is the one that always gets me.
I was typing too fast, or wasn't paying enough attention. I misspelled a variable name, and now Vue is complaining because it doesn't know what I'm trying to do.
It's a pretty easy mistake to make:
<template><div>{{ messag }}</div></template>
export default {data() {return {message: "Hello, world!"};}};
Whenever I see this warning I make sure to closely inspect my code and ensure I haven't made any weird typos.
But if there are no typos, the problem lies somewhere else!
This is another common mistake that is easy to make.
Components are scoped, meaning that something defined in one component isn't available in another. You have to use props and events to move things between components.
But just like making a typo, it's pretty easy to forget that a method or property is on one component, when it's actually on a different one.
How does this happen?
Well, sometimes you'll want to define multiple components in one file. It might look something like this:
<!-- Template for the Page component --><template><ul><link-item url="google.com" text="Google" /><link-item url="yahoo.com" text="Yahoo" /><link-item url="facebook.com" text="Facebook" /></ul></template>
// Clean up some code by using another componentconst LinkItem = {props: ['url', 'text'],template: `<li><a:href="url"target="_blank">{{ text }}</a></li>`};// Define the Page componentexport default {name: 'Page',components: { LinkItem },};
Instead of rewriting the <li>
tag each time, we just encapsulated it inside of the LinkItem
component.
But let's say we have a method on our Page
component that forces us to always use HTTPS instead of HTTP:
methods: {forceHTTPS(url) {// ...}}
What forceHTTPS
actually does is unimportant here.
But let's use it on our URLs so that we can make sure our app only links to safe website. We'll update LinkItem
to use this method:
const LinkItem = {props: ['url', 'text'],template: `<li><a:href="forceHTTPS(url)"target="_blank">{{ text }}</a></li>`};
We save it, our page refreshes, and...
Whoops.
It turns out that we forgot that forceHTTPS
isn't defined on the LinkItem
component, but instead it's defined on the Page
component!
Because the two components were in the same file, it was easy for us to get mixed up with what was and wasn't in scope. This is one reason why it can be a good idea to separate things out into their own files, even if it's only a few lines long.
Let's fix that then:
const LinkItem = {props: ['url', 'text'],methods: {forceHTTPS(url) {// Do some stuff...}},template: `<li><a:href="forceHTTPS(url)"target="_blank">{{ text }}</a></li>`};
Now things should be dandy.
As you can see, it's pretty easy to mess this up and forget that a value is on a different component. Thankfully Vue has this handy warning!
If you have this warning all of the time, don't worry about it!
It's really common, and even though I have a lot of experience with Vue, I still get this one all of the time.
To recap, the two main causes of this are:
If you're still having trouble with this warning, the problem may lie elsewhere. Ping me on Twitter and I'd love to help you out with it!