1

I currently have three steps in a form that I want to show sequentially, so I created three components - one for each step of the process.

My app.js file:

import LocationList from './components/LocationList.vue';
import ChooseTime from './components/ChooseTime.vue';
import ChooseMethod from './components/ChooseMethod.vue';

Vue.component('location-list', LocationList);
Vue.component('choose-time', ChooseTime);
Vue.component('choose-method', ChooseMethod);

let store = {
    isVisible: {
        steps: {
            one: true,
            two: false,
            three: false,
        }
    }
};

new Vue({
    el: '#app-order',

    data: store,

    router
});

Now, when my one and only route is called,

import VueRouter from 'vue-router';

let routes = [
    {
        path: '/order',
        component: require('./views/Order.vue')
    }
];

export default new VueRouter({
    routes
});

all these components are being loaded properly. The issue is that when I try to v-show them one at a time:

Order.vue:

<template>

    // ...

    <location-list v-show="isVisible.steps.one"></location-list>
    <choose-time v-show="isVisible.steps.two"></choose-time>
    <choose-method v-show="isVisible.steps.three"></choose-method>

    // ...

</template>

<script>
</script>

<style>
</style>

The error message I receive is:

[Vue warn]: Property or method "isVisible" is not defined on the instance but referenced during render. Make sure to declare reactive data properties in the data option.

But when I check within Vue's browser extension, isVisible is defined within the root element?

error

As you can see it is in the root-element, but not inside the Order view though.

Thanks for any help!

5
  • Is isVisible referenced in one of the step components templates? Commented Jul 25, 2017 at 0:14
  • No, I just have a basic file structure like <template></template> <script></script> <style></style>. I do not reference isVisible anywhere in it Commented Jul 25, 2017 at 0:16
  • I don't see a problem with what's posted so far. Commented Jul 25, 2017 at 0:19
  • I do, but it is a private one unfortunately. I could replicate the issue later and share it in a repo, but I just updated the post with some more detailed information. I think the issue might be because the Order view does not include the isVisible property, only the root parent element. I am fairly new with Vue, so I sorry about this! Commented Jul 25, 2017 at 0:36
  • Yes, that would be the issue. You need to pass isVisible down to the Order.vue, or define it there entirely. Commented Jul 25, 2017 at 0:38

1 Answer 1

1

In Vue, child components do not have direct access to data defined in their parents. You have to pass the data down.

I think you would probably save yourself a little trouble if you just defined isVisible in Order.vue. However, if you want to leave it where it is, you need to pass it into the component.

One easy way to do that is to define isVisble as a property of Order.vue and then pass it through your router-view.

<router-view :is-visible="isVisible"></router-view>

There are other ways of passing props to routes that are defined in the router documentation.

The reason I say you would save your self some trouble defining isVisible in Order.vue is because whenever you want to change the values of your steps, you will need to do it at the root as you currently have it defined.

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

3 Comments

I agree, I feel I like it would be better to define it within the component as well. I would just move the isVisible object to Order.vue and have it inside a mounted() method?
@Chris just define it in the components data. data(){ return { isVisible: ...}}
Thanks so much Bert!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.