simbamufasa
simbamufasa

Reputation: 25

My children paths in vue refuse to render their view when resolved, they are rendering the parent view

I've tried redoing the whole process, refactoring the code a bit (I'm still rather new to vue so some of my code is a bit sloppy) but nothing seems to render the component for the child path. It always resolves to the parent path.

The code in my products.js (all paths under products)

import Products from '../views/Products.vue'
import Product from '../views/Product.vue'

export default {
  path: '/products',
  name: 'Products',
  component: Products,
  children: [
    {
      path: ':id',
      name: 'OneProduct',
      component: Product
    }
  ]
}

The code in my product.view (the view for the path: /products/:id)

<template>
  <div>
    <ExpandedProduct
      :prodNmae="$route.query.productName"
      :price="$route.query.prodPrice"
      :description="$route.query.description"
      />
  </div>
</template>

<script>
import ExpandedProduct from '../components/ExpandedProduct'

export default {
  name: 'Product',
  components: {
    ExpandedProduct
  }
}
</script>

<style lang="scss" scoped>

</style>

the ExpandedProduct component is the component which is supposed to be rendered when the route resolves to '/products/:id' ExpandedProduct.vue

<template>
  <div>
    <div class="carousel-holder">
      <v-carousel>
        <v-carousel-item
          v-for="(item,i) in items"
          :key="i"
          :src="item.src"
          reverse-transition="fade-transition"
          transition="fade-transition"
        ></v-carousel-item>
      </v-carousel>
    </div>
    <div class="description-holder">
      <h2>{{ $route.query }}</h2>
      <h4>{{ $route.query.prodPrice }}</h4>
      <h3>{{ $route.query.description }}</h3>
    </div>
  </div>
</template>

<script>
export default {
  name: 'ExpandedProduct',
  props: {
    prodName: {
      type: String,
      required: true,
      default: 'N/A'
    },
    price: {
      type: String,
      required: true,
      default: 'N/A'
    },
    description: {
      type: String,
      required: true,
      default: 'N/A'
    }
  },
  data () {
    return {
      items: [
        { src: 'https://cdn.vuetifyjs.com/images/carousel/squirrel.jpg' },
        { src: 'https://cdn.vuetifyjs.com/images/carousel/sky.jpg' },
        { src: 'https://cdn.vuetifyjs.com/images/carousel/bird.jpg' },
        { src: 'https://cdn.vuetifyjs.com/images/carousel/planet.jpg' }
      ]
    }
  }
}
</script>

<style lang="scss" scoped>

</style>

If someone could explain to me what I'm missing

Upvotes: 2

Views: 67

Answers (1)

muka.gergely
muka.gergely

Reputation: 8329

Creating a /product route and a separate /product/:id route is not the same as adding children with :id to a parent /product route.

The former creates a page without the :id parameter and a page that handles the :id parameter. The latter creates ONE page and a child router-view gets the :id parameter.

I think it's better explained with snippets:

1. This is the /product + /product/:id

const Foo = {
  template: `
    <div>Foo</div>
  `
}

const FooId = {
  template: `
    <div>Foo+{{ $route.params.id }}</div>
  `
}

const Bar = {
  template: `
    <div>Bar</div>
  `
}

const Baz = {
  template: `
    <div>Baz</div>
  `
}

const routes = [{
    path: '/foo',
    component: Foo
  },
  {
    path: '/foo/:id',
    component: FooId
  },
  {
    path: '/bar',
    component: Bar
  },
  {
    path: '/baz',
    component: Baz
  }
]

const router = new VueRouter({
  routes
})

new Vue({
  router,
  el: "#app",
})
div {
  border: 1px solid black;
  background: rgba(0, 0, 0, 0.2);
  padding: 8px 16px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
<div id="app">
  <h3>APP</h3>
  <p>
    <router-link to="/foo">Go to Foo</router-link><br />
    <router-link to="/foo/1">Go to Foo-1</router-link><br />
    <router-link to="/foo/2">Go to Foo-2</router-link><br />
    <router-link to="/bar">Go to Bar</router-link><br />
    <router-link to="/baz">Go to Baz</router-link><br />
  </p>
  <h3>ROUTES:</h3>
  <router-view></router-view>
</div>

2. This is the /product parent + :id children

const Foo = {
  template: `
    <div>
      Foo
      <router-view></router-view>
    </div>
  `
}

const FooId = {
  template: `
    <div>Foo+{{ $route.params.id }}</div>
  `
}

const Bar = {
  template: `
    <div>Bar</div>
  `
}

const Baz = {
  template: `
    <div>Baz</div>
  `
}

const routes = [{
    path: '/foo',
    component: Foo,
    children: [{
      path: ':id',
      component: FooId
    }]
  },
  {
    path: '/bar',
    component: Bar
  },
  {
    path: '/baz',
    component: Baz
  }
]

const router = new VueRouter({
  routes
})

new Vue({
  router,
  el: "#app",
})
div {
  border: 1px solid black;
  background: rgba(0, 0, 0, 0.2);
  padding: 8px 16px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
<div id="app">
  <h3>APP</h3>
  <p>
    <router-link to="/foo">Go to Foo</router-link><br />
    <router-link to="/foo/1">Go to Foo-1</router-link><br />
    <router-link to="/foo/2">Go to Foo-2</router-link><br />
    <router-link to="/bar">Go to Bar</router-link><br />
    <router-link to="/baz">Go to Baz</router-link><br />
  </p>
  <h3>ROUTES:</h3>
  <router-view></router-view>
</div>

3. Difference

The other name for children routes is nested routes. That means that a route is treated as root, and there's another router-view inside it (Ok, this is only for concept-explanation). (Nested routes)


So, the question is: do you want separate pages for products and each product (v1 - two separate routes), or you want a parent page for all your products and control the subsection of THAT page for each product (v2 - nested routes).

EDIT

Added a bit of CSS, so it's more understandable that what's inside what.

Upvotes: 1

Related Questions