Skip to content

3. Pages & Routing

Khriztian Moreno edited this page Nov 8, 2017 · 2 revisions

Nuxt.js automatically generates the vue-router configuration based on your file tree of Vue files inside the pages directory.

We are going to have this file tree in our application:

pages/
--| post/
-----| _id.vue
-----| index.vue
-----| create.vue
--| index.vue

will automatically generate:

router: {
  routes: [
    {
      name: 'index',
      path: '/',
      component: 'pages/index.vue'
    },
    {
      name: 'post-id',
      path: '/post/:id?',
      component: 'pages/post/_id.vue'
    },
    {
      name: 'post',
      path: '/post',
      component: 'pages/post/index.vue'
    },
    {
      name: 'post-create',
      path: '/post/create',
      component: 'pages/post/create.vue'
    }
  ]
}

Pages Index

Vue-CLI creates by default an index.vue file in the pages folder, we will overwrite its contents with the following:

<template>
  <article class="post post-large">
    <div>
      <div class="post-date">
        <span class="day">27</span>
        <span class="month">Sep</span>
      </div>
      <div class="post-content">
        <h2>
          <a href="/post/1" class="">Talk: Estructurando la base de nuestro proyecto</a>
        </h2>
        <p>Talk: Estructurando la base de nuestro proyecto</p>
        <div class="post-meta">
          <span>
            <i class="fa fa-user"></i>
            By
            <a href="https://github.com/khriztianmoreno" target="_blank">khriztianmoreno</a>
          </span>
          <span>
            <i class="fa fa-comments"></i>
            <a href="#" target="_blank">0 Comments</a>
          </span>
          <a href="/post/1" class="btn btn-xs btn-primary pull-right">Read More...</a>
        </div>
      </div>
    </div>
  </article>
</template>

<style lang="scss" scoped>
  $primary-color: #41b883;

  .pagination {
    margin: -10px 0 20px;
  }

  .btn-primary {
    background-color: $primary-color;
    border-color: $primary-color;
  }

  article {
    border-bottom: 1px solid #DDD;
    margin-bottom: 50px;
    padding-bottom: 10px;

    &.post {
      h2 a {
        text-decoration: none;
      }
      .post-meta {
        font-size: 0.9em;
        margin-bottom: 7px;
        >span {
          display: inline-block;
          padding-right: 8px;
        }
        i {
          margin-right: 3px;
        }
      }
      .post-date {
        box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.1);
        float: left;
        margin-right: 10px;
        text-align: center;
        .month {
          background-color: $primary-color;
          border-radius: 0 0 2px 2px;
          box-shadow: 0 -1px 0 0 rgba(0, 0, 0, 0.07) inset;
          color: #FFF;
          font-size: 0.9em;
          padding: 0 10px 2px;
        }
        .day {
          background: #F4F4F4;
          border-radius: 2px 2px 0 0;
          color: $primary-color;
          display: block;
          font-size: 16px;
          font-weight: 500;
          font-weight: bold;
          padding: 10px;
        }
      }
    }
    &.post-large {
      margin-left: 60px;
      h2 {
        margin-bottom: 5px;
      }
      .post-date {
        margin-left: -60px;
      }
    }
  }
</style>

Pages Post - Index

Create a post folder inside pages and create the file index.vue that will have the same content of the index.vue of the root, only for practical purposes:

<template>
  <article class="post post-large">
    <div>
      <div class="post-date">
        <span class="day">27</span>
        <span class="month">Sep</span>
      </div>
      <div class="post-content">
        <h2>
          <a href="/post/1" class="">Talk: Estructurando la base de nuestro proyecto</a>
        </h2>
        <p>Talk: Estructurando la base de nuestro proyecto</p>
        <div class="post-meta">
          <span>
            <i class="fa fa-user"></i>
            By
            <a href="https://github.com/khriztianmoreno" target="_blank">khriztianmoreno</a>
          </span>
          <span>
            <i class="fa fa-comments"></i>
            <a href="#" target="_blank">0 Comments</a>
          </span>
          <a href="/post/1" class="btn btn-xs btn-primary pull-right">Read More...</a>
        </div>
      </div>
    </div>
  </article>
</template>

<style lang="scss" scoped>
  $primary-color: #41b883;

  .pagination {
    margin: -10px 0 20px;
  }

  .btn-primary {
    background-color: $primary-color;
    border-color: $primary-color;
  }

  article {
    border-bottom: 1px solid #DDD;
    margin-bottom: 50px;
    padding-bottom: 10px;

    &.post {
      h2 a {
        text-decoration: none;
      }
      .post-meta {
        font-size: 0.9em;
        margin-bottom: 7px;
        >span {
          display: inline-block;
          padding-right: 8px;
        }
        i {
          margin-right: 3px;
        }
      }
      .post-date {
        box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.1);
        float: left;
        margin-right: 10px;
        text-align: center;
        .month {
          background-color: $primary-color;
          border-radius: 0 0 2px 2px;
          box-shadow: 0 -1px 0 0 rgba(0, 0, 0, 0.07) inset;
          color: #FFF;
          font-size: 0.9em;
          padding: 0 10px 2px;
        }
        .day {
          background: #F4F4F4;
          border-radius: 2px 2px 0 0;
          color: $primary-color;
          display: block;
          font-size: 16px;
          font-weight: 500;
          font-weight: bold;
          padding: 10px;
        }
      }
    }
    &.post-large {
      margin-left: 60px;
      h2 {
        margin-bottom: 5px;
      }
      .post-date {
        margin-left: -60px;
      }
    }
  }
</style>

Pages Post - Create

Inside the post folder create the file create.vue and add the following content:

<template>
  <div>
    <form name="form">
      <div class="form-group">
        <label for="name">Title</label>
        <input type="text" id="name" placeholder="Enter title" required="required" value="" class="form-control"
        >
      </div>
      <div class="form-group">
        <label for="description">Description</label>
        <div class="row">
          <div class="col-sm-6">
            <textarea name="description" rows="10" value="# hello"></textarea>
          </div>
          <div class="col-sm-6">
            <div id="editor-result">
              <h1 id="hello">hello</h1>
            </div>
          </div>
        </div>
      </div>
      <button type="submit" class="btn btn-primary">Guardar</button>
    </form>
  </div>
</template>

<style lang="scss" scoped>
  #editor {
    margin: 0;
    height: 100%;
    font-family: "Helvetica Neue", Arial, sans-serif;
    color: #333;

    &-result {
      border: 1px solid;
      height: 100%;
      padding: 10px;
    }
  }

  textarea,
  #editor div {
    display: inline-block;
    width: 100%;
    height: 100%;
    vertical-align: top;
    box-sizing: border-box;
    padding: 0 20px;
  }

  textarea {
    border: none;
    border-right: 1px solid #ccc;
    resize: none;
    outline: none;
    background-color: #f6f6f6;
    font-size: 14px;
    font-family: "Monaco", courier, monospace;
    padding: 20px;
  }

  code {
    color: #f66;
  }
</style>

Pages Post - Detail

To define a dynamic route with a param, you need to define a .vue file OR a directory prefixed by an underscore. That's why we're going to create the _id.vue file with an empty template for now.

<template>
  <h1>Detalle</h1>
</template>

To see these steps complete, you can change to the 3-pages-routing branch in this repository.