Create Cart Laravel 5.4 +VueJS

Hello mọi người giờ cũng khuya rồi tự nhiên nhớ lại mình quên upload bài viết chia sẽ với mọi người cách tạo giỏ hàng trong Laravel 5.4 + Vuejs, vừa rồi mình có chia sẽ với mấy bạn cách cài đặt thư viện Vuejs trong laravel và tạo ứng dụng nhỏ nhỏ! Các bạn có thể xem lại các bài viết đó để mình bắt đầu làm phần thú vì này nhé!(TẠO ỨNG DỤNG LARAVEL 5.4 KẾT HỢP VỚI VUEJS)

Trong bài chia sẽ này mình sẽ không sử dụng thư viện shop-cart của laravel cung cấp mà mình sẽ viết tay bên phía front-end sao để gửi sang backend để xử lý, chúng ta  tự code xem giỏ hàng làm bằng Laravel 5.4 + Vuejs có khó không nào, theo mình nghĩ khó quá đi chứ, mà tuy theo mọi người nghĩ sau ::)

 Chuẩn bị:

 Bước 1: Tải source laravel 5.4 về và cài đặt thư viện Vuejs nhé các bạn có thể xem lại bài sau(Tạo ứng dụng Laravel 5.4 kết hợp với Vuejs) 

   composer create-project --prefer-dist laravel/laravel shopcart "5.4.*"

  sau đó bạn vào thư mục mới tải mở CMD lên gỏ npm install 

 - Thư viện Vuejs

 * cài đặt câu lệnh bên dưới cho VueJS để tích hợp vào thư viện

npm install --save-dev vue-axios vue-loader vue-router vue-template-compiler

 Bước 2: Tạo migration cho các bảng cần lưu trữ dữ liệu, ở đây mình tạo 3 bảng gồm(sanphams,khachhang,donhang)

 Bước 3: Bạn tạo cho mình file SanphamController.php, và tạo file model là Sanphams.php, chúng ta dùng để viết các thao tác lấy dữ liệu để hiển thị lên template VueJS(Cài này chúng ta hồi sẽ hiểu)

 

 * Công đoạn giờ đã xong rồi, giờ chúng ta xây dụng front-end nhé bên phía VueJS
 Đầu tiên bạn vào chỉnh sửa lại file welcome.blade.php tại thành như sau:

<!doctype html>
<html lang="{{ app()->getLocale() }}">
    <head>
        <meta charset="utf-8">
        <meta https-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Laravel Vue CRUD Application</title>
        <link href="{{asset('css/app.css')}}" rel="stylesheet" type="text/css">
    </head>
    <body>
        <div id="app">
        </div>
         <script>
           window.Laravel = <?php echo json_encode([
               'csrfToken' => csrf_token(),
                    ]); ?>
          </script>
        <script src="{{asset('js/app.js')}}"></script>
    </body>
</html>

- Tiếp bạn vào đường dẫn này (C:\xampp\htdocs\shopcart\resources\assets\js) tạo cho mình file Listsp.vue, Dathang.vue nhé 2 file này
 - Listsp.vue (dùng để hiễn thị danh sách sản phẩm và giỏ hàng khi chúng ta mua), mình có viết một số hàm và cũng có ghi chú thích bạn có thể hình dung ra khi
 các bạn chạy thử ứng dụng nhé

Source

 <template>
	<div class="row">
		<div class="col-md-6">
			<h5 class="label label-primary">Danh sach san pham</h5>
			<table class="table">
				<thead>
					<tr>
						<th>MASP</th>
						<th>TITLE</th>
						<th>IMAGE</th>
						<th>PRICE</th>
						<th>MUA</th>
					</tr>
				</thead>
				<tbody >
					<tr v-for="(sp,index) in listsp">
						<td>{{sp.masp}}</td>
						<td>{{sp.title}}</td>
						<td align="center"><img :src="sp.image" class="class_img" /></td>
						<td><span class="label label-success">{{sp.price}}</span></td>
						<td><a href="#" class="label label-primary" v-on:click="muasp(index)">Mua</a></td>
					</tr>
				</tbody>
			</table>

		</div>
		<div class="col-md-6">
			 <h5 class="label label-success">Danh sách đã mua |Số lượng:<span>{{tongsosl}}</span></h5>
			<table class="table">
				<thead>
					<tr>
						<th>MASP</th>
						<th>TITLE</th>
						<th>SL</th>
						<th>PRICE</th>
						<th>XOA</th>
					</tr>
				</thead>
				<tbody>
					 <tr v-for="(mua, index) in dsmua">    
                        <td><label class="label label-danger">{{mua.title}}</label></td>
                         <td><input type="int" v-model="mua.slmua" class="form-control" :name="mua.masp" :data-id="mua.id"></td>
                        <td><label class="label label-danger">{{mua.price}}</label></td>
                         <td><a href="#" class="label label-info" v-on:click="editsp(index)">Cập nhật</a></td>
                        <td><a href="#" class="label label-warning" v-on:click="xoasp(index)">Xóa</a></td>
                    </tr>
                    <tr>
                        <td colspan="4" v-if="tonggia>0"><label class="label label-primary">Tổng giá:{{tonggia}}</label>
                            <router-link :to="{name:'Dathang'}"><button class="btn btn-success" >Đặt hàng</button></router-link>
                        </td>
                    </tr>
				</tbody>
			</table>
		</div>
	</div>
</template>
<script>

	export default{
		data(){
			return {
				listsp:[],
				dsmua:[],  
	            tongsosl:0,
	            tonggia:0,
			}
		},
       
		created:function(){
			this.danhsachsp();
            this.load_dsmua();
			this.giohang();  
		},
		methods:{
			danhsachsp(){
				 this.axios.get("https://localhost:8000/sanpham").then((response)=>{
				 	this.listsp=response.data;
                });
			},
			muasp:function(index){
                var sanpham = this.listsp[index];//lấy vị trí index của sản phẩm
                var items = this.dsmua; //lấy tất cả danh sách mà chúng ta đã chọn mua
                var check_sp=false;  //dùng check xem sản phẩm này có trong danh sách mua chưa true:có, false:không
                var vitri=0;//dùng lấy vị trí sản phẩm có trong danh sách mua
                var result = Object.keys(items).map(function(key) {
                   if(items[key].masp==sanpham.masp){
                       check_sp=true;
                       vitri=key; //gán vị trí đã tìm thấy sản phẩm có trong danh sách mua
                   }
    			}); 
                if(check_sp){
                    //cập nhật lại sản phẩm đã có trong danh sách mua
                    this.dsmua[vitri]={
                        "id":sanpham.id,
                        "title":sanpham.title,
                        "image":sanpham.image,
                        "price":this.listsp[index].price*parseInt(this.dsmua[vitri].slmua+1),
                        //"slmua":document.querySelector("input[name="+index_edit.masp+"]").value
                        "slmua":parseInt(this.dsmua[vitri].slmua)+1,
                        "masp":sanpham.masp
                    }
                }else{

                    //thêm sản phẩm mới vào danh sách mua
                    this.dsmua.push({
                        "id":sanpham.id,
                        "title":sanpham.title,
                        "image":sanpham.image,
                        "price":sanpham.price,
                        "slmua":1,
                        "masp":sanpham.masp
                    });
                }
               
                this.save_dsmua();//gọi hàm này dùng để gửi mảng danh sách mua qua phía laravel lưu vào mảng session
                this.giohang();	//gọi tính lại tổng số lượng sản phẩm, tổng giá		
            },
            xoasp:function(index){
                this.dsmua.splice(index,1); //xóa sản phẩm khỏi danh sách mua
                this.save_dsmua();
                this.giohang();
            },
            editsp:function(index){
               // var sanpham = this.listsp.indexOf(index);
                 var index_edit = this.dsmua[index];
                // var sl = index_edit.slmua;
                 this.dsmua[index]={
                    "id":index_edit.id,
                    "title":index_edit.title,
                    "image":index_edit.image,
                    "price":this.listsp[index].price*parseInt(this.dsmua[index].slmua),
                    //"slmua":document.querySelector("input[name="+index_edit.masp+"]").value
                    "slmua":parseInt(this.dsmua[index].slmua),
                     "masp":index_edit.masp
                }
              this.save_dsmua();
              this.giohang();
            },
            giohang(){
                var items= this.dsmua;
                var tong=0;
                var toggia=0;
                var result = Object.keys(items).map(function(key) {
                    //console.log(items[key].slmua);
    				tong=tong+parseInt(items[key].slmua);
                    toggia=toggia+parseInt(items[key].price);
                   // console.log("tong la:"+tong);
    			}); 
                this.tongsosl=tong;
                this.tonggia=toggia;
            },
            load_dsmua(){
                this.axios.get("https://localhost:8000/cart-list").then((response)=>{
                    var data2 = response.data;
                    if(data2.length>0){
                       this.dsmua=response.data;
                       this.giohang();
                    }
                    else{
                        console.log("ckhong con");
                    }
                })
            },
            save_dsmua(){
                 //dùng lưu danh sách mua vào một cái mảng session bên phía laravel
                this.axios.post("https://localhost:8000/cart",this.dsmua).then((response)=>{
                    console.log(response.data);

                });
            }
            
		}
	}
	
</script>

- Dathang.vue: chúng ta dùng để show các sản phẩm mà chúng ta đã chọn mua, từ mảng đã lưu trong session bên phía laravel trả về phía vuejs đễ hiển thị lên template(mình nói vậy cho
các bạn dễ hình dung nhé)

Source:

<template>
	<div class="row">
		<div class="col-md-2"></div>
		<div class="col-md-8">
			<h5 class="label label-success">Thông tin đặt hàng</h5>
			<table class="table">
				<tr>
					<td>Họ tên</td>
					<td><input type="text" placeholder="Nhập họ tên" class="form-control" name="hoten" v-model="thongtin.hoten"></td>
				</tr>
				<tr>
					<td>Email</td>
					<td><input type="email" class="form-control" placeholder="Nhập email" name="email" v-model="thongtin.email"></td>
				</tr>
				<tr>
					<td>Số điện thoại</td>
					<td><input type="text" placeholder="Nhập họ số điện thoại" class="form-control" name="sodienthoai" v-model="thongtin.sodienthoai"></td>
				</tr>
				<tr>
					<td>Địa chỉ</td>
					<td><input type="text" class="form-control" placeholder="Nhập địa chỉ" name="diachi" v-model="thongtin.diachi"></td>
				</tr>
				<tr>
					<td colspan="2"><button class="btn btn-success" v-on:click="dathang">Đặt hàng</button>
						<label class="label label-primary" v-if="a_check">Đặt hàng thành công</label>
					</td>
				</tr>
			</table>
			<h5 class="label label-danger">Danh sách sản phẩm</h5>
			<table class="table">
				<thead>
					<tr>
						<th>MASP</th>
						<th>TITLE</th>
						<th>IMAGE</th>
						<th>SL</th>
						<th>PRICE</th>
					</tr>
				</thead>
				<tbody>
					<tr v-for="(sp,index) in dsmua">
						<td>{{sp.masp}}</td>
						<td><label class="label label-danger">{{sp.title}}</label></td>
						<td><img :src="sp.image" class="class_img"/></td>
						<td><input type="int" class="form-control" :value="sp.slmua"/></td>
						<td><span class="label label-danger">{{sp.price}}</span></td>
					</tr>
				</tbody>
			</table>
			
		</div>
		<div class="col-md-2"></div>
	</div>
</template>
<script>
	export default{
		data(){
			return {
				dsmua:[],
				thongtin:{},
				a_check:false
			}
		 
		},
		created:function(){
			this.load_dsmua();
		},
		methods:{
			load_dsmua(){
				this.axios.get("https://localhost:8000/cart-list").then((response)=>{
					this.dsmua=response.data;	
					console.log(this.dsmua);
				})
			},
			dathang:function(){
				
				this.axios.post("https://localhost:8000/sanpham",this.thongtin).then((response)=>{
					var result = response.data;
					if(parseInt(result.success)>0){
						console.log(result.success);
						this.a_check=true;
					}
					

				})
			}
		}
	}
</script>

 - các hàm như: load_dsmua(dùng để lấy tất cả các các sản phẩm mà chúng ta đã lưu trong mảng session), dathang(dùng khi chúng ta
 bấm nút đặt hàng)
 
 - Tiếp theo các bạn vào đường dẫn sau:C:\xampp\htdocs\shopcart\resources\assets\js tạo cho mình 1 file như App.vue
  source:

<template>
    <div class="container">
        <div>
            <transition name="fade">
                <router-view></router-view>
            </transition>
        </div>
    </div>
</template>

<style>
    .fade-enter-active, .fade-leave-active {
      transition: opacity .5s
    }
    .fade-enter, .fade-leave-active {
      opacity: 0
    }
</style>

<script>

    export default{
    }

- Tiếp theo cái này rất quan trọng để có thể sử dụng thì file này quan trong nhé bạn vào cũng đường dẫn C:\xampp\htdocs\shopcart\resources\assets\js và mở file app.js lên và chỉnh lại như sau:

import Vue from 'Vue';
import VueRouter from 'vue-router';
Vue.use(VueRouter);

import VueAxios from 'vue-axios';
import axios from 'axios';
Vue.use(VueAxios,axios);

// import cac template vao day
import App from './App.vue';
import Listsp from './components/Listsp.vue';
import Dathang from './components/Dathang.vue';


const routes = [
  {
      name: 'Listsp',
      path: '/',
      component: Listsp
  },
   {
      name: 'Dathang',
      path: '/dathang',
      component: Dathang
  }
 
];

const router = new VueRouter({mode:'history', routes: routes});
new Vue(Vue.util.extend({router},App)).$mount('#app');

- File này mình cũng đã giới thiệu ở 2 phần trước rồi nhé ::)! Mấy bạn có thể xem lại 2 phần trước để làm phần này sẽ hiểu rỏ và làm 
nhanh hơn nhé!

* Chúng ta xong phần front-end rồi giờ chúng ta tới phần backend nhé!

- Tiếp tục bạn mở file SanphamController.php và sửa lại thành như sau:

<?php

namespace App\Http\Controllers;
use Illuminate\Support\Facades\DB;
use Illuminate\Http\Request;
use App\Sanphams;
class SanphamController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $listsp = Sanphams::all();
        return response()->json($listsp);
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        //
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        if($request->session()->has('danhsach')){
         
            $id_insert= DB::table('khachhang')->insertGetId($request->all());
            if($id_insert>0){
               
               $cart = array();
               foreach($request->session()->get('danhsach') as $row){
                    $data_cart = array();
                    $data_cart['idkh'] = $id_insert;
                    $data_cart['masp'] = $row['masp'];
                    $data_cart['soluong'] = $row['slmua'];
                    $data_cart['price'] = $row['price'];
                    array_push($cart, $data_cart);
                }
                DB::table('donhang')->insert($cart);
                $request->session()->forget('danhsach');//xóa danh sách mua
                return Response()->json(array("success"=>$id_insert,"data_cart"=>$cart));

            }
            else{
                return Response()->json(array("success"=>0));
            }
            
        }
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        //
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        //
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        //
    }


    //them sản phẩm
    public function cart(Request $request){
        $dsmua = array();
        foreach($request->all() as $row){
            $sanpham = array();
            $sanpham['id']=$row['id'];
            $sanpham['title']=$row['title'];
            $sanpham['image']=$row['image'];
            $sanpham['price']=$row['price'];
            $sanpham['slmua']=$row['slmua'];
            $sanpham['masp']=$row['masp'];
            array_push($dsmua,$sanpham);
        }
        $request->session()->forget('danhsach');
        $request->session()->put('danhsach',$dsmua);
        return response()->json($dsmua);
    }
    public function cart_list(Request $request){
        if($request->session()->has("danhsach")){
            //echo response()->json($request->session()->get("danhsach"));
            
            return json_encode($request->session()->get("danhsach"));
        }
       
       
    }
}
?>

- Tiếp tục mờ file model Sanphams.php chỉnh lại thành như sau:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Sanphams extends Model
{
    protected $table="sanphams";
}
?>

- Giờ bạn vào C:\xampp\htdocs\shopcart\routes mở file web.php lên chỉnh như sau nhé
 

Route::get('/', function () {
    return view('welcome');
});

Route::resource("sanpham","SanphamController");

Route::post("cart","SanphamController@cart");
Route::get("cart-list","SanphamController@cart_list");

* Vậy là chúng ta đã xong phần backend rồi nhé! tôi tin phần backend này các bạn đã thường sử dụng nên mình không giải thích gì nhiều
mình chi giải thích bên Vuejs thôi nhé hi!

* Sau khi các bạn làm xong các bước từ trên xuống dưới thì các bạn muốn khởi động cho serve chạy bạn thực hiện câu lệnh như sau:
  npm run dev
  php artisan serve

  
* sau đó bạn gỏ trên trình duyệt https://localhost:8000 để nhận được kết quả mà nảy giờ bạn bỏ công ra làm nhé! Các bạn có thể download source tại đây
 https://github.com/skipperhoa/laravel-vuejs-cart

Các bạn nào thấy thú vị về những gì mình chia sẽ, bằng cách like website mình nhé! để ngày càng có kiến thức chia sẽ hơn! Chúc các bạn thành công!

Bài Viết Liên Quan

Messsage

Ủng hộ tôi bằng cách click vào quảng cáo. Để tôi có kinh phí tiếp tục phát triển Website!(Support me by clicking on the ad. Let me have the money to continue developing the Website!)