knaka Tech-Blog

AI, IoT, DIYエレクトロニクス, データサイエンスについて投稿予定です。

Vue.js (Vue CLI 3) と、firebaseで SPA開発、アプリ実装編 フォーム登録など SPA開発(5) #Vue.js #web #firebase #SPA

index:

概要:

前のSPA(SinglePageApplication) 関連で、Vue CLI 3 +firebase
の実装編となります。

・クロスドメイン構成で、バックエンドは別クラウドとなります。

環境

Vue-CLI 3.6.6
Vue.js
vue-router
firebase

参考の設定

github.com

画面レイアウト

・index
f:id:knaka0209:20190428131102p:plain

・new
f:id:knaka0209:20190428131118p:plain

コードなど

・firebase のプロジェクトを作成

・datbase
Cloud firestoreの、コレクションを追加しておきます。


・App.vue
https://github.com/kuc-arc-f/vue_2_ver2/blob/master/src/App.vue

<template>
  <div id="app">
    <navbar />
    <router-view/>
  </div>
</template>

<script>
import navbar from './components/Layouts/Navbar'

export default {
  name: 'app',
  components: {
    navbar
  }
}
</script>
<style>
</style>

・main.js
https://github.com/kuc-arc-f/vue_2_ver2/blob/master/src/main.js

・firebase の接続設定を追加してます。

// Initialize Firebase
var config = {
  apiKey: "YOUR-PROJECT",
  authDomain: "YOUR-PROJECT.firebaseapp.com",
  databaseURL: "https://YOUR-PROJECT.firebaseio.com",
  projectId: "YOUR-PROJECT",
  storageBucket: "YOUR-PROJECT.appspot.com",
  messagingSenderId: "123"
}
firebase.initializeApp(config)

・router/index.js
https://github.com/kuc-arc-f/vue_2_ver2/blob/master/src/router/index.js


ルーティングの設定など

Vue.use(Router)
//
export default new Router({
  mode: 'history',
  routes: [
    { path: '/', component: home },
    { path: '/about', component: about },
    /* tasks */
    { path: '/tasks/new', component: tasksNew },
    { path: '/tasks', component: tasksIndex },
    { path: '/tasks/show/:id', component: tasksShow },
    { path: '/tasks/edit/:id', component: tasksEdit },
  ]
})

Vueコンポーネント

・tasks/new
https://github.com/kuc-arc-f/vue_2_ver2/blob/master/src/components/Tasks/new.vue

<script>
import firebase from 'firebase'
var tableName = 'tasks'
export default {
    created() {
        this.database = firebase.firestore()
    },
    data() {
        return {
            title:'',
            content:''
        }
    },
    methods: {
        createTask: function() {
            console.log('#create')
            if (this.newTodoName == "") { return; }        
            this.database.collection(tableName).add({
                title: this.title,
                content: this.content
            }).then(function(docRef) {
                console.log("Document written with ID: ", docRef.id)
                window.location.href='/tasks'
            }).catch(function(error) {
                console.log("Error adding document: ", error)
            })
            this.newTodoName = ""
        },
    }
}
</script>

・tasks/index
https://github.com/kuc-arc-f/vue_2_ver2/blob/master/src/components/Tasks/Index.vue

<script>
import firebase from 'firebase'
import {Mixin} from '../../mixin'
//
export default {
  mixins:[Mixin],
  created () {
    this.getTasks()
    /* console.log(this.sysConst.STORAGE_KEY_tasksData ) */
  },
  data () {
    return {
      tasks: []
    }
  },
  methods: {
    getTasks () {
        var items = []
        var self = this
        this.database = firebase.firestore()
        var dbRef = this.database.collection('tasks')
        dbRef = dbRef.orderBy("title", "desc")
        dbRef.get().then(function(querySnapshot) {
            querySnapshot.forEach(function(doc) {
                /* console.log(doc.id, " => ", doc.data()) */
                var item = doc.data()
                items.push({
                    id : doc.id,
                    title : item.title,
                    content : item.content
                })            
            })
            self.tasks = items
        })
    }
  }
}
</script>

・tasks/show
https://github.com/kuc-arc-f/vue_2_ver2/blob/master/src/components/Tasks/show.vue


・tasks/edit
https://github.com/kuc-arc-f/vue_2_ver2/blob/master/src/components/Tasks/edit.vue

まとめ

・比較的シンプルな構成ですが、
 バックエンドは firebase を使用しているので、
 フロント側の、主体の作業になりますね。

Vue.js 初級編、V-ディレクティブ #Vue.js #web

index:

概要:

前の Vue.js 関連で、初級編的な内容となります。
V-ディレクティブ の説明などです。

環境

Vue.js

参考のコード

github.com

v-text

テキストをレンダリングする(v-text)
https://github.com/kuc-arc-f/vue_sample_1/blob/master/v-text.html

	<div id="app-101">
	  <div v-text="message"></div>
	  <div>{{ message }}</div>
	</div>
	<script>
	var app101 = new Vue({
	  el: '#app-101',
	  data: { message: 'Hello!' }
	})
	</script>

v-html

HTMLをレンダリングする(v-html
https://github.com/kuc-arc-f/vue_sample_1/blob/master/v-html.html

	<div id="app-102">
		<div v-text="message"></div>
		<div v-html="message"></div>
	</div>
	<script>
	var app102 = new Vue({
		el: '#app-102',
		data: { message: '<b>Hello!</b>' }
	})
	</script>

v-show

条件により表示を制御する(v-show)
https://github.com/kuc-arc-f/vue_sample_1/blob/master/v-show.html

	<div id="app-103">
		<input type="checkbox" @click="change" checked>
		<span v-show="seen">Hello!</span>
	</div>
<script>
var app103 = new Vue({
  el: '#app-103',
  data: { seen: true },
  methods: {
    change: function(e) {
      this.seen = e.target.checked
    }
  }
})
</script>

v-if

条件により表示を制御する(v-if)
https://github.com/kuc-arc-f/vue_sample_1/blob/master/v-if.html

	<div id="app-104">
		<input type="checkbox" @click="change" checked>
		<span v-if="seen">Hello!</span>
	</div>
<script>
var app104 = new Vue({
  el: '#app-104',
  data: { seen: true },
  methods: {
    change: function(e) {
      this.seen = e.target.checked
    }
  }
})
</script>

v-else

条件により表示を制御する(v-else)
https://github.com/kuc-arc-f/vue_sample_1/blob/master/v-else.html

	<div id="app-105">
		<input type="checkbox" @click="change" checked>
		<span v-if="seen">Hello!</span>
		<span v-else>Bye!</span>
	</div>
<script>
var app105 = new Vue({
  el: '#app-105',
  data: { seen: true },
  methods: {
    change: function(e) {
      this.seen = e.target.checked
    }
  }
})
</script>

v-else-if

条件により表示を制御する(v-else-if)
https://github.com/kuc-arc-f/vue_sample_1/blob/master/v-else-if.html

	<!-- -->
	<div id="app-106">
		<input type="radio" name="app106-type" onclick="app106.type='A'" checked>
		<input type="radio" name="app106-type" onclick="app106.type='B'">
		<input type="radio" name="app106-type" onclick="app106.type='C'">
		<span v-if="type=='A'">Good morning.</span>
		<span v-else-if="type=='B'">Hello!</span>
		<span v-else>Bye!</span>
	</div>
<script>
var app106 = new Vue({
  el: '#app-106',
  data: { type: 'A' }
})
</script>

v-for

ループする(v-for)
https://github.com/kuc-arc-f/vue_sample_1/blob/master/v-for.html

	<!-- -->
	<div id="app-107">
		<ul>
		<li v-for="color in colorList">{{ color }}</li>
		</ul>
	</div>
<script>
var app107 = new Vue({
  el: '#app-107',
  data: { colorList: [ 'Red', 'Green', 'Blue' ] }
})
</script>

v-on

イベントを処理する(v-on, @)
https://github.com/kuc-arc-f/vue_sample_1/blob/master/v-on.html

	<!-- -->
	<div id="app-108">
		<button v-on:click="hello">Hello</button>
		<button @click="hello">Hello</button>
	</div>
<script>
var app108 = new Vue({
  el: '#app-108',
  methods: {
    hello: function() {
      alert("Hello!");
    }
  }
})
</script>

v-bind

HTMLの属性を指定する(v-bind, :)
https://github.com/kuc-arc-f/vue_sample_1/blob/master/v-bind.html

	<!-- -->
	<div id="app-109">
		<input type="button" v-bind:value="message">
		<input type="button" :value="message">
	</div>
<script>
var app109 = new Vue({
  el: '#app-109',
  data: { message: 'Hello!' }
})
</script>

v-model

入力フォームにモデルを割り当てる(v-model)
https://github.com/kuc-arc-f/vue_sample_1/blob/master/v-model.html

	<!-- -->
	<div id="app-120">
		<input v-model="message">
		<div>Message: {{ message }}</div>
	</div>
<script>
var app120 = new Vue({
  el: '#app-120',
  data: { message: 'Hello!' }
})
</script>

v-pre

テキストをそのまま出力する(v-pre)
https://github.com/kuc-arc-f/vue_sample_1/blob/master/v-pre.html

	<!-- -->
	<div id="app-121">
		<div v-pre>Message: {{ message }}</div>
		<div>Message: {{ message }}</div>
	</div>
<script>
var app121 = new Vue({
  el: '#app-121',
  data: { message: 'Hello' }
})
</script>

v-cloak

画面表示時に {{ ... }} を表示しない(v-cloak)
https://github.com/kuc-arc-f/vue_sample_1/blob/master/v-cloak.html

	<!-- -->
<style>
[v-cloak] { display: none }
</style>
	<div id="app-122">
		<button onclick="location.reload()">再表示</button>
		<div>Message: <span v-cloak>{{ message }}</span></div>
		<div>Message: <span>{{ message }}</span></div>
	</div>
<script>
window.setTimeout(function() {
  var app122 = new Vue({
    el: '#app-122',
    data: { message: 'Hello!' }
  })
}, 1000);
</script>

v-once

一度だけ表示する(v-once)
https://github.com/kuc-arc-f/vue_sample_1/blob/master/v-once.html

	<!-- -->
<div id="app-123">
  <input type="text" name="text1" v-model:value="message">
  <div>Message: <span v-once>{{ message }}</span></div>
  <div>Message: <span>{{ message }}</span></div>
</div>
<script>
var app123 = new Vue({
  el: '#app-123',
  data: { message: 'Hello' }
})
</script>

Laravel 5 + sqlite 設定編 #Laravel #sqlite #PHP

index:

概要:

前回の Laravel 5 のDB関連で、
sqlite windows版設定となります。

環境

php7.1
Laravel 5.6
sqlite

設定方法

sqlite 64bit をDLしました。
https://www.sqlite.org/download.html

sqlite-dll-win64-x64-3240000.zip

・sqlite3.dllを、下記に配置
C:\Windows\System32

・DBと、テストの表の作成
 適当なフォルダに配置します。

sqlite3 spa1.sqlite

create table temp(id, name);
.exit

・ .sqlite ファイルが作成されます。

Laravel 設定

・ config/database.php

    'default' => env('DB_CONNECTION', 'sqlite'),

・ .env

DB_CONNECTION=sqlite
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=C:\xampp71\htdocs\spa1\spa1.sqlite
DB_USERNAME=homestead
DB_PASSWORD=secret

php.exe artisan migrate
php.exe artisan tinker

・サービス起動
php.exe artisan serve

Laravel 5 + React.js で、ajax でリスト作成など #Laravel #React.js #PHP

index:

概要:
前回の Laravel 5 + React.js の関連になります。
ajaxで、DB登録機能、リスト表示など実装となります。

環境

php7.1
Laravel 5.8
React.js
react-dom
react-router-dom

参考の設定

resource など、一部のフォルダです。
github.com

実装など

事前に、mysql DB作成、接続設定を行います。
手順は、前のVue.js と同様です

・migrate
https://github.com/kuc-arc-f/spa2-ver2/blob/master/database/migrations/2019_04_20_234711_create_to_dos_table.php

model:
https://github.com/kuc-arc-f/spa2-ver2/blob/master/app/ToDo.php

・app.js
https://github.com/kuc-arc-f/spa2-ver2/blob/master/resources/js/app.js

require('./bootstrap');
import React from 'react';
import { render } from 'react-dom';
import {  BrowserRouter, Router, Link, Route, browserHistory } from 'react-router-dom';
import Main   from './components/Main';
import Create from './components/Create';
import List from './components/List';
import Edit from './components/Edit';
//
class Hello extends React.Component {
    render() {
		return (
			<BrowserRouter>
			<div>
				<ul>
					<li><Link to="/create">Create</Link></li>
					<li><Link to="/list">List</Link></li>
				</ul>
				<Route path="/create" component={Create} />
				<Route path="/list" component={List} />
				<Route path="/todos/:id/edit" component={Edit} />
			</div>
			</BrowserRouter>
		);
    }
}
render(
    <Hello />,
    document.getElementById('example')
);


・web.php
https://github.com/kuc-arc-f/spa2-ver2/blob/master/routes/web.php

Route::prefix('api')->group(function(){
     Route::resource('todos', 'ToDosController', ['only'=>['index', 'store', 'show', 'update', 'destroy']]);
});
//
Route::get('/{any?}', function () {
    return view('welcome');
})->where('any', ".*");


・コントローラ
https://github.com/kuc-arc-f/spa2-ver2/blob/master/app/Http/Controllers/ToDosController.php

参考のページ

knaka0209.hatenablog.com

Laravel 5 + React.js で、設定編 #Laravel #React.js #PHP

index:

概要:
Laravel 5 + React.js の設定編になります。

環境

php7.1
Laravel 5.8
React.js
react-dom
react-router-dom

参考の設定

resource など、一部のフォルダです。
github.com

設定など

php.exe composer.phar create-project --prefer-dist laravel/laravel spa2
cd spa2
php.exe artisan preset react
npm install
npm run dev


・起動します。
php.exe artisan serve

・react-router-dom の、追加
 package.json
https://github.com/kuc-arc-f/spa2-ver1/blob/master/package.json

"react-router-dom": "^4.1.1",

・welcome.blade.php
https://github.com/kuc-arc-f/spa2-ver1/blob/master/resources/views/welcome.blade.php


・app.js
https://github.com/kuc-arc-f/spa2-ver1/blob/master/resources/js/app.js

require('./bootstrap');
import React from 'react';
import { render } from 'react-dom';
import {  BrowserRouter, Router, Link, Route, browserHistory } from 'react-router-dom';
import Example from './components/Example';
//import Hello1 from './components/Hello1';
//import Hello2 from './components/Hello2';

// <Hello />,
render(
    <Example />,
    document.getElementById('example')
);


コンポーネント
Example.js
https://github.com/kuc-arc-f/spa2-ver1/blob/master/resources/js/components/Example.js

・ npm run watch
の実行

結果

http://localhost:8000/ を開きます。

f:id:knaka0209:20190420184911p:plain

Laravel 5.6 + Vue.js で、SPA開発(4) ページング機能 #Laravel #vue.js #SPA #PHP

index:

概要:

前回のSPA(SinglePageApplication) 構成で、Laravel 5 +vue.js
の関連となります。

ページング機能の実装になります。


環境

php7.1
Laravel 5.6
Vue.js

参考の設定

resource など、一部のフォルダです。
github.com

追加した、一覧画面

f:id:knaka0209:20190415183311p:plain

実装など

・表の作成
php.exe artisan make:migration create_books_table --create=books
php.exe artisan migrate

https://github.com/kuc-arc-f/spa1_ver3/blob/master/database/migrations/2019_04_15_073043_create_books_table.php

・モデルの作成
php.exe artisan make:model Book


・データの登録、数件登録しておきます。

api.php
https://github.com/kuc-arc-f/spa1_ver3/blob/master/routes/api.php

=> ページ内の、件数指定 の場合。

    Route::get('/books', function(Request $request) {
        return App\Book::paginate(4);
    });

・app.js
/books/ の追加。
https://github.com/kuc-arc-f/spa1_ver3/blob/master/resources/assets/js/app.js

       { path: '/books/'              , component: require('./components/Books/index.vue') },

・Vueコンポーネント
Books/Index.vue

https://github.com/kuc-arc-f/spa1_ver3/blob/master/resources/assets/js/components/Books/Index.vue

Laravel 5.6 + Vue.js で、SPA開発(3) 状態の保持 #Laravel #vue.js #SPA #PHP

index:

概要:
前回のSPA(SinglePageApplication) 構成で、Laravel 5 +vue.js
の関連となります。

複数の画面を遷移した時の、
横断的に変数値を保存する方法について、検討してみました。
会員制サイト等での、ログイン情報等を保存し。
各ページで、保存された変数を使用。

=>今回は、vuex を使用せず。localStorageに保存しています。

環境

php7.1
Laravel 5.6
Vue.js

参考の設定

resource など、一部のフォルダです。
github.com

実装など

ユーザー追加等は、Laravel のauth 機能を
追加しました。(手抜きですが。)


php.exe artisan make:auth
php.exe artisan migrate

下記で、ユーザーを追加しておきます、
http://localhost:8000/register

・app.js
https://github.com/kuc-arc-f/spa1_ver2/blob/master/resources/assets/js/app.js
認証画面を追加

       { path: '/users/login'        , component: require('./components/Users/Login.vue') },

api.php
https://github.com/kuc-arc-f/spa1_ver2/blob/master/routes/api.php
認証API の追加

    // users
    Route::post('users/auth',  function(Request $request) {
        $const = new AppConst;
        $ret=$const->NG_CODE;
        $email   = request('email');
        $password= request('password');
//var_dump( $password );
        $query = App\User::query();
        $query->where('email', $email);
        $user = $query->first();
        if (Hash::check($password, $user->password)) {
            $ret= $const->OK_CODE;
        }
        return ['ret'=>$ret,'user'=> $user ];
    });

Vue.js

・Login.vue
https://github.com/kuc-arc-f/spa1_ver2/blob/master/resources/assets/js/components/Users/Login.vue

ログイン認証が、完了した場合。結果をストレージに保存しています。

<template lang="html">
    <div class="container">
            <h1>User -Login</h1>
            <div class="form-group">
                <label for="email">email</label>
                <input type="text" class="form-control" id="email" v-model="email" >
            </div>
            <div class="form-group">
                <label for="password">password</label>
                <input type="password" class="form-control" id="password" v-model="password" >
            </div>
            <button v-on:click="postLogin">ログイン</button>
    </div>
</template>

<script>
    export default {
        data() {
            return {
                email:'',
                password:'',
                store:  [],
                user:   []
            }
        },
        mounted: function() {
        },
        methods: {
            postLogin(){
                var user = {
                    'email': this.email,
                    'password': this.password
                };
                axios.post('/api/users/auth/' ,user).then(res => {
                    console.log(res.data );
                    if(res.data.ret==1){
                        this.user = res.data.user
                        this.store.push({
                            id: this.user.id
                        })
                        myStorage.save( this.store )
                        window.location.href='/'
                    }else{
                        console.log('#-NG-auth');
                    }
                });
            }
        }
    }
</script>

・my_storage.js
localStorage 処理
https://github.com/kuc-arc-f/spa1_ver2/blob/master/public/js/my_storage.js

実行結果

・指定ページ、ログアウト後に開くと。
 認証状態をチェックして、
 ログイン画面に。強制 リダイレクトできました。
(vue-router 経由)

f:id:knaka0209:20190414164442p:plain

その他

flashメッセージ表示を追加しました。
(2019/04/15)
・/tasks/new/ で、登録、完了後。
/tasks 、一覧で。完了メッセージを表示。

f:id:knaka0209:20190415150239p:plain

・Vueコンポーネントは、
resources\assets\js\components\Layouts\FlashMessage.vue
を追加
https://github.com/kuc-arc-f/spa1_ver2/blob/master/resources/assets/js/components/Layouts/FlashMessage.vue