Vue.js 3

(function(){
	'use strict';

	var likeComponent = Vue.extend({
		template : '<button>like</button>'
	});

	var app = new Vue({
		el: '#app',
		components: {
			'like-component': likeComponent
		}
	});
})();
(function(){
	'use strict';

	var likeComponent = Vue.extend({
		data: function(){
			return {
				count: 0
			}
		},
		template : '<button @click="countUp">like {{ count }}</button>',
		methods: {
			countUp: function(){
				this.count++;
			}
		}
	});

	var app = new Vue({
		el: '#app',
		components: {
			'like-component': likeComponent
		}
	});
})();
(function(){
	'use strict';

	var likeComponent = Vue.extend({
		props: {
			message: {
				type: String,
				default: 'Like'
			}
		},
		data: function(){
			return {
				count: 0
			}
		},
		template : '<button @click="countUp">{{ message }} {{ count }}</button>',
		methods: {
			countUp: function(){
				this.count++;
			}
		}
	});

	var app = new Vue({
		el: '#app',
		components: {
			'like-component': likeComponent
		}
	});
})();
(function(){
	'use strict';

	var likeComponent = Vue.extend({
		props: {
			message: {
				type: String,
				default: 'Like'
			}
		},
		data: function(){
			return {
				count: 0
			}
		},
		template : '<button @click="countUp">{{ message }} {{ count }}</button>',
		methods: {
			countUp: function(){
				this.count++;
				this.$emit('increment');
			}
		}
	});

	var app = new Vue({
		el: '#app',
		components: {
			'like-component': likeComponent
		},
		data: {
			total: 0
		},
		methods: {
			incrementTotal: function(){
				this.total++;
			}
		}
	});
})();

Vue.js 2

<p>Hello {{ name.toUpperCase() }}</p>
		<p><input type="text" v-model="name"></p>
(function(){
	'use strict';

	var vm = new Vue({
		el: '#app',
		data: {
			newItem: '',
			todos:[
				'task1',
				'task2',
				'task3'
			]

		},
		methods: {
			addItem: function(){
				// e.preventDefault();
				this.todos.push(this.newItem);
				this.newItem = '';
			}
		}
	});
})();
<div id="app" class="container">
		<h1>My Todos</h1>
		<ul>
			<li v-for="(todo, index) in todos">
			{{ todo }}
			<span @click="deleteItem(index)" class="command">[x]</span>
		</li>
		</ul>
		<form @submit.prevent="addItem">
			<input type="text" v-model="newItem">
			<input type="submit" value="Add">
		</form>
	</div>
(function(){
	'use strict';

	var vm = new Vue({
		el: '#app',
		data: {
			newItem: '',
			todos:[{
				title: 'task1',
				isDone: false
			},{
				title: 'task2',
				isDone: false
			},{
				title: 'task3',
				isDone: true
			}]

		},
		methods: {
			addItem: function(){
				var item = {
					title: this.newItem,
					isDone: false
				};
				this.todos.push(item);
				this.newItem = '';
			},
			deleteItem: function(index){
				// e.preventDefault();
				if(confirm('are you shure')){
					this.todos.splice(index, 1);
				}
				
			}
		}

	});
})();
computed: {
			remaining: function(){
				var items = this.todos.filter(function(todo){
					return !todo.isDone;
				});
				return items.length;
			}
		}
(function(){
	'use strict';

	var vm = new Vue({
		el: '#app',
		data: {
			newItem: '',
			todos:[]
		},
		watch: {
			todos: {
				handler: function(){
					localStorage.setItem('todos', JSON.stringify(this.todos));
				},
				deep: true
			}
		},
		mounted: function(){
			this.todos = JSON.parse(localStorage.getItem('todos')) || [];
		},
		methods: {
			addItem: function(){
				var item = {
					title: this.newItem,
					isDone: false
				};
				this.todos.push(item);
				this.newItem = '';
			},
			deleteItem: function(index){
				// e.preventDefault();
				if(confirm('are you shure')){
					this.todos.splice(index, 1);
				}
				
			},
			purge: function(){
				if(!confirm('delete finished')){
					return;
				}
				this.todos = this.remaining;
				
			}
		},
		computed: {
			remaining: function(){
				return this.todos.filter(function(todo){
					return !todo.isDone;
				});
			}
		}

	});
})();

Vue.js 1

Vue.jsとは?
ユーザーインターフェイスを構築するためのプログレッシブフレームワーク
双方向データバインディング
web:https://jp.vuejs.org/v2/guide/index.html
-> 「はじめに」のdemoを見ると、フレームワークとしてはAnglarJSに凄く似ているように見える

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
	<link ref="stylesheet" src="css/styles.css">
</head>
<body>
	<div id="app">
		<p>Hello {{ name }}</p>
	</div>


	<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
	<script src="js/main.js"></script>
</body>
</html>
(function(){
	'use strict';

	var vm = new Vue({
		el: '#app',
		data: {
			name: 'yoshi'
		}
	});
})();

anglarの場合は、inputをそのままdomに書いていたけど、vueはjs側で記述する必要がありそうですね。

TypeScript 3

class User {
	constructor(private _name: string){
	}

	public sayHi(): void {
		console.log("hi i am" + this._name);
	}
	get name(){
		return this._name;
	}
	set name(newValue: string){
		this._name = newValue;
	}
}

var tom = new User("Tom");
console.log(tom.name);
tom.sayHi();
console.log(tom.name);
tom.sayHi();
class User {
	constructor(protected _name: string){
	}

	public sayHi(): void {
		console.log("hi i am" + this._name);
	}
}

class AdminUser extends User {
	private _age: number;
	construtor (_name: string, _age: number){
		super(_name);
		this._age = _age;
	}
	public sayHi(): void {
		console.log("my age: " + this._age);
		console.log("my name: " + this._name);
		super.sayHi();
	}
}

var bob = new AdminUser("Bob", 23);
bob.sayHi();
class User {
	name: string;
	constructor(name: string){
		this.name = name;
		User.count++;
	}
	sayHi(): void {
		console.log("hi! i am" + this.name);
	}
	static count: number = 0;
}

var tom = new User("Tom");
var bob = new User("Bob");
console.log(User.count);
// interface
interface Result{
	a: number;
	b: number
}

function getTotal(result: Result){
	return result.a + result.b;
}

var result = {
	a: 32,
	b: 55
};

console.log(getTotal(result));

// interface
interface SpringResult {
	a: number;
}
interface FallResult {
	b: number;
}
interface FinalResult extends SpringResult, FallResult{
	final: number;
}


function getTotal(result: FinalResult){
	return result.a + result.b + result.final;
}

var result = {
	a: 32,
	b: 55,
	final: 67
};

console.log(getTotal(result));
interface GameUser{
	socre: number;
	showScore(): void;
}

class User implements GameUser {
	name: string;
	score : number = 0;
	constructor(name: string){
		this.name = name;
	}
	sayHi(): void {
		console.log("hi, i am" + this.name);
	}
	showSchore(): void {
		console.log("score" + this.score);
	}
}
// generics

function getArray<T>(value: T): T[]{
	return [value, value, value];
}

console.log(getArray<number>(3))
class MyData<T>{
	constructor(public value: T){}
	getArray(): T[]{
		return [this.value, this.value, this.value];
	}
}
var v1 = new MyData<string>("hello");
console.log(v1.getArray());
var v2 = new MyData<number>(234);
console.log(v2.getArray());
// 内部モジュール

module UserModule {
	export var name = "sato";
	export moudle AddressModule {
		export var zip = "111-1111";
	}
}
console.log(UserModule.name);
console.log(UserModule.AddressModule.zip);
// 外部モジュール

import User = require("./user_commonjs")
console.log(User.name);

[vagrant@localhost typescript]$ tsc main.ts -m commonjs

TypeScript 2

web:https://www.typescriptlang.org/

typescriptはtsとjsを共存して書ける
main.ts

class User {
	
}
console.log("hello world");

main.js

var User = /** @class */ (function () {
    function User() {
    }
    return User;
}());
console.log("hello world");

変数の後にコロンを入れて型を宣言する

var x: number = 10;
x = "hello";

// number, string, boolean, any
var i: number;
var i = 10; // i:number 型推論

var x; // var x:any

var results: number[]; // 配列の宣言
results = [10, 5, 3];

列挙型

// 列挙型
enum Signal {
	Red = 0,
	Blue = 1,
	Yello = 2
}
var result: Signal;
console.log(Signal[2]);

// 列挙型
enum Signal {
	Red,
	Blue = 3,
	Yello
}
var result: Signal;
console.log(Signal[3]);

enum Signal {
	Green = 6
}

拡張もできる

関数
型制限を間違えるとコンパイル時にエラーになる

function add(a:number, b:number) : number{
	return a + b;
}
console.log(add(5, 3));

function add(a:number, b:number) : number{
	if(b){
		return a + b;
	} else {
		return a + a;
	}
}

関数式

var add = function(a: number, b: number){
	return a + b;
}

var add = (a: number, b: number): number =>{
	return a + b;
}

オーバーロード

function add(a: number, b: number): number; // シグネチャ
function add(a: string, b: string): string;

function add(a: any, b: any): any {
	if(typeof a === "string" && typeof b === "string"){
		return a + " " + b;
	}
	return a + b;
}

class

class User {
	public name: string;

	constructor(name: strin){
		this.name = name;
	}

	sayHi(): void {
		console.log("hi i am" + this.name);
	}
}

var tom = new User("Tom");

TypeScript 1

TypeScriptとは?
– Microsoftによって開発されたJavaScript拡張言語
– 静的型付クラスベースオブジェクト言語
– AngularJSもTypeScript推奨
– TypeScript作者はC#の制作者(マジかよ)

JSでの大規模開発向けか?
TypeScriptの求人を眺めているとロジック実装が多そうではある

$ sudo npm install -g typescript
$ tsc -v
Version 3.7.2

hello.ts

class test{
	constructor(public Text: string){}

	helloShow()
	{
		return this.Text;
	}
}

var msgStr = new test("Hello World!");
document.body.innerHTML = msgStr.helloShow();

[vagrant@localhost typescript]$ tsc hello.ts
[vagrant@localhost typescript]$ ls
hello.js hello.ts node_modules package-lock.json

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>

</head>
<body>
<script src="hello.js"></script>
</body>
</html>

BEMとは

BEMとは
– フロントエンドの設計方法
– Block、Element、Modifier
– 厳格なclass名の命名ルール
https://en.bem.info/methodology/

背景
– スタイルの優先順位の指定が難しい
– !importantの多用
– パーツを別の場所に流用すると表示が崩れる
– 制作者本人しかわからないclass名

制作ボリュームが膨大になった時、全体像を誰も理解できないってのはよくありますね。
特に、長いサービスだと、前任者が全員退職して、知っている人がいないとか。

BEMではパーツをBlockと呼ぶ
Blockはid属性ではなく、classを使う
※idは1ページ1回、classは重複利用可能
Blockは入れ子にしない

ElementはBlockの構成要素
Elementのclass名はblockの構成要素名を入れる

.search
.search__input
.search__button


Modiferは既存のBlockやElementと似た物を作りたいとき

<ul class="list  list_type_disc">
  <li class="list__item"></li>
  <li class="list__item"></li>
  ...
</ul>
 
<ul class="list  list_type_check">
  <li class="list__item"></li>
  <li class="list__item"></li>
  ...
</ul>

BEMでは、block, element, modiferで一貫したセパレーター(_)を使う

modife: Block_key_value
単語はハイフン(-)もしくはキャメルケースなど

で、BEMはどれ位使われているかというと、50%くらい
50%といえば、かなりの割合ですなー

AngularJS 4

残り文字数の表示

<form novalidate name="myForm" ng-submit="addUser()">
			<p>18+:<input type="checkbox" ng-model="user.adult" ng-true-value="adult" ng-false-value="chile"></p>
			<p>phone:<input type="radio" ng-model="user.phone" value="iphone"> iPhone</p>
			<input type="radio" ng-model="user.phone" value="android"> Android</p>
			<p>Memo:
				<textarea ng-model="user.memo" ng-maxlength="140"></textarea>{{140-user.memo.length}}
			<p><input type="submit" value="add"></p>
			<pre>{{user|json}}</pre>
		</form>

これめっちゃいい、使いたい

<form novalidate name="myForm" ng-submit="addUser()">
			<p>Color:
				<select ng-model="user.color" ng-options="'label:'+color for color in &#91;'red','blue','pink'&#93;" ng-init="user.color='red'"></select>
			</p>
			<p><input type="submit" value="add"></p>
			<pre>{{user|json}}</pre>
		</form>

AngularJS 3

<li ng-repeat="user in users" ng-controller="UserItemController">
				{{user.name|uppercase}} {{user.score}}
				<button ng-click="increment()">+1</button>
			</li>
angular.module('myapp', [])
    .controller('MainController', ['$scope', function($scope) {
        $scope.users = [
            {"name":"taguchi", "score":52.22},
            {"name":"tanaka", "score":38.22},
            {"name":"yamada", "score":11.11},
            {"name":"goto", "score":22.22},
            {"name":"kurumi", "score":58.22},
            {"name":"sakamoto", "score":81.11},
        ];
        $scope.today = new Date();
    }])
    .controller('UserItemController', ['$scope', function($scope){
        $scope.increment = function(){
            $scope.user.score++;
        };
    }]);

やっぱGoogleはリアルタイム処理とか高速処理がめちゃくちゃ強いな。会社作った時からそーなんだろうけど、何でだろう。。

<div ng-controller="MainController">
		<form name="myName" ng-submit="addUser()">
			<p>Name:<input type="text" name="name" ng-model="user.name"></p>
			<p><input type="submit" value="add"></p>
			<pre>{{user|json}}</pre>
		</form>
	</div>

フォームのバリデーションはhtml5やサーバーサイド側でもできるけど、DBに入力しない問い合わせフォームのバリデーションはangularでもいいかもね。

<form novalidate name="myForm" ng-submit="addUser()">
			<p>Name:<input type="text" name="name" ng-model="user.name" required ng-minlength="5" ng-maxlength="8">
			<span ng-show="myForm.name.$error.required">Required!</span>
			<span ng-show="myForm.name.$error.minlength">too short!</span>
			<span ng-show="myForm.name.$error.maxlength">too long!</span></p>
			<p><input type="submit" value="add"></p>
			<pre>{{user|json}}</pre>
		</form>

emailは正規表現のルールはデフォルトがあるのか、これは自分で決めたいよね。

<form novalidate name="myForm" ng-submit="addUser()">
			<p>score:<input type="number" name="score" ng-model="user.score">
			</p>
			<p>email:<input type="email" name="email" ng-model="user.email">
			<span ng-show="myForm.email.$error.email">Not valide email</span></p>
			<p><input type="submit" value="add"></p>
<p>web:<input type="url" name="url" ng-model="user.url">
			<span ng-show="myForm.url.$error.url">Not valide url</span></p>
			<pre>{{user|json}}</pre>
		</form>

AngularJS 2

<!DOCTYPE html>
<html lang="en" ng-app="myapp">
<head>
	<meta charset="UTF-8">
	<title>Angular</title>
	<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.8/angular.min.js"></script>
	<script src="myscript.js"></script>
</head>
<body>
	<h1>practice angular</h1>
	<div ng-controller="MainController">
		<p>{{users.length}} users</p>
		<ul>
			<li ng-repeat="user in users">
				{{user.name}} {{user.score}}
			</li>
		</ul>
	</div>
</body>
</html>
angular.module('myapp', [])
    .controller('MainController', ['$scope', function($scope) {
        $scope.users = [
            {"name":"taguchi", "score":52.22},
            {"name":"tanaka", "score":38.22},
            {"name":"yamada", "score":11.11}
        ];
    }]);

numberは便利だ
todayは単純にjsのdateを渡すだけです

<li ng-repeat="user in users">
				{{user.name|uppercase}} {{user.score|number:4}}
			</li>
<p>{{600 * 240| number}}</p>
<p>{{today}}</p>
<p>{{today|date: 'yyyy-MM-dd'}}</p>

filter
filterはsqlから取得する場合はwhere-byで指定する箇所だけど、データバインディングで使うところって何だろう? 
あああああああああああああ、filter:queryは検索一覧ですげー使えるじゃん。。。さすがGoogle
あれ、でもこれ、keyとvalueでmysqlからjsファイルに吐き出さないとダメってこと??まー試す価値はありそうね。

<li ng-repeat="user in users|limitTo:5">
<li ng-repeat="user in users|orderBy:'score'">
<li ng-repeat="user in users|orderBy:'-score'|limitTo:3">
<li ng-repeat="user in users|filter:query">

classのeven, oddも便利ですねー

{{$index}}{{user.name|uppercase}} {{user.score|number:4}}
{{$index+1}} {{$first}} {{$last}}{{user.name|uppercase}} {{user.score|number:4}}
<li ng-repeat="user in users" ng-class-even="'even'" ng-class-odd="'odd'">