Membuat Blog dengan Laravel & VueJS - #17 | Homepage

wahyunanangwidodo

wahyunanangwidodo Rabu, 16 Oktober 2019

Membuat Blog dengan Laravel & VueJS - #17 | Homepage

Kita akan membuat halaman baru untuk menampilkan postingan blog yang akan dilihat oleh pengunjung blog.

Pada halaman homepage ini nantinya akan kita buat sebagai tempat untuk merender komponen dan nested routes dari vue router.

Langsung saja mari kita kerjakan.

Membuat File Baru

Langkah pertama mari kita buat file baru pada direktori views dengan nama homepage.blade.php dan copas html dibawah ini.
//homepage.blade.php
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- CSRF Token -->
    <meta name="csrf-token" content="{{ csrf_token() }}">
    <title>Homepage</title>
    <!-- Fonts -->
    <link rel="dns-prefetch" href="//fonts.gstatic.com">
    <link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet" type="text/css">
    <link href="https://use.fontawesome.com/releases/v5.0.6/css/all.css" rel="stylesheet">
    <!-- Styles -->
    <link rel="stylesheet" type="text/css" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
    <link href="{{ asset('css/homepage.css') }}" rel="stylesheet">     
  </head>
<body>
  <div id="app">
      <div class="page-wrapper chiller-theme toggled">
        <a id="show-sidebar" class="btn btn-sm btn-dark" href="#">
          <i class="fas fa-bars"></i>
        </a>

        <!-- Menu Homepage-->
          Menu
        <main class="page-content">
          <div class="container-fluid">
       
        <!-- Nested Routes -->
        <router-view></router-view>

          </div>
        <section class="footers bg-light pb-3">
         <div class="container pt-5">
             <div class="row">
                 <div class="col-xs-12 col-sm-6 col-md-6 footers-one">
                  <div class="footers-logo">
                  <p>Teluk Coding</p>
                        </div>
                  <div class="footers-info">
                      <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. </p>
                  </div>
                  <div class="social-icons"> 
                      <a href="#"><i id="social-fb" class="fab fa-facebook fa-2x social"></i></a>
                      <a href="#"><i id="social-tw" class="fab fa-twitter fa-2x social"></i></a>
                     <a href="#"><i id="social-em" class="fas fa-envelope fa-2x social"></i></a>
                </div>
              </div>  

               <div class="col-xs-12 col-sm-6 col-md-2 footers-four">
               
                  <ul class="list-unstyled">
                 <li><a href="#">Success item</a></li> 
                 <li><a href="#">Secondary item</a></li> 
                 <li><a href="#">Info item</a></li> 
                 <li><a href="#">Warning item</a></li> 
                 <li><a href="#">Danger item</a></li> 
                 <li><a href="#">Primary item</a></li> 
                </ul>
              </div>
               <div class="col-xs-12 col-sm-6 col-md-2 footers-five">
             
                  <ul class="list-unstyled">  
                  <li><a href="#">Success item</a></li> 
                 <li><a href="#">Secondary item</a></li> 
                 <li><a href="#">Info item</a></li> 
                 <li><a href="#">Warning item</a></li> 
                 <li><a href="#">Danger item</a></li> 
                 <li><a href="#">Primary item</a></li> 
                </ul>
              </div>
              
             </div>
         </div>
      </section>
        </main>
      </div> 
    </div>
    <script src="{{ asset('js/app.js') }}"></script>
    <script src="{{ asset('js/main.js') }}"></script> 
  
  </body>
</html>
Buat juga file css di direktori public/css dengan hama homepage.css dan paste css dibawah ini:
//homepage.css
body {
  font-size: 0.9rem;
}
.page-wrapper .sidebar-wrapper,
.sidebar-wrapper .sidebar-brand > a,
.sidebar-wrapper .sidebar-dropdown > a:after,
.sidebar-wrapper .sidebar-menu .sidebar-dropdown .sidebar-submenu li a:before,
.sidebar-wrapper ul li a i,
.page-wrapper .page-content,
.sidebar-wrapper .sidebar-search input.search-menu,
.sidebar-wrapper .sidebar-search .input-group-text,
.sidebar-wrapper .sidebar-menu ul li a,
#show-sidebar,
#close-sidebar {
  -webkit-transition: all 0.3s ease;
  -moz-transition: all 0.3s ease;
  -ms-transition: all 0.3s ease;
  -o-transition: all 0.3s ease;
  transition: all 0.3s ease;
} 

.page-wrapper {
  height: 100vh;
}

.page-wrapper .theme {
  width: 40px;
  height: 40px;
  display: inline-block;
  border-radius: 4px;
  margin: 2px;
}

.page-wrapper .theme.chiller-theme {
  background: #1e2229;
}
 
.page-wrapper.toggled .sidebar-wrapper {
  left: 0px;
}

@media screen and (min-width: 768px) {
  .page-wrapper.toggled .page-content {
    padding-left:  270px;
  }
} 
#show-sidebar {
  position: fixed;
  left: 0;
  top: 10px;
  border-radius: 0 4px 4px 0px;
  width: 35px;
  transition-delay: 0.3s;
}
.page-wrapper.toggled #show-sidebar {
  left: -40px;
} 

.sidebar-wrapper {
  width: 260px;
  height: 100%;
  max-height: 100%;
  position: fixed;
  top: 0;
  left: -300px;
  z-index: 999;
}

.sidebar-wrapper ul {
  list-style-type: none;
  padding: 0;
  margin: 0;
}

.sidebar-wrapper a {
  text-decoration: none;
}
 

.sidebar-content {
  max-height: calc(100% - 30px);
  height: calc(100% - 30px);
  overflow-y: auto;
  position: relative;
}

.sidebar-content.desktop {
  overflow-y: hidden;
} 

.sidebar-wrapper .sidebar-brand {
  padding: 10px 20px;
  display: flex;
  align-items: center;
}

.sidebar-wrapper .sidebar-brand > a {
    text-transform: uppercase;
    font-weight: bold;
    flex-grow: 1;
    text-align: center;
    font-size: 18px;
    color: #fff;
}

.sidebar-wrapper .sidebar-brand #close-sidebar {
  cursor: pointer;
  font-size: 20px;
} 
.sidebar-wrapper .sidebar-header {
  padding: 20px;
  overflow: hidden;
}

.sidebar-wrapper .sidebar-header .user-pic {
    width: 71px;
    border-radius: 73%;
    margin: 3px auto;
    border: 5px solid #33353a;
    overflow: hidden;
}

.sidebar-wrapper .sidebar-header .user-pic img {
  object-fit: cover;
  height: 100%;
  width: 100%;
}

.sidebar-wrapper .sidebar-header .user-info {
text-align: center;
}

.sidebar-wrapper .sidebar-header .user-info > span {
  display: block;
}

.sidebar-wrapper .sidebar-header .user-info .user-role {
  font-size: 12px;
}
  

.sidebar-wrapper .sidebar-search > div {
  padding: 10px 20px;
} 

.sidebar-wrapper .sidebar-menu {
  padding-bottom: 10px;
}

.sidebar-wrapper .sidebar-menu .header-menu span {
  font-weight: bold;
  font-size: 14px;
  padding: 15px 20px 5px 20px;
  display: inline-block;
}

.sidebar-wrapper .sidebar-menu ul li a {
  display: inline-block;
  width: 100%;
  text-decoration: none;
  position: relative;
  padding: 8px 30px 8px 20px;
}

.sidebar-wrapper .sidebar-menu ul li a i {
  margin-right: 10px;
  font-size: 12px;
  width: 30px;
  height: 30px;
  line-height: 30px;
  text-align: center;
  border-radius: 30px;
}

.sidebar-wrapper .sidebar-menu ul li a:hover > i::before {
  display: inline-block;
  animation: swing ease-in-out 0.5s 1 alternate;
}

.sidebar-wrapper .sidebar-menu .sidebar-dropdown > a:after {
  font-family: "Font Awesome 5 Free";
  font-weight: 900;
  content: "\f105";
  font-style: normal;
  transform: rotate(90deg);
  display: inline-block;
  font-style: normal;
  font-variant: normal;
  text-rendering: auto;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  background: 0 0;
  position: absolute;
  right: 15px;
  top: 14px;
}

.sidebar-wrapper .sidebar-menu .sidebar-dropdown .sidebar-submenu ul {
  padding: 5px 0;
}

.sidebar-wrapper .sidebar-menu .sidebar-dropdown .sidebar-submenu li {
  padding-left: 25px;
  font-size: 13px;
}

.sidebar-wrapper .sidebar-menu .sidebar-dropdown .sidebar-submenu li a:before {
  content: "\f111";
  font-family: "Font Awesome 5 Free";
  font-weight: 400;
  font-style: normal;
  display: inline-block;
  text-align: center;
  text-decoration: none;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  margin-right: 10px;
  font-size: 8px;
}

.sidebar-wrapper .sidebar-menu ul li a span.label,
.sidebar-wrapper .sidebar-menu ul li a span.badge {
  float: right;
  margin-top: 8px;
  margin-left: 5px;
}

.sidebar-wrapper .sidebar-menu .sidebar-dropdown .sidebar-submenu li a .badge,
.sidebar-wrapper .sidebar-menu .sidebar-dropdown .sidebar-submenu li a .label {
  float: right;
  margin-top: 0px;
}

.sidebar-wrapper .sidebar-menu .sidebar-submenu {
  display: none;
}

.sidebar-wrapper .sidebar-menu .sidebar-dropdown.active > a:after {
  transform: rotate(-90deg);
  right: 17px;
} 
.sidebar-footer {
  position: absolute;
  width: 100%;
  bottom: 0;
  display: flex;
}

.sidebar-footer > a {
  flex-grow: 1;
  text-align: center;
  height: 30px;
  line-height: 30px;
  position: relative;
}

.sidebar-footer > a .notification {
  position: absolute;
  top: 0;
}

.badge-sonar {
  display: inline-block;
  background: #980303;
  border-radius: 50%;
  height: 8px;
  width: 8px;
  position: absolute;
  top: 0;
}

.badge-sonar:after {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  border: 2px solid #980303;
  opacity: 0;
  border-radius: 50%;
  width: 100%;
  height: 100%;
  animation: sonar 1.5s infinite;
}
 
.card-title {
    margin-bottom: .75rem;
    font-size: 17px;
    font-weight: 500;
}

.jumbotron{
      background: #7F7FD5;
    background: -webkit-linear-gradient(to right, #91EAE4, #86A8E7, #7F7FD5);
    background: linear-gradient(to right, #91EAE4, #86A8E7, #7F7FD5);
}
.page-wrapper .page-content #titlepage{
        font-size: 2em;
    font-weight: 500;
    border-left: 4px solid #999;
    padding: 0 6px;
}

.page-wrapper .page-content {
  display: inline-block;
  width: 100%;
  padding-left: 0px;
}

.page-wrapper .page-content > div {
  padding: 20px 40px;
}

.page-wrapper .page-content {
  overflow-x: hidden;
}
 
::-webkit-scrollbar {
  width: 5px;
  height: 7px;
}
::-webkit-scrollbar-button {
  width: 0px;
  height: 0px;
}
::-webkit-scrollbar-thumb {
  background: #525965;
  border: 0px none #ffffff;
  border-radius: 0px;
}
::-webkit-scrollbar-thumb:hover {
  background: #525965;
}
::-webkit-scrollbar-thumb:active {
  background: #525965;
}
::-webkit-scrollbar-track {
  background: transparent;
  border: 0px none #ffffff;
  border-radius: 50px;
}
::-webkit-scrollbar-track:hover {
  background: transparent;
}
::-webkit-scrollbar-track:active {
  background: transparent;
}
::-webkit-scrollbar-corner {
  background: transparent;
}
 
.chiller-theme .sidebar-wrapper {
    background: #222222;
    border-right: 5px solid #607D8B;
}

.chiller-theme .sidebar-wrapper .sidebar-header,
.chiller-theme .sidebar-wrapper .sidebar-search,
.chiller-theme .sidebar-wrapper .sidebar-menu {
    border-top: 1px solid #3a3f48;
}

.chiller-theme .sidebar-wrapper .sidebar-search input.search-menu,
.chiller-theme .sidebar-wrapper .sidebar-search .input-group-text {
    border-color: transparent;
    box-shadow: none;
}

.chiller-theme .sidebar-wrapper .sidebar-header .user-info .user-role,
.chiller-theme .sidebar-wrapper .sidebar-header .user-info .user-status,
.chiller-theme .sidebar-wrapper .sidebar-search input.search-menu,
.chiller-theme .sidebar-wrapper .sidebar-search .input-group-text,
.chiller-theme .sidebar-wrapper .sidebar-menu ul li a,
.chiller-theme .sidebar-footer>a {
    color: #818896;
}
.chiller-theme .sidebar-wrapper .sidebar-menu ul li a:hover{
  color:#fff;
}

.chiller-theme .sidebar-wrapper .sidebar-menu ul li:hover>a,
.chiller-theme .sidebar-wrapper .sidebar-menu .sidebar-dropdown.active>a,
.chiller-theme .sidebar-wrapper .sidebar-header .user-info,
.chiller-theme .sidebar-wrapper .sidebar-brand>a:hover,
.chiller-theme .sidebar-footer>a:hover i {
    color: #b8bfce;
}

.page-wrapper.chiller-theme.toggled #close-sidebar {
    color: #bdbdbd;
}

.page-wrapper.chiller-theme.toggled #close-sidebar:hover {
    color: #ffffff;
}

.chiller-theme .sidebar-wrapper ul li:hover a i,
.chiller-theme .sidebar-wrapper .sidebar-dropdown .sidebar-submenu li a:hover:before,
.chiller-theme .sidebar-wrapper .sidebar-search input.search-menu:focus+span,
.chiller-theme .sidebar-wrapper .sidebar-menu .sidebar-dropdown.active a i {
    color: #fff;
    text-shadow:0px 0px 10px rgba(22, 199, 255, 0.5);
}

.chiller-theme .sidebar-wrapper .sidebar-menu ul li a i,
.chiller-theme .sidebar-wrapper .sidebar-menu .sidebar-dropdown div,
.chiller-theme .sidebar-wrapper .sidebar-search input.search-menu,
.chiller-theme .sidebar-wrapper .sidebar-search .input-group-text {
    background: #33353a;
}

.chiller-theme .sidebar-wrapper .sidebar-menu .header-menu span {
    color: #6c7b88;
}

.chiller-theme .sidebar-footer {
    background: #3a3f48;
    box-shadow: 0px -1px 5px #282c33;
    border-top: 1px solid #464a52;
}

.chiller-theme .sidebar-footer>a:first-child {
    border-left: none;
}

.chiller-theme .sidebar-footer>a:last-child {
    border-right: none;
}
.container-fluid .breadcrumb {
    display: -ms-flexbox;
    display: flex;
    -ms-flex-wrap: wrap;
    flex-wrap: wrap;
    padding: 5px 15px;
    margin-bottom: 0;
    list-style: none;
    background-color: #e9ecef;
    border-radius: .25rem;
        font-size: 14px;
}

.breadcrumb-item.active {
    color: #6c757d;
    font-style: italic;
}

.show-content h1{
     padding: 19px 0px 5px;
    font-size: 2em;
    line-height: 1.2;
    font-weight: 400;
}

.show-content p{ 
    font-size: 16px; 
}
.user-cat{
      padding-bottom: 5px;
    border-bottom: 1px solid #eee;
    margin-bottom: 12px;
}
.footers a {color:#696969;}
.footers p {color:#696969;}
.footers ul {line-height:30px;}
#social-fb:hover {
     color: #3B5998;
     transition:all .001s;
 }
 #social-tw:hover {
     color: #4099FF;
     transition:all .001s;
 }
 #social-gp:hover {
     color: #d34836;
     transition:all .001s;
 }
 #social-em:hover {
     color: #f39c12;
     transition:all .001s;
 }

 .social-icons{
  padding: 28px 0;
  font-size: 14px;
 }
.footers-logo{
  font-size: 2rem;
}

 .social-icons i{
      padding-right: 20px;
 }

 .about-me{
      font-size: 2rem;
    padding: 12px 0;
 }
 .comment-wrap{
      padding: 11px 0;
    border-top: 1px solid #eee;
 }
 .comment-wrap p{
  font-size: 20px;
    padding-bottom: 10px;
 }

Membuat Komponen

Kita buat sebuah komponen untuk mengambil data pos dan dirender pada halaman homepage.

Mari kita buat sebuah komponen di direktori resources/js/components dengan nama HomepagePosts.vue.
//HomepagePosts.vue
<template>
<div>
  <div class="jumbotron">
    <h1 class="display-4">Hello, world!</h1>
    <p class="lead">This is a simple hero unit, a simple jumbotron-style component for calling extra attention to featured content or information.</p>
    <hr class="my-4"> 
  </div>
  <h2 id="titlepage">Blog</h2>
  <hr>
  <div class="row">
        <div class="form-group col-md-12">
          <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.</p> 
        </div>
  </div>      
  <hr>
  <div class="row">
        <div class="col-md-4" v-for="post in posts" style="padding-bottom: 25px;">          
          <div class="card rounded-0 p-0 shadow-sm">
            <img :src="'/images/' + post.image" class="card-img-top rounded-0" alt=""/>
            <div class="card-body">
                <h6 class="card-title"> {{post.title }}</h6>
                 <a href="#" target="_blank" class="btn btn-light btn-sm float-left"><i class="fa fa-share"></i></a> 

                 <router-link :to="{name: 'readpost', params: {id: post.id} }">
                <button type="button" class="btn btn-secondary btn-sm float-right">
                       Read More..
                 </button> 
               </router-link>
            </div>
          </div>          
        </div>   
    </div>
</div> 
</template> 

<script>
  export default{
    data: function(){
      return {
        posts: []
      }
    },
    created: function(){
      this.getPosts();
    },
    methods:{
      getPosts(){
        axios.get("/api/getHomepagePosts")
        .then(response => {
          console.log(response.data)
          this.posts = response.data;
        })
        .catch(error => {
          console.log(error.response.data)
        })
      }
    }
  }
</script>
Kita tampilkan data pos dalam bentuk array menggunakan directive v-for.
Didalam directive kita membuat alias pos dari properti posts (v-for="post in posts") untuk dirender menjadi list array.

Kemudian buka file app.js untuk kita import dan membuat rotuenya.
//app.js
import HomepagePosts from './components/HomepagePosts'

{
  path: '/',
  name: 'homepageposts',
  component: HomepagePosts,
  props: true, 
},

Membuat Route

Selanjutnya buat route di web.php. 
//web.php
Route::get('/', function () {
    return view('homepage');
});

Route::get('/getHomepagePosts', 'PostController@getHomepagePosts');

PostController.php

Kita buat method pada postcontroller.php untuk mengambil data pos.
//PostController.php
public function getHomepagePosts()
{
  $posts = Post::latest()->get(); 
      
  return response()->json($posts);
}

Terakhir mari kita lihat hasilnya, jika tidak ada kesalahan hasilnya akan seperti gambar dibawah ini.

Membuat Blog dengan Laravel & VueJS - #17 | Homepage

Sampai disini kita berhasil menampilkan data postingan dihalaman homepage blog atau index.

Urutan part / bagian dari tutorial ini bisa dilihat disini.

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel

Berlangganan

Berlangganan untuk mendapat pemberitahuan artikel terbaru via email.