라라벨버전

php버전 

 8.x

7.3 이상 

 7.x

 7.25 이상

 6x

 7.2.0 이상

 5.6 ~ 5.8

 7.1.3 이상

 5.5

 7.0.0 이상



    Asset     Size   Chunks             Chunk Names

/js/app.js  596 KiB  /js/app  [emitted]  /js/app


ERROR in ./resources/css/app.css

Module build failed (from ./node_modules/css-loader/index.js):

ModuleBuildError: Module build failed (from ./node_modules/postcss-loader/src/index.js):

TypeError: getProcessedPlugins is not a function

    at /Users/wonhochoi/blog/node_modules/tailwindcss/lib/processTailwindFeatures.js:71:83

    at LazyResult.run (/Users/wonhochoi/blog/node_modules/postcss-loader/node_modules/postcss/lib/lazy-result.js:288:14)

    at LazyResult.asyncTick (/Users/wonhochoi/blog/node_modules/postcss-loader/node_modules/postcss/lib/lazy-result.js:212:26)

    at LazyResult.asyncTick (/Users/wonhochoi/blog/node_modules/postcss-loader/node_modules/postcss/lib/lazy-result.js:225:14)

    at /Users/wonhochoi/blog/node_modules/postcss-loader/node_modules/postcss/lib/lazy-result.js:254:14

    at new Promise (<anonymous>)

    at LazyResult.async (/Users/wonhochoi/blog/node_modules/postcss-loader/node_modules/postcss/lib/lazy-result.js:250:23)

    at LazyResult.then (/Users/wonhochoi/blog/node_modules/postcss-loader/node_modules/postcss/lib/lazy-result.js:131:17)

    at Promise.resolve.then.then (/Users/wonhochoi/blog/node_modules/postcss-loader/src/index.js:142:8)

    at process._tickCallback (internal/process/next_tick.js:68:7)

    at runLoaders (/Users/wonhochoi/blog/node_modules/webpack/lib/NormalModule.js:316:20)

    at /Users/wonhochoi/blog/node_modules/loader-runner/lib/LoaderRunner.js:367:11

    at /Users/wonhochoi/blog/node_modules/loader-runner/lib/LoaderRunner.js:233:18

    at context.callback (/Users/wonhochoi/blog/node_modules/loader-runner/lib/LoaderRunner.js:111:13)

    at Promise.resolve.then.then.catch (/Users/wonhochoi/blog/node_modules/postcss-loader/src/index.js:208:9)

    at process._tickCallback (internal/process/next_tick.js:68:7)

 @ ./resources/css/app.css


ERROR in ./resources/css/app.css (./node_modules/css-loader??ref--5-2!./node_modules/postcss-loader/src??postcss0!./resources/css/app.css)

Module build failed (from ./node_modules/postcss-loader/src/index.js):

TypeError: Object.entries(...).flatMap is not a function

    at flattenColorPalette (/Users/wonhochoi/blog/node_modules/tailwindcss/lib/util/flattenColorPalette.js:8:83)

    at /Users/wonhochoi/blog/node_modules/tailwindcss/lib/plugins/divideColor.js:27:53

    at plugins.forEach.plugin (/Users/wonhochoi/blog/node_modules/tailwindcss/lib/util/processPlugins.js:69:5)

    at Array.forEach (<anonymous>)

    at _default (/Users/wonhochoi/blog/node_modules/tailwindcss/lib/util/processPlugins.js:63:11)

    at /Users/wonhochoi/blog/node_modules/tailwindcss/lib/processTailwindFeatures.js:60:54

    at LazyResult.run (/Users/wonhochoi/blog/node_modules/postcss-loader/node_modules/postcss/lib/lazy-result.js:288:14)

    at LazyResult.asyncTick (/Users/wonhochoi/blog/node_modules/postcss-loader/node_modules/postcss/lib/lazy-result.js:212:26)

    at LazyResult.asyncTick (/Users/wonhochoi/blog/node_modules/postcss-loader/node_modules/postcss/lib/lazy-result.js:225:14)

    at /Users/wonhochoi/blog/node_modules/postcss-loader/node_modules/postcss/lib/lazy-result.js:254:14

    at new Promise (<anonymous>)

    at LazyResult.async (/Users/wonhochoi/blog/node_modules/postcss-loader/node_modules/postcss/lib/lazy-result.js:250:23)

    at LazyResult.then (/Users/wonhochoi/blog/node_modules/postcss-loader/node_modules/postcss/lib/lazy-result.js:131:17)

    at Promise.resolve.then.then (/Users/wonhochoi/blog/node_modules/postcss-loader/src/index.js:142:8)

 @ ./resources/css/app.css 2:14-142

npm ERR! code ELIFECYCLE

npm ERR! errno 2

npm ERR! @ development: `cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --config=node_modules/laravel-mix/setup/webpack.config.js`

npm ERR! Exit status 2

npm ERR! 

npm ERR! Failed at the @ development script.

npm ERR! This is probably not a problem with npm. There is likely additional logging output above.


npm ERR! A complete log of this run can be found in:

npm ERR!     /Users/wonhochoi/.npm/_logs/2020-11-30T19_29_06_154Z-debug.log

npm ERR! code ELIFECYCLE

npm ERR! errno 2

npm ERR! @ dev: `npm run development`

npm ERR! Exit status 2

npm ERR! 

npm ERR! Failed at the @ dev script.

npm ERR! This is probably not a problem with npm. There is likely additional logging output above.


npm ERR! A complete log of this run can be found in:

npm ERR!     /Users/wonhochoi/.npm/_logs/2020-11-30T19_29_06_176Z-debug.log




여기서 자꾸 에러가 되어서 컴파일에러가 발생했다.

node 버전이 v10.15.3


node  버전을 업그레이드하여 해결하였다. v14.15.1



       Asset      Size   Chunks             Chunk Names

/css/app.css  3.74 MiB  /js/app  [emitted]  /js/app

  /js/app.js   594 KiB  /js/app  [emitted]  /js/app





그래도 안된다면 PostCSS 7 호환성 빌드 참고하자

https://tailwindcss.com/docs/installation



package.json

{
"private": true,
"scripts": {
"dev": "npm run development",
"development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --config=node_modules/laravel-mix/setup/webpack.config.js",
"watch": "npm run development -- --watch",
"watch-poll": "npm run watch -- --watch-poll",
"hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --disable-host-check --config=node_modules/laravel-mix/setup/webpack.config.js",
"prod": "npm run production",
"production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --config=node_modules/laravel-mix/setup/webpack.config.js"
},
"devDependencies": {
"axios": "^0.19",
"cross-env": "^7.0",
"laravel-mix": "^6.0.0-beta.14",
"lodash": "^4.17.19",
"postcss": "^8.2.1",
"resolve-url-loader": "^3.1.0",
"vue-template-compiler": "^2.6.12"
},
"dependencies": {
"autoprefixer": "^9.8.6",
"tailwindcss": "npm:@tailwindcss/postcss7-compat@^2.0.1"
}
}




1. 네이버 개발자 센터에서 애플리케이션 등록으로 간다.

https://developers.naver.com/main/









1. 공공데이터포털에 회원가입을 하고 로그인을 해준다.

오픈API 로 이동한다.



2. 활용신청을 클릭한다.


3. 개발신청을 작성한다.


4. 신청완료


5. 활용을 선택한다.


6. 실행을 누른다.


7. 미리보기를 누르면 이렇게 나온다.

한시간 정도 지나야지 사용가능한 것 같다.

8. xml데이터를 json데이터로 변경시켜준다. 


사용할때 인증키를 넣어줘야한다.

public function index()
{
$popularMovies = Http::get('http://openapi.airkorea.or.kr/openapi/services/rest/ArpltnInforInqireSvc/서비스키');

$xml = simplexml_load_string($popularMovies);
$json = json_encode($xml);

$array = json_decode($json,TRUE);

// dd($array['body']['items']);
dd($array);
return view('index');

}


9. 이렇게 api 데이터를 활용해서 사용할 수 있다.


1. 영화 진흥 위원회 회원가입하기 

http://www.kobis.or.kr/kobisopenapi/homepg/main/main.do


2.key 발급받기 위해 어떤 정보의 제공을 받을 것인지 선택해야한다.

일별 박스오피스를 받아보자

아래에 요청 URL을 복사한다.



3.  key 를 발급받자



발급키가 보일 것이다.


4. 사용방법은 JSON을 사용한다.


http://www.kobis.or.kr/kobisopenapi/webservice/rest/boxoffice/searchDailyBoxOfficeList.json?key=430156241533f1d058c603178cc3ca0e&targetDt=20120101

 

5. config/services.php

'boxoffice' => [
'token' => env('KOBISDB_BOX_OFFICE_TOKEN'),
],



6. .env  (영화 진흥위원회 에서 발급받은 키값을 입력한다)

KOBISDB_BOX_OFFICE_TOKEN = 발급받은 키값입력


7. MovuesController.php 

public function index()
{
//박스오피스 가져오기
$popularMovies = Http::withToken(config('services.boxoffice.token'))
->get('http://www.kobis.or.kr/kobisopenapi/webservice/rest/boxoffice/searchDailyBoxOfficeList.json?key=430156241533f1d058c603178cc3ca0e&targetDt=20200101'.'&api_key='.config('services.boxoffice.token'))
->json()['boxOfficeResult']['dailyBoxOfficeList'];

dd($popularMovies);
return view('index');
}


8. 브라우저 확인


9. 응답구조에 영화이미지가 없다.. 아쉽다.....


1.  스캐폴딩 설치

1
composer require laravel/ui
cs


2. ui명령정보 확인

1
php artisan ui --help
cs


3. 다음 명령어로 ui 설치할 수  있음


부트스트랩 

1
php artisan ui bootstrap --auth
cs


VUE

1
php artisan ui vue --auth
cs


React

1
php artisan ui react --auth
cs


4. npm패키지 설치

1
npm install
cs


5. 컴파일

1
npm run dev
cs


1. 라라벨 설치

1
composer create-project --prefer-dist laravel/laravel turbo
cs


2. livewire 패키지 설치

1
composer require livewire/livewire
cs


3. 모델, 마이그레이션, 시더, 팩토리생성

1
php artisan make:model -msf Product
cs


-m | 마이그레이션을 만듭니다

-s | 시더를 만듭니다

-f | 공장을 만듭니다

4. 마이그레이션 파일 스키마 작성 (2020_04_17_091934_create_products_table)

1
2
3
4
5
6
7
8
9
10
11
12
    public function up()
    {
        Schema::create('products', function (Blueprint $table) {
            $table->id();
 
            $table->string('name');
            $table->string('description');
            $table->float('price');
 
            $table->timestamps();
        });
    }
cs


5. factories/ProductFactory.php 작성

<?php

/** @var \Illuminate\Database\Eloquent\Factory $factory */

use App\Product;
use Faker\Generator as Faker;

$factory->define(Product::class, function (Faker $faker) {
return [
'name' => $faker->word,
'description' => $faker->text(180),
'price' => $faker->numberBetween(50, 100)
];
});


6. seeds/ProductSeeder.php 작성 

<?php

use App\Product;
use Illuminate\Database\Seeder;

class ProductSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
factory(Product::class, 50)->create();
}
}


7. seeds/DatabaseSeeder.php 작성

<?php

use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*
* @return void
*/
public function run()
{
$this->call(ProductSeeder::class);
}
}


8. 마이그레이션 및 시더생성

1
php artisan migrate:fresh --seed
cs



9. tailwindcss 설치

1
2
3
4
5
6
7
8
9
10
11
-테일윈드css
npm install tailwindcss
 
-컨피그파일 생성(tailwind.config.js)
npx tailwind init 
 
-패키지설치
npm install 
 
-빌드하기
npm run dev
cs


10. resources/sass/app/scss

1
2
3
@tailwind base;
@tailwind components;
@tailwind utilities;
cs


11. webpack.mix.js 

const mix = require('laravel-mix');

mix.js('resources/js/app.js', 'public/js');

const tailwindcss = require('tailwindcss')

mix.sass('resources/sass/app.scss', 'public/css')
.options({
processCssUrls: false,
postCss: [ tailwindcss('tailwind.config.js') ],
})


12. 다시 빌드하기

npm run dev


13. 레이아웃만들기 resources/views/layouts/app.blade.php

Livewire는 app.blade.php라는 레이아웃을 자동으로 검색하여 컨텐츠 섹션을 정의하는 기본적으로 컴포넌트를 렌더링합니다.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Laravel</title>
<link href="{{ asset('css/app.css') }}" rel="stylesheet">

@livewireStyles
</head>
<body>
<div class="mx-auto">
@yield('content')
</div>

@livewireScripts
<script src="{{ asset('js/app.js') }}"></script>
</body>
</html>



14. resources/views/layouts/header.blade.php 파일생성

<nav class="flex items-center justify-between flex-wrap p-6 mb-6 shadow">
<div class="block lg:hidden">
<button class="flex items-center px-3 py-2 border rounded text-teal-200 border-teal-400 hover:text-white hover:border-white">
<svg class="fill-current h-3 w-3" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><title>Menu</title><path d="M0 3h20v2H0V3zm0 6h20v2H0V9zm0 6h20v2H0v-2z"/></svg>
</button>
</div>
<div class="w-full block flex-grow lg:flex lg:items-center lg:w-auto">
<div class="text-sm lg:flex-grow">
<a href="/" class="block mt-4 lg:inline-block lg:mt-0 mr-4">
Home
</a>
<a href="/products" class="block mt-4 lg:inline-block lg:mt-0 mr-4">
Products
</a>
</div>
</div>
</nav>


15. app.blade.php 파일에 header파일 넣기


16. livewire 구성요소를 추가


php artisan make:livewire home


두가지 파일이 생성됨

CLASS: app/Http/Livewire/Home.php

VIEW:  resources/views/livewire/home.blade.php


17. resources/views/livewire/home.blade.php

<div>
<p class="text-center p-6">
<span class="text-4xl">Welcome! 3899</span>
</p>
</div>


18. 라우트 등록

<?php

use Illuminate\Support\Facades\Route;

Route::livewire('/', 'home')->name('home');


php artisna route:list


19. Products 구성요소 추가

php artisan make:livewire Products


CLASS: app/Http/Livewire/Products.php

VIEW:  resources/views/livewire/products.blade.php


20. resources/views/livewire/products.blade.php

<div>
<p class="text-center p-6">
<span class="text-4xl">Products Page</span>
</p>
</div>


21. web.php 라우터등록

<?php

use Illuminate\Support\Facades\Route;

Route::livewire('/', 'home')->name('home');
Route::livewire('products', 'products')->name('products');


22. 브라우저 확인을 하면 페이지 이동시 새로고침 되는 것을 볼 수 있다.

이것을 spa처럼 만들어 줄 수 있다. 


23. SPA활성화

npm install --save turbolinks


24. resources/js.app.js

require('./bootstrap');

var Turbolinks = require("turbolinks")
Turbolinks.start()


25. css,js 빌드하기

npm run dev


26. 브라우저 확인  새로고침이 없어졌다. (나도 아직 왜 이렇게 작동하는건지 모르겠음)

27. 이제 products 목록을 불러오자

app/Http/Livewire/Products.php

<?php

namespace App\Http\Livewire;

use App\Product;
use Livewire\Component;

class Products extends Component
{
public function render()
{
$products = Product::latest()->get();
return view('livewire.products', compact('products'));
}
}


28. livewire/product.blade.php

<div>

<p class="text-center p-6">
<span class="text-4xl">Products Page</span>
</p>
<hr>

<div class="flex justify-center bg-gray-200">
<table class="table-auto">
<thead>
<tr>
<th class="px-4 py-2">ID</th>
<th class="px-4 py-2">NAME</th>
<th class="px-4 py-2">PRICE</th>
</tr>
</thead>
<tbody>
@foreach($products as $product)
<tr>
<td class="border px-4 py-2">{{ $product->id }}</td>
<td class="border px-4 py-2">{{ $product->name }}</td>
<td class="border px-4 py-2">{{ $product->price }}</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>


29. 브라우저 확인 (DB가 잘 불러와 진다.)


30. resources/views/layouts/pagination.blade.php 파일을 만들자

@if ($paginator->lastPage() > 1)
<ul >
<li class="{{ ($paginator->currentPage() == 1) ? ' disabled' : '' }} inline border-t border-b border-l border-brand-light px-3 py-2 no-underline">
<a href="{{ $paginator->url(1) }}"><<</a>
</li>
@for ($i = 1; $i <= $paginator->lastPage(); $i++)
<li class="{{ ($paginator->currentPage() == $i) ? ' text-green-500' : '' }} inline border-t border-b border-l border-brand-light px-3 py-2 no-underline">
<a href="{{ $paginator->url($i) }}">{{ $i }}</a>
</li>
@endfor
<li class="{{ ($paginator->currentPage() == $paginator->lastPage()) ? ' disabled' : '' }} inline border-t border-b border-r border-l border-brand-light px-3 py-2 no-underline">
<a href="{{ $paginator->url($paginator->currentPage()+1) }}" >>></a>
</li>
</ul>
@endif


31. views/livewire/products.blade.php 

테이블 밑에 페이지네이션 불러오는 소스를 삽입한다.

<br>
<div class="w-full flex justify-center pb-6">
{{ $products->links('layouts.pagination') }}
</div>


32. app/Http/Livewire/Products.php 수정

<?php

namespace App\Http\Livewire;

use App\Product;
use Illuminate\View\View;
use Livewire\Component;
use Livewire\WithPagination;

class Products extends Component
{
use WithPagination;
public $search;

public function render(): View
{
return view('livewire.products', [
'products' => $this->search === null ?
Product::paginate(5) :
Product::where('name', 'like', '%' . $this->search . '%')->paginate(5)
]);
}
}




33. 테이블 상단에 검색창을 달아준다.

<br>
<div class="w-full flex justify-center">
<input wire:model="search" type="text" class="shadow appearance-none border rounded w-1/2 py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" placeholder="Search products by name...">
</div>
<br>


34. 파일 검색이 실시간으로 된다.


'라라벨 > livewire_study' 카테고리의 다른 글

숫자카운터 db비동기  (0) 2020.04.12
라라벨 와이어 동작방법 버튼 카운터  (0) 2020.04.11
데이터바인딩  (0) 2020.04.11
속성사용하기  (0) 2020.04.11
변수값 넘기기  (0) 2020.04.11

1. 라라벨 프로젝트 설치

composer create-project laravel/laravel inertia --prefer-dist 6.0


2. 데이터베이스 설정 ( .env)


3. 마이그레이션 실행

php artisan migrate


4. 이터니아 라라벨 어댑터 설치

https://inertiajs.com/server-side-setup

1
composer require inertiajs/inertia-laravel
cs


5. 루트 템플릿 설정 resources/views/app.blade.php

1
2
3
4
5
6
7
8
9
10
11
12
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
    <link href="{{ mix('/css/app.css') }}" rel="stylesheet" />
    <script src="{{ mix('/js/app.js') }}" defer></script>
  </head>
  <body>
    @inertia
  </body>
</html>
cs


6. npm과 vue 어댑터 설치

https://inertiajs.com/client-side-setup

1
npm install @inertiajs/inertia @inertiajs/inertia-vue
cs


7. webpack.mix.js

const mix = require('laravel-mix');

mix.js('resources/js/app.js', 'public/js')
.sass('resources/sass/app.scss', 'public/css')
.webpackConfig({
output: { chunkFilename: 'js/[name].js?id=[chunkhash]' },
resolve: {
alias: {
vue$: 'vue/dist/vue.runtime.esm.js',
'@': path.resolve('resources/js'),
},
},
});


8. 동적가져오기 활성화

1
npm install @babel/plugin-syntax-dynamic-import
cs


프로젝트명/.babelrc 파일생성 후 다음 소스 작성

1
2
3
{
  "plugins": ["@babel/plugin-syntax-dynamic-import"]
}
cs


9. resources/js/app.js 아래처럼 교체

https://inertiajs.com/client-side-setup

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import { InertiaApp } from '@inertiajs/inertia-vue'
import Vue from 'vue'
 
Vue.use(InertiaApp)
 
const app = document.getElementById('app')
 
new Vue({
  render: h => h(InertiaApp, {
    props: {
      initialPage: JSON.parse(app.dataset.page),
      resolveComponent: name => import(`./Pages/${name}`).then(module => module.default),
    },
  }),
}).$mount(app)
 
cs


10. npm 패키지 설치

npm install


11. 빌드

npm run watch


12. 에러시 

npm install --save vue


13. resources/js/Pages/Welcome.vue  생성


14. web.php 설정

1
2
3
4
5
6
7
8
9
<?php
 
use Inertia\Inertia;
 
Route::get('/', function () {
    return Inertia::render('Welcome',[
       'foo' => 'bar'
    ]);
});
cs


15. resources/js/Pages/Welcome.vue 변수 값 들어오는지 확인

1
2
3
4
5
6
7
8
9
10
11
<template>
  <div>
      Welcome Page{{ foo }}
  </div>
</template>
 
<script>
export default {
     props: ['foo']
}
</script>
cs


16. 브라우저확인


17. main틀을 만들자

resources/js/Shared/Layout.vue

<template>
<main>
<header>
<inertia-link href="/">Home</inertia-link>
<inertia-link href="/about">About</inertia-link>
<inertia-link href="/contact">Contact</inertia-link>

</header>

<article>
<slot/>
</article>

</main>
</template>

<script>
export default {

}
</script>

<style>

</style>


18. welcome.vue    

<layout> 감싸자

<template>
<layout>

<div>
Welcome Page{{ foo }}
</div>
</layout>
</template>

<script>
import Layout from '@/Shared/Layout'

export default {
props: ['foo'],

components:{
Layout
},
}
</script>




19. 부트스트랩 디자인 적용

1
composer require laravel/ui "^1.2"
cs


1
php artisan ui bootstrap --auth
cs


npm install


npm run watch


20. Layout.vue

<template>
<main>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<a class="navbar-brand" href="#">Navbar</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNavAltMarkup">
<div class="navbar-nav">
<inertia-link href="/" class="nav-item nav-link">Home</inertia-link>
<inertia-link href="/about" class="nav-item nav-link">About</inertia-link>
<inertia-link href="/contact" class="nav-item nav-link">Contact</inertia-link>
</div>
</div>
</nav>

<article>
<slot />
</article>
</main>
</template>




21. 팅커콘솔에서 다음과 같이 입력

factory('App\User',30)->create()

그럼 users테이블에 30row 가짜 데이터가 입력되었을 것이다.


22. UsersControllers -r 을 만들어준다.

php artisan make:controller UsersController -r

public function index()
{
$users = User::all();

return Inertia::render('Users/Index',[
'users' => $users,
]);
}


23. web.php 파일에서 라우터를 정의해준다.

Route::get('/users', 'UsersController@index')->name('users.index');


24. resources/js/Pages/Users/Index.vue 생성

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<template>
    <layout>
 
        <div>
            users Page
        </div>
 
    </layout>
</template>
 
<script>
import Layout from '@/Shared/Layout'
 
export default {
     props: ['users'],
 
     components:{
         Layout
     },
}
</script>
 
cs


25.  브라우저 확인


26. Index.vue 디자인 수정

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<template>
  <layout>
    <div class="container">
      <div v-if="successMessage" class="alert alert-success mt-4">
        {{ successMessage }}
      </div>
 
      <div class="my-5">
        <a href="/users/create" class="btn btn-primary">Create User</a>
      </div>
      <table class="table table-striped">
        <thead>
          <tr>
            <th scope="col">Name</th>
            <th scope="col">Email</th>
            <th scope="col">Actions</th>
          </tr>
        </thead>
        <tbody>
          <tr v-for="user in users" :key="user.id">
            <td>{{ user.name }}</td>
            <td>{{ user.email }}</td>
            <td>
              <inertia-link :href="`/users/${user.id}/edit`">Edit</inertia-link>
            </td>
          </tr>
        </tbody>
      </table>
    </div>
  </layout>
</template>
 
<script>
import Layout from '@/Shared/Layout'
export default {
 props: ['users''successMessage'],
  components: {
    Layout,
  },
}
</script>
 
cs



27. web.php 파일에 CRUD에 대한 라우터를 모두 정의한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 유저목록
Route::get('/users', 'UsersController@index')->name('users.index');
 
// 유저생성 페이지
Route::get('/users/create', 'UsersController@create')->name('users.create');
 
//유저 생성 로직 처리
Route::post('/users', 'UsersController@store')->name('users.store');
 
//유저 수정 페이지
Route::get('/users/{user}/edit', 'UsersController@edit')->name('users.edit');
 
// 유저 수정 로직 처리
Route::patch('/users/{user}', 'UsersController@update')->name('users.update');
 
// 유저 삭제
Route::delete('/users/{user}', 'UsersController@destroy')->name('users.destroy');
cs


28. UsersController.php

public function create()
{
return Inertia::render('Users/Create');
}


29. resources/js/Pages/Users/Create.vue 생성

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<template>
  <layout>
    <div class="container">
      <div class="col-md-6">
 
        <form action="/users" method="POST" class="my-5" @submit.prevent="createUser">
          <div class="form-group">
            <label for="name">Name</label>
            <input type="text" class="form-control" id="name" placeholder="Name" v-model="form.name">
          </div>
          <div class="form-group">
            <label for="email">Email</label>
            <input type="email" class="form-control" id="email" placeholder="Email" v-model="form.email">
          </div>
          <div class="form-group">
            <label for="password">Password</label>
            <input type="password" class="form-control" id="password" placeholder="Password" v-model="form.password">
          </div>
          <button type="submit" class="btn btn-primary">Create User</button>
        </form>
      </div>
    </div>
  </layout>
</template>
 
<script>
import Layout from '@/Shared/Layout'
export default {
 props: ['errors'],
  components: {
    Layout,
  },
  data() {
    return {
      form: {
        name'',
        email: '',
        password: '',
      }
    }
  },
  methods: {
    createUser() {
      this.$inertia.post('/users', this.form)
        .then(() => {
          // code
        })
    }
  }
}
</script>
 
cs



30. UsersController.php

public function store(Request $request)
{
$request->validate([
'name' => 'required',
'email' => 'required|email|unique:users',
'password' => 'required|min:5'
]);

User::create([
'name' => $request->name,
'email' => $request->email,
'password' => bcrypt($request->password)
]);

return redirect()->route('users.index')->with('successMessage','등록이 완료 되었습니다.');
}


31. 글을 작성해본다.


32. Layout.vue 하단에 아래와 같이 작성한다.

<script>
export default{
inject: ['page'],
}
</script>


33. Create.vue

props: ['errors'],


34. app/Providers/AppServiceProvider.php  다음과 같이 작성하자(오류 통신공유)

public function register()
{
Inertia::share('app.name', config('app.name'));

Inertia::share('errors', function () {
return session()->get('errors') ? session()->get('errors')->getBag('default')->getMessages() : (object) [];
});

Inertia::share('successMessage', function () {
return session()->get('successMessage') ? session()->get('successMessage') : null;
});
}


35. Create.vue 오류메시지 삽입

<div v-if="Object.keys(errors).length > 0" class="alert alert-danger mt-4">
{{ errors[Object.keys(errors)[0]][0] }}
</div>



36. 성공메시지를 넣어보자

app/Providers/AppServiceProvider.php  다음과 같이 작성하자(오류 통신공유)

//성공 메시지
Inertia::share('successMessage', function () {
return session()->get('successMessage') ? session()->get('successMessage') : null;
});


37. Index.vue

<div v-if="successMessage" class="alert alert-success mt-4">
{{ successMessage }}
</div>


props: ['users', 'successMessage'],



38. UsersController.php

public function edit(User $user)
{
return Inertia::render('Users/Edit',[
'user' => $user,
]);
}


39. resources/js/Pages/Users/Edit.vue 작성

<template>
<layout>
<div class="container">
<div class="col-md-6">
<div v-if="Object.keys(errors).length > 0" class="alert alert-danger mt-4">
{{ errors[Object.keys(errors)[0]][0] }}
</div>
<form action="#" method="PATCH" class="my-5" @submit.prevent="updateUser">
<div class="form-group">
<label for="name">Name</label>
<input type="text" class="form-control" id="name" placeholder="Name" v-model="form.name">
</div>
<div class="form-group">
<label for="email">Email</label>
<input type="email" class="form-control" id="email" placeholder="Email" v-model="form.email">
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" class="form-control" id="password" placeholder="Password" v-model="form.password">
</div>
<button type="submit" class="d-flex btn btn-primary" :disabled="loading">
<span>Update User</span>
</button>
</form>

<button class="btn btn-danger" @click="deleteUser">Delete User</button>
</div>
</div>
</layout>
</template>

<script>
import Layout from '@/Shared/Layout'
export default {
components: {
Layout,
},
props: ['user', 'errors'],
data() {
return {
loading: false,
form: {
name: this.user.name,
email: this.user.email,
}
}
},
methods: {
updateUser() {
this.loading = true;
this.$inertia.patch(`/users/${this.user.id}`, this.form)
.then(() => {
this.loading = false;
})
},
deleteUser() {
if (confirm('Are you sure you want to delete this contact?')) {
this.$inertia.delete(`/users/${this.user.id}`)
.then(() => {
})
}
}
}
}
</script>



40. UsersController.php

public function update(Request $request, User $user)
{
$request->validate([
'name' => 'required',
'email' => 'required|unique:users,email,'.$user->id, //다른 사람 이메일인지 확인
]);

$user->update([
'name' => $request->name,
'email' => $request->email
]);

return redirect()->route('users.index')->with('successMessage','업데이트 완료!');
}


'라라벨 > Inertia.js' 카테고리의 다른 글

Inertia.js란  (0) 2020.04.15
Laravel + Inertia.js 예제  (0) 2020.04.15

+ Recent posts