如何将数组数据从 vuejs 传递到 laravel api 控制器

Posted

技术标签:

【中文标题】如何将数组数据从 vuejs 传递到 laravel api 控制器【英文标题】:How to pass array data from vuejs to laravel api controller 【发布时间】:2019-08-15 01:02:00 【问题描述】:

我想通过 api 使用 vuejs 使用 laravel 制作发票系统。首先显示所有产品,当我点击添加到购物车时,它添加了。

截图如下:

现在我想将输入填充数据发送到 order_masters 表,包括最后插入的 ID 购物车数据发送 order_details 表。

但我不能传递整个数据。有时会传递客户信息,但不会传递购物车数据。

N。 B:我正在使用 vuejs、vform 和 API

我的组件代码如下:

<template>
<div class="row">
    <div class="col-md-7">
        <div class="col-md-11">
            <input type="hidden" v-model="field">
            <input type="search" v-model="query" class="form-control form-control-sm mb-3" placeholder="Search Here">
        </div>
        <div class="row justify-content-center">
            <div v-show="products.length" v-for="(product, id) in products" :key="id" class="card col-xl-3 col-md-3 col-sm-3 mb-5 mr-5 float-left" style="background-color:lightgray">
                <div class="card-body">
                    <h5 class="card-title">product.name</h5>
                    <p class="card-text"><input type="text" v-model="product.qty" class="form-control form-control-sm mb-2"></p>
                    <strong class="">
                           product.price TK
                        </strong>
                    <button class="btn btn-sm btn-primary float-right" @click="addToCart(product)">
                        <i class="fas fa-plus"></i>
                    </button>
                </div>
            </div>
        </div>
        <div v-show="!products.length" class="alert alert-danger text-center" role="alert">
            <strong>Opps! No Data Found!</strong>
        </div>
        <pagination v-if="pagination.last_page > 1" :pagination="pagination" :offset="5" @paginate="query === ''? showProduct(): searchProduct()"></pagination>
    </div>

    <div class="col-md-5 float-righ">
        <form @submit.prevent="store" @keydown="form.onKeydown($event)">
            <alert-error :form="form"></alert-error>
        <div class="row mb-2">
            <label for="" class="col-md-3 font-weight-bold">Name</label>
            <div class="col-md-9">
                <input type="text" v-model="form.name" name="name" class="form-control form-control-sm" :class=" 'is-invalid': form.errors.has('name') ">
                <has-error :form="form" field="name"></has-error>
            </div>
        </div>
        <div class="row mb-2">
            <label for="" class="col-md-3 font-weight-bold">Phone</label>
            <div class="col-md-9">
                <input type="text" v-model="form.phone" name="phone" class="form-control form-control-sm" :class=" 'is-invalid': form.errors.has('phone') ">
                <has-error :form="form" field="phone"></has-error>
            </div>
        </div>
        <div class="row mb-2">
            <label for="" class="col-md-3 font-weight-bold">Address</label>
            <div class="col-md-9">
                <input type="text" v-model="form.address" name="address" class="form-control form-control-sm" :class=" 'is-invalid': form.errors.has('address') " >
                <has-error :form="form" field="address"></has-error>
            </div>
        </div>
        <div class="mb-5">
            <input type="button" class="btn btn-sm btn-danger float-left" @click="clearCart" value="Clear" />
            <button type="submit" :disabled="form.busy" class="btn btn-sm btn-success float-right" @click="store">Checkout</button>
        </div>
        <table class="table table-sm table-bordered table-striped">
            <thead class="text-center">
                <tr>
                <th>ID</th>
                <th>Name</th>
                <th>Qty</th>
                <th>Price</th>
                <th>L/T</th>
                <th>Action</th>
                </tr>
            </thead> 
            <tbody>
                <tr v-for="(cart, i) in carts" :key="i">
                    <td class="text-center"><input type="hidden" name="pro_id[]" v-model="form.pro_id"> cart.id</td>
                    <td>cart.name </td>
                    <td class="text-right" name="qty"><input type="hidden" name="qty[]" v-model="form.qty">cart.qty</td>
                    <td class="text-right" name="unit_price"><input type="hidden" name="pro_id[]" v-model="form.price">cart.price</td>
                    <td class="text-right">cart.price*cart.qty</td>
                    <td class="text-center"><button type="button" @click="removeProduct(i)" class="btn btn-sm btn-danger">x</button></td>
                </tr>
            </tbody>
            <tfoot>
                <tr>
                    <td colspan="4" class="text-right font-weight-bold">Total =</td>
                    <td class="text-right"> total/-</td>
                </tr>
            </tfoot>
        </table>

        </form>
    </div>
    <vue-progress-bar></vue-progress-bar>
    <vue-snotify></vue-snotify>
</div>

<script>
export default 
data()
    return
        field: 'name',
        query: '',
        form: new Form(
            'name': '',
            'phone': '',
            'address':'',
            'pro_id' : [],
            'qty' : [],
            'unit_price' : []
        ),
        products:[],
        carts:[],
        pagination:
            current_page: 1
        
    
,
methods:
    store()
        var data = 
            carts: this.carts,
        
        this.$Progress.start()
        this.form.busy = true
        this.form.post('api/pos', data)
            .then( res => 
                this.form.reset()
                this.form.clear()
                this.$Progress.finish()
                console.log(data)
            )
            .catch( e => 
                this.$Progress.fail()
                console.log(e)
            )

      
  

</script>

这里是 API 控制器功能:

public function store(Request $request)

    $carts = json_decode($request->getContent('data'), true);

     $this->validate($request,[
         'name' => 'required',
         'phone' => 'required',
         'address' => 'required'
     ]);

     $order = new OrderMaster;
     $order->name = $request->name;
     $order->phone = $request->phone;
     $order->address = $request->address;
     $order->save();

    $order_id = DB::getPdo()->lastInsertId();

    foreach ($carts as $cart) 

         OrderDetails::create([
             'order_id' => $order_id,
             'product_id' => ?,
             'qty' => ?,
             'unite_price' => ?,
         ]);
    

【问题讨论】:

【参考方案1】:

首先,您调用 form.post 是错误的。第二个参数不是附加数据,而是axios.request调用的配置选项。

为了发送carts 数组,您应该将它添加到表单本身:

form: new Form(
  'name': '',
  'phone': '',
  'address':'',
  'pro_id' : [],
  'qty' : [],
  'unit_price' : [],
  'carts' : [], // <-- added
),

然后,在您的模板(和方法)中将 carts 的用法替换为 form.carts

现在,carts 将与其他数据一起发送到服务器。

最后,您根本不需要使用json_decode

//...
$data = $this->validate($request, [
  'name' => 'required',
  'phone' => 'required',
  'address' => 'required',
  'carts' => 'required|array',
  'carts.*.name' => 'string',
  'carts.*.id' => 'integer',
  'carts.*.qty' => 'integer',
  'carts.*.price' => 'numeric',
]);

然后,您可以使用$data 作为数据源。

foreach ($data['carts'] as $cart) 
  OrderDetails::create([
    'order_id' => $order_id,
    'product_id' => $cart['id'],
    'qty' => $cart['qty'],
    'unite_price' => $cart['price'],
  ]);

【讨论】:

@MizanurRahman 它应该可以工作。也许你会分享更多信息?【参考方案2】:

我以其他方式完成了它。不使用 vform 我使用了 axios。但我想使用 vform 来完成。

return
        field: 'name',
        query: '',
        form:
            'name': '',
            'phone': '',
            'address':''
        ,
        products:[],
        carts:[],
        pagination:
            current_page: 1
        
    
store()
        let client = 
            cli: this.form
        
        let data = 
            carts: this.carts
        

        this.$Progress.start()
        axios.post('api/pos', data, client)
            .then( res => 
                this.$Progress.finish()
                console.log(res)
            )
            .catch( e => 
                this.$Progress.fail()
                console.log(e)
            )

    

控制器:

$carts = json_decode($request->getContent('client','data'), true);

    $customer = $carts['client'];
    $pro_info = $carts['data'];

    foreach ($customer as $cus) 
        $order = new OrderMaster;
        $order->name = $cus['name'];
        $order->phone = $cus['phone'];
        $order->address = $cus['address'];
        $order->save();

    

    $order_id = DB::getPdo()->lastInsertId();

    foreach ($pro_info as $cart) 
        foreach ($cart as $c) 
            OrderDetails::create([
                'order_id' => $order_id,
                'product_id' => $c['id'],
                'qty' => $c['qty'],
                'unit_price' => $c['price'],
            ]);
        
    

【讨论】:

以上是关于如何将数组数据从 vuejs 传递到 laravel api 控制器的主要内容,如果未能解决你的问题,请参考以下文章

如何在VueJS中将数据从视图传递到组件

如何将动态生成的 vuejs 数组发布到 mysql 数据库

将数据从 Node 传递到 Vuejs

VueJS:通过路由器视图将数据从根元素传递到子组件

Vue JS 3:如何将数据从一个组件传递到另一个组件?

如何将检索到的数据从 v-for 绑定到 Vuejs 中的数据对象?