龙空技术网

将Vue.js单页应用程序添加到Laravel CRUD数据存储教程

晋州万悦城商贸 518

前言:

而今我们对“laraver5ajax分页”都比较重视,兄弟们都想要学习一些“laraver5ajax分页”的相关文章。那么小编也在网上汇集了一些对于“laraver5ajax分页””的相关内容,希望咱们能喜欢,姐妹们一起来了解一下吧!

CRUD(创建,读取,更新和删除)是数据存储的基本操作,也是您作为Laravel开发人员学习的第一件事情之一。

但是,当您将Vue.js单页应用程序添加到此堆栈的前端时会发生什么?突然之间,你必须处理异步 CRUD,因为操作现在不需要刷新页面。这需要特别注意确保数据的状态在前端后端都是一致的。

演示应用

演示全栈应用程序允许用户创建新的“Cruds”,我决定在创造性地思考一个令人难以置信的数量后,使用陌生名称的外星生物以及从红色变为绿色和后退的能力。

Cruds显示在主页上,用户有权创建新Crud,删除它们或更新颜色。

在Laravel后端添加CRUD

我们将在Laravel后端开始进行CRUD操作的教程。由于Laravel CRUD是其他地方广泛涉及的主题,因此我将继续简要介绍这一部分。

总之,我们会:

建立一个数据库

通过使用资源控制器设置RESTful API路由

定义控制器中的方法来执行CRUD操作

数据库

首先,迁移。我们的Cruds有两个属性:我们存储为文本的名称和颜色。

2018_02_02_081739_create_cruds_table.php

<?php...class CreateCrudsTable extends Migration{

public function up()

{

Schema::create('cruds', function (Blueprint $table) {

$table->increments('id');

$table->text('name');

$table->text('color');

$table->timestamps();

});

}

...}...

API

现在我们设置RESTful API路由。正面的resource方法Route将自动创建我们需要的所有操作。但是,我们不需要edit,show或者store我们会排除这些。

routes/api.php

<?phpRoute::resource('/cruds', 'CrudsController', [

'except' => ['edit', 'show', 'store']]);

有了这个,以下是我们现在可以在我们的API中使用的各种端点:

动词 路径 动作 路线名称

GET /api/cruds index cruds.index

GET /api/cruds/create create cruds.create

PUT /api/cruds/{id} update cruds.update

DELETE /api/cruds/{id} destroy cruds.destroy

Controller

我们现在需要在控制器中执行这些操作:

app/Http/Controllers/CrudsController.php

<?phpnamespace App\Http\Controllers;use App\Crud;use Illuminate\Http\Request;use Illuminate\Http\Response;use Faker\Generator;class CrudsController extends Controller{

// Methods}

我们来简单介绍一下每种方法:

创造。我们使用FakerLaravel附带的软件包随机化新Crud的名称和颜色。我们将新的Crud数据作为JSON发回。

<?php...public function create(Generator $faker){

$crud = new Crud();

$crud->name = $faker->lexify('????????');

$crud->color = $faker->boolean ? 'red' : 'green';

$crud->save();

return response($crud->jsonSerialize(), Response::HTTP_CREATED);}

索引。我们用index方法返回全套Cruds 。在更严重的应用程序中,我们使用分页,但现在让我们保持简单。

<?php...public function index(){

return response(Crud::all()->jsonSerialize(), Response::HTTP_OK);}

更新。这个动作允许客户改变Crud的颜色。

<?php...public function update(Request $request, $id){

$crud = Crud::findOrFail($id);

$crud->color = $request->color;

$crud->save();

return response(null, Response::HTTP_OK);}

破坏。这是我们如何删除我们的Cruds。

<?php...public function destroy($id){

Crud::destroy($id);

return response(null, Response::HTTP_OK);}

Vue.js应用程序

现在为我们的Vue单页应用程序。我们将首先创建一个单一文件组件来表示我们称之为Cruds CrudComponent.vue。

该组件仅用于显示,并没有太多逻辑。以下是值得注意的方面:

显示的图像取决于Crud的颜色(red.png或green.png)

有一个删除按钮,它会触发一个del点击方法,它会发出一个delete带有Crud ID的事件

有一个HTML选择(用于选择颜色),它会触发update变化的方法,该选择会发出一个事件,其中update包含Crud的ID和所选的新颜色

resources/assets/js/components/CrudComponent.vue

<template>

<div>

<div>

<img :src="image"/>

</div>

<div>

<h3>Name: {{ name | properCase }}</h3>

<select @change="update">

<option

v-for="col in [ 'red', 'green' ]"

:value="col"

:key="col"

:selected="col === color ? 'selected' : ''"

>{{ col | properCase }}</option>

</select>

<button @click="del">Delete</button>

</div>

</div></template><script>

export default {

computed: {

image() {

return `/images/${this.color}.png`;

}

},

methods: {

update(val) {

this.$emit('update', this.id, val.target.selectedOptions[0].value);

},

del() {

this.$emit('delete', this.id);

}

},

props: ['id', 'color', 'name'],

filters: {

properCase(string) {

return string.charAt(0).toUpperCase() + string.slice(1);

}

}

}</script><style>...</style>

在这个项目的另一个组成部分是App.js。这就是所有有趣的逻辑发生的地方,所以我们要一步一步地经历这一切。

我们从模板开始。这有以下工作:

用crud-component上面讨论的组件显示我们的Cruds

循环访问Crud对象(在数组中cruds),每个映射到一个实例crud-component。我们通过一个CRUD的所有属性通过对组件作为道具,并成立了听众update和delete从组件即将开展的活动

我们也有一个Add按钮,通过create点击触发一个方法来创建新的Cruds

resources/assets/js/components/App.vue

<template>

<div id="app">

<div>

<h1>Cruds</h1>

</div>

<crud-component

v-for="crud in cruds"

v-bind="crud"

:key="crud.id"

@update="update"

@delete="del"

></crud-component>

<div>

<button @click="create()">Add</button>

</div>

</div></template>

下面是script从App.js。我们也来谈谈这个:

我们从一个Crud创建用于表示我们的Crud的新对象开始。每个人都有一个ID,颜色和名称

我们导入相邻 CrudComponent

组件定义包含数组cruds作为数据属性。我还为每个CRUD操作存储了方法,这些操作将在下一节中介绍

resources/assets/js/components/App.vue

<template>...</template><script>

function Crud({ id, color, name}) {

this.id = id;

this.color = color;

this.name = name;

}

import CrudComponent from './CrudComponent.vue';

export default {

data() {

return {

cruds: []

}

},

methods: {

create() {

// To do

},

read() {

// To do

},

update(id, color) {

// To do

},

del(id) {

// To do

}

},

components: {

CrudComponent

}

}</script>

使用AJAX从前端触发CRUD

由于这是数据库所在的位置,因此全栈应用程序中的所有CRUD操作都将在后端执行。但是,CRUD操作的触发通常会发生在前端。

因此,HTTP客户端(可以通过互联网在我们的前端和后端之间进行通信的东西)在这里很重要。Axios是一个非常棒的HTTP客户端,它预装了默认的Laravel前端。

让我们再看看我们的资源表,因为每个AJAX调用都需要定位到相关的API endpoint:

动词 路径 动作 路线名称

GET /api/cruds index cruds.index

GET /api/cruds/create create cruds.create

PUT /api/cruds/{id} update cruds.update

DELETE /api/cruds/{id} destroy cruds.destroy

Read

我们从这个read方法开始。这个方法负责从后端检索我们的Cruds,并且将针对index我们的Laravel控制器的行为,从而使用GET endpoint / api / cruds。

我们可以设置GET调用window.axios.get,因为Axios库window在默认的Laravel前端设置中被作为对象的属性。

爱可信的方法,如get,post等返回一个承诺。我们then用一个回调链接一个方法来访问响应。解析的对象可以被解构以允许方便地访问data回调中的属性,这是AJAX响应的主体。

resources/assets/js/components/App.vue

...methods() {

read() {

window.axios.get('/api/cruds').then(({ data }) => {

// console.log(data)

});

},

...}/*

Sample response:

[

{

"id": 0,

"name": "ijjpfodc",

"color": "green",

"created_at": "2018-02-02 09:15:24",

"updated_at": "2018-02-02 09:24:12"

},

{

"id": 1,

"name": "wjwxecrf",

"color": "red",

"created_at": "2018-02-03 09:26:31",

"updated_at": "2018-02-03 09:26:31"

}

]

*/

正如你所看到的,Cruds是以JSON数组的形式返回的。Axios自动分析JSON,并为我们提供JavaScript对象,这很好。让我们在回调中遍历这些内容,然后使用我们的Crud工厂函数创建新的Cruds ,然后将它们推送到cruds数组数据属性即this.cruds.push(...)。

resources/assets/js/components/App.vue

...methods() {

read() {

window.axios.get('/api/cruds').then(({ data }) => {

data.forEach(crud => {

this.cruds.push(new Crud(crud));

});

});

},},...created() {

this.read();}

注意:我们需要read在应用程序加载时以编程方式触发该方法。我们从created钩子上做到了这一点,但效果不是很好。read完全摆脱该方法会更好,只需在第一次加载时将应用程序的初始状态内联到文档头中即可。如果您想实现它,请在文章Avoid This Common Anti-Pattern In Full-Stack Vue / Laravel Apps中深入讨论此设计模式。

完成后,我们现在可以在加载时在应用中看到Cruds:

更新(和同步状态)

该update行动要求我们发送表单数据,即color控制器知道要更新什么。Crud的ID在终点中给出。

这是讨论我在本文开头提到的问题的好时机:在全栈应用程序中,您必须确保数据的状态在前端和后端都一致。

在该update方法的情况下,我们可以在AJAX调用之前立即更新前端应用程序中的Crud对象,因为我们已经知道新的状态。

但是,在AJAX调用完成之前,我们不会执行此更新。为什么?原因是该操作可能因某种原因失败:互联网连接可能会丢失,更新后的值可能会被数据库拒绝或其他原因。

如果在更新前端状态之前等待服务器响应,我们可以确定该操作已成功完成,并且前端和后端数据已同步。

resources/assets/js/components/App.vue

methods: {

read() {

...

},

update(id, color) {

window.axios.put(`/api/cruds/${id}`, { color }).then(() => {

// Once AJAX resolves we can update the Crud with the new color

this.cruds.find(crud => crud.id === id).color = color;

});

},

...}

你可能会认为它的糟糕的用户体验等待AJAX解决,然后再显示更改后的数据,但是我认为用户误导用户认为改变已经完成,实际上我们并不是那么糟糕不知道它是否完成。

创建和删除

既然您已经理解了架构的关键点,那么您将能够理解这些最后两个操作,而无需我的评论:

resources/assets/js/components/App.vue

methods: {

read() {

...

},

update(id, color) {

...

},

create() {

window.axios.get('/api/cruds/create').then(({ data }) => {

this.cruds.push(new Crud(data));

});

},

del(id) {

window.axios.delete(`/api/cruds/${id}`).then(() => {

let index = this.cruds.findIndex(crud => crud.id === id);

this.cruds.splice(index, 1);

});

}}

加载指示器并禁用交互

如您所知,我们的CRUD操作是异步的,因此在等待AJAX呼叫到达服务器时,服务器会作出响应并接收响应时会有小的延迟。

为了改善用户体验,拥有某种视觉加载指示器并在我们等待当前操作解决时禁用任何交互性是很好的做法。这可以让用户知道正在发生的事情,并且可以让他们确定数据的状态。

对于Vue.js加载状态,有一些很好的插件,但我只是想在这里做一些快速和肮脏的事情:在AJAX正在进行时,我会覆盖整个屏幕,div在应用程序顶部半透明。这将用一块石头杀死所提到的两只鸟。

resources/views/index.blade.php

<body><div id="mute"></div><div id="app"></div><script src="js/app.js"></script></body>

为此,我们将mute在AJAX正在进行时将布尔值从false 切换到true,并使用此值来显示/隐藏div。

resources/assets/js/components/App.vue

export default {

data() {

return {

cruds: [],

mute: false

}

},

...}

下面是我们如何实现的触发mute的update方法。当该方法被调用时,mute被设置为true。当承诺解决时,AJAX已完成,因此用户再次与应用程序交互是安全的,因此我们将其设置mute为false。

resources/assets/js/components/App.vue

update(id, color) {

this.mute = true;

window.axios.put(`/api/cruds/${id}`, { color }).then(() => {

this.cruds.find(crud => crud.id === id).color = color;

this.mute = false;

});},

您需要在每个CRUD方法中实现相同的功能,但为了简洁起见,我不会在此显示。

为了使我们的加载指示器标记和CSS,我们<div id="mute"></div>直接在我们的mount元素上添加元素<div id="app"></div>。

从内联样式中可以看到,当类on添加时<div id="mute">,它将完全覆盖应用程序,添加灰色调并防止任何点击事件到达按钮并选择:

resources/views/index.blade.php

<!doctype html><html lang="{{ app()->getLocale() }}"><head>

<meta charset="utf-8">

<meta http-equiv="X-UA-Compatible" content="IE=edge">

<meta name="viewport" content="width=device-width, initial-scale=1">

<meta name="csrf-token" content="{{ csrf_token() }}">

<title>Cruds</title>

<style>

html, body {

margin: 0;

padding: 0;,

height: 100%;

width: 100%;

background-color: #d1d1d1

}

#mute {

position: absolute;

}

#mute.on {

opacity: 0.7;

z-index: 1000;

background: white;

height: 100%;

width: 100%;

}

</style></head><body><div id="mute"></div><div id="app"></div><script src="js/app.js"></script></body></html>

最后一块难题是on通过利用一个watch值来切换课程,mute每次mute更改时都会调用此方法:

export default {

...

watch: {

mute(val) {

document.getElementById('mute').className = val ? "on" : "";

}

}}

完成后,您现在可以使用带有加载指示器的全功能Vue / Laravel CRUD应用程序。

标签: #laraver5ajax分页