11
175b4e5b47
PHPhero • 于 2018-03-03发布 • 91次阅读 • (原文: www.bear777.com)

laravel5.5 + react完成简单的CRUD

[toc]

在这篇文章中,我想和大家分享如何在PHP Laravel框架中使用js来创建crud(Create Read Update Delete)应用程序。在这个例子中,您可以学习如何为laravel reactjs应用程序构建设置,我还使用axios post请求,获取请求,放入请求和删除请求来插入更新删除应用程序。

教程大概分为如下9步

  • 1.1) 第1步:安装Laravel 5.5
  • 1.2) 第2步:数据库配置
  • 1.3) 第3步:创建产品表格和模型
  • 1.4) 第4步:创建Web路由和API路由
  • 1.5) 第5步:创建PostController
  • 2.0) 第6步:安装ReactJS的配置
  • 3.0) 第7步:创建React组件文件
  • 4.0) 第8步:创建视图文件
  • 5.0) 第9步:运行项目

1. 安装laravel5.5

1.1 创建项目

composer create-project laravel/laravel laravel-react --prefer-dist

1.2 修改数据库配置

创建数据库并修改配置文件

cd laravel-react

vim .env

1.3 创建文章迁移表及模型

php artisan make:model Post -m

这样就创建好了Post模型以及posts

当然你也可以分两步执行

// 创建Post 模型
php artisan make:model Post
// 创建posts表
php artisan make:migration create_posts_table

修改迁移文件的up方法database/migrations/2018_01_23_021301_create_posts_table.php

public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->increments('id');
            $table->string('title');
            $table->text('content');
            $table->timestamps();
        });
    }

执行迁移

php artisan migrate

修改app/Post.php

?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    protected $fillable = [
        'title', 'body'
    ];
}

1.4 创建web路由和api路由

routes/web.php

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

routes/api.php

Route::resource('posts', 'PostController');

1.5 创建PostController

php artisan make:controller PostController --resource

--resource 会默认创建以下方法 1) index() 2) store() 3) edit() 4) update() 5) destory()6) show() 这里暂时我们不需要这个方法

修改 app/Http/PostController.php

?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Post;

class PostController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $data = Post::all();
        return response()->json($data);
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create(Request $request)
    {
        $data = new Post([
          'title' => $request->get('title'),
          'content' => $request->get('content')
        ]);
        $data->save();

        return response()->json('添加成功 :)');
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param \Illuminate\Http\Request $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $data = new Post([
          'title' => $request->get('title'),
          'content' => $request->get('content')
        ]);
        $data->save();

        return response()->json('保存成功 :)');
    }

    /**
     * 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)
    {
        $data = Post::find($id);
        return response()->json($data);
    }

    /**
     * Update the specified resource in storage.
     *
     * @param \Illuminate\Http\Request $request
     * @param int $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        $data = Post::find($id);
        $data->title = $request->get('title');
        $data->content = $request->get('content');
        $data->save();

        return response()->json('修改成功 :)');
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param int $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        $data = Post::find($id);
        $data->delete();

        return response()->json('删除成功 :)');
    }
}

2. 安装ReactJS

修改前端预置

php artisan preset react

npm 安装

npm install

运行

npm run dev

安装react router

npm install react-router@2.8.1

3. 创建React组件文件

我们需要创建的文件列表如下:

  • 1)app.js
  • 2)bootstrap.js
  • 3)组件/ CreatePost.js
  • 4)组件/ DisplayPost.js
  • 5)组件/ MasterPost.js
  • 6)组件/ MyGlobleSetting.js
  • 7)组件/ TableRow.js
  • 8)组件/ UpdatePost.js

resources/assets/js/app.js

require('./bootstrap');
import React from 'react';
import { render } from 'react-dom';
import { Router, Route, browserHistory } from 'react-router';

import Master from './components/Master';
import CreatePost from './components/CreatePost';
import DisplayPost from './components/DisplayPost';
import UpdatePost from './components/UpdatePost';

render(
  Router history={browserHistory}>
      Route path="/" component={Master} >
        Route path="/add-item" component={CreatePost} />
        Route path="/display-item" component={DisplayPost} />
        Route path="/edit/:id" component={UpdatePost} />
      Route>
    Router>,
        document.getElementById('crud-app'));

resources/assets/js/bootstrap.js

window._ = require('lodash');

try {
    window.$ = window.jQuery = require('jquery');

    require('bootstrap-sass');
} catch (e) {}

window.axios = require('axios');

window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';

let token = document.head.querySelector('meta[name="csrf-token"]');

if (token) {
    window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
} else {
    console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
}

resources/assets/js/components/CreatePost.js

import React, {Component} from 'react';
import {browserHistory} from 'react-router';
import MyGlobleSetting from './MyGlobleSetting';

class CreatePost extends Component {
  constructor(props){
    super(props);
    this.state = {postTitle: '', postContent: ''};

    this.handleChange1 = this.handleChange1.bind(this);
    this.handleChange2 = this.handleChange2.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);

  }
  handleChange1(e){
    this.setState({
      postTitle: e.target.value
    })
  }
  handleChange2(e){
    this.setState({
      postContent: e.target.value
    })
  }
  handleSubmit(e){
    e.preventDefault();
    const posts = {
      title: this.state.postTitle,
      content: this.state.postContent
    }
    let uri = MyGlobleSetting.url + '/api/posts';
    axios.post(uri, posts).then((response) => {
      browserHistory.push('/display-item');
    });
  }

    render() {
      return (
      div>
        h1>Create Posth1>
        form onSubmit={this.handleSubmit}>
          div className="row">
            div className="col-md-6">
              div className="form-group">
                label>Post Title:label>
                input type="text" className="form-control" onChange={this.handleChange1} />
              div>
            div>
            div>
            div className="row">
              div className="col-md-6">
                div className="form-group">
                  label>Post Content:label>
                  textarea className="form-control col-md-6" onChange={this.handleChange2}>textarea>
                div>
              div>
            div>br />
            div className="form-group">
              button className="btn btn-primary">Add Postbutton>
            div>
        form>
  div>
      )
    }
}
export default CreatePost;

resources/assets/js/components/DisplayPost.js

import React, {Component} from 'react';
import axios from 'axios';
import { Link } from 'react-router';
import TableRow from './TableRow';
import MyGlobleSetting from './MyGlobleSetting';
class DisplayPost extends Component {
  constructor(props) {
    super(props);
    this.state = {value: '', posts: ''};
  }
  componentDidMount(){
   axios.get(MyGlobleSetting.url + '/api/posts')
   .then(response => {
     this.setState({ posts: response.data });
   })
   .catch(function (error) {
     console.log(error);
   })
  }
  tabRow(){
   if(this.state.posts instanceof Array){
     return this.state.posts.map(function(object, i){
        return TableRow obj={object} key={i} />;
     })
   }
  }

  render(){
    return (
      div>
        h1>Posth1>

        div className="row">
          div className="col-md-10">div>
          div className="col-md-2">
            Link to="/add-item">Create PostLink>
          div>
        div>br />

        table className="table table-hover">
            thead>
            tr>
                td>IDtd>
                td>Post Titletd>
                td>Post Contenttd>
                td width="200px">Actionstd>
            tr>
            thead>
            tbody>
              {this.tabRow()}
            tbody>
        table>
    div>
    )
  }
}
export default DisplayPost;

resources/assets/js/components/Master.js

import React, {Component} from 'react';
import { Router, Route, Link } from 'react-router';

class Master extends Component {
  render(){
    return (
      div className="container">
        nav className="navbar navbar-default">
          div className="container-fluid">
            div className="navbar-header">
              a className="navbar-brand" href="https://www.bear777.com">bear777.coma>
            div>
            ul className="nav navbar-nav">
              li>Link to="/">HomeLink>li>
              li>Link to="add-item">Create PostLink>li>
              li>Link to="display-item">Post ListLink>li>
            ul>
          div>
      nav>
          div>
              {this.props.children}
          div>
      div>
    )
  }
}
export default Master;

resources/assets/js/components/MyGlobleSetting.js

class MyGlobleSetting {
  constructor() {
    this.url = 'http://localhost:8000';
  }
}
export default (new MyGlobleSetting);

resources/assets/js/components/TableRow.js

import React, { Component } from 'react';
import { Link, browserHistory } from 'react-router';
import MyGlobleSetting from './MyGlobleSetting';

class TableRow extends Component {
  constructor(props) {
      super(props);
      this.handleSubmit = this.handleSubmit.bind(this);
  }
  handleSubmit(event) {
    event.preventDefault();
    let uri = MyGlobleSetting.url + `/api/posts/${this.props.obj.id}`;
    axios.delete(uri);
      browserHistory.push('/display-item');
  }
  render() {
    return (
        tr>
          td>
            {this.props.obj.id}
          td>
          td>
            {this.props.obj.title}
          td>
          td>
            {this.props.obj.content}
          td>
          td>
          form onSubmit={this.handleSubmit}>
            Link to={"edit/"+this.props.obj.id} className="btn btn-primary">EditLink>
           input type="submit" value="Delete" className="btn btn-danger"/>        
         form>
          td>
        tr>
    );
  }
}

export default TableRow;

resources/assets/js/components/UpdatePost.js

import React, {Component} from 'react';
import axios from 'axios';
import { Link } from 'react-router';
import MyGlobleSetting from './MyGlobleSetting';

class UpdatePost extends Component {
  constructor(props) {
      super(props);
      this.state = {title: '', content: ''};
      this.handleChange1 = this.handleChange1.bind(this);
      this.handleChange2 = this.handleChange2.bind(this);
      this.handleSubmit = this.handleSubmit.bind(this);
  }

  componentDidMount(){
    axios.get(MyGlobleSetting.url + `/api/posts/${this.props.params.id}/edit`)
    .then(response => {
      this.setState({ title: response.data.title, content: response.data.content });
    })
    .catch(function (error) {
      console.log(error);
    })
  }
  handleChange1(e){
    this.setState({
      title: e.target.value
    })
  }
  handleChange2(e){
    this.setState({
      content: e.target.value
    })
  }

  handleSubmit(event) {
    event.preventDefault();
    const posts = {
      title: this.state.title,
      content: this.state.content
    }
    let uri = MyGlobleSetting.url + '/api/posts/'+this.props.params.id;
    axios.patch(uri, posts).then((response) => {
          this.props.history.push('/display-item');
    });
  }
  render(){
    return (
      div>
        h1>Update Posth1>
        div className="row">
          div className="col-md-10">div>
          div className="col-md-2">
            Link to="/display-item" className="btn btn-success">Return to PostLink>
          div>
        div>
        form onSubmit={this.handleSubmit}>
            div className="form-group">
                label>Post Titlelabel>
                input type="text"
                  className="form-control"
                  value={this.state.title}
                  onChange={this.handleChange1} />
            div>

            div className="form-group">
                label name="post_content">Post Contentlabel>
                textarea className="form-control"
                  onChange={this.handleChange2} value={this.state.content}>textarea>  
            div>

            div className="form-group">
                button className="btn btn-primary">Updatebutton>
            div>
        form>
    div>
    )
  }
}
export default UpdatePost;

4. 创建主视图文件

resources/views/welcome.blade.php

DOCTYPE html>
html>
    head>
        meta charset="utf-8">
        meta http-equiv="X-UA-Compatible" content="IE=edge">
        meta name="viewport" content="width=device-width, initial-scale=1">
        title>Laravel 5.5 ReactJS CRUD Exampletitle>
        link href="{{asset('css/app.css')}}" rel="stylesheet" type="text/css">
    head>
    body>
        div id="crud-app">div>
        script src="{{asset('js/app.js')}}" >script>
    body>
html>

为了避免Laravel CSRF报错 我们在视图文件head加入

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

script>
window.Laravel = ?php echo json_encode([
    'csrfToken' => csrf_token(),
]); ?>
script>

完整视图resources/views/welcome.blade.php

DOCTYPE html>
html>
    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>Laravel 5.5 ReactJS CRUD Exampletitle>
        link href="{{asset('css/app.css')}}" rel="stylesheet" type="text/css">
        script>
        window.Laravel = ?php echo json_encode([
            'csrfToken' => csrf_token(),
        ]); ?>
        script>
    head>
    body>
        div id="crud-app">div>
        script src="{{asset('js/app.js')}}" >script>
    body>
html>

5. 编译&运行

编译

npm run dev

artisan运行项目

php artisan serve

访问 http://localhost:8000 即可

效果图

主要参考资料 Laravel 5.5 ReactJS Tutorial

本教程翻译于 Laravel 5 - Simple CRUD Application Using ReactJS

github地址 https://github.com/pandoraxm/laravel-react-curd

原文链接 https://www.bear777.com/blog/laravel5-5-react-crud

暂无回复。
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册
Top