Vue.jsのラジオボタン

Demo

html

	<div id="app1">
		<div>
			<label v-for="(ent, index) in animals" style="margin-right:20px">
				<input type="radio" v-model="active_value" v-bind:value="ent.value" />{{ent.animal_name}}
			</label>
		</div>
		<br><br>
		animal_value→<span>{{active_value}}</span><br>
	</div>
	

JavaScript

	var app; // vue.js
	jQuery(() => {
	
		let animals = [
			{animal_name:'cat', value:1},
			{animal_name:'ヤンバルクイナ', value:2},
			{animal_name:'ヒージャー(やぎ)', value:3},
			{animal_name:'ウヮー(pig)', value:4},
			{animal_name:'インガー(The publish dog)', value:5},
		];
		
		app = new Vue({
				el: '#app1',
				data: {
					animals: animals,
					active_value:2,
				}
			})
	});
	

Vue.js | ラジオボタンのクリックイベント

Demo

html

	<div id="app1">
		<div>
			<label v-for="(ent, index) in animals" style="margin-right:20px">
				<input type="radio" v-model="active_value" v-bind:value="ent.value" v-on:click="clickAnimalRdo(index)" />{{ent.animal_name}}
			</label>
		</div>
		<br><br>
		animal_value→<span>{{active_value}}</span><br>
		<div>{{msg1}}</div>
	</div>
	

JavaScript

	var app; // vue.js
	jQuery(() => {
	
		let animals = [
			{animal_name:'cat', value:1},
			{animal_name:'ヤンバルクイナ', value:2},
			{animal_name:'ヒージャー(やぎ)', value:3},
			{animal_name:'ウヮー(pig)', value:4},
			{animal_name:'インガー(The publish dog)', value:5},
		];
		
		app = new Vue({
				el: '#app1',
				data: {
					animals: animals,
					active_value:2,
					msg1:'テストメッセージ',
				},
				methods: {
					clickAnimalRdo:(index)=>{
						let animal_name = app.animals[index].animal_name;
						app.msg1 = index + ':' + animal_name;
					}
				}
			})
	});
	

Vue.jsのバリデーション | 基本

Vue.js自体にはバリデーション機能はないようだが、工夫次第でVue.jsの機能だけで実現できる。

Demo

HTML

	<div id="app1">
		<table class="tbl2">
			<thead><tr><th>項目名</th><th>入力</th><th>説明</th></tr></thead>
			<tbody>
				<tr>
					<td>名前</td>
					<td>
						<input type="text" v-model="ent.animal_name" v-on:change="valid_animal_name(ent.animal_name)" />
						<div class="text-danger">{{valids.animal_name}}</div>
					</td>
					<td>必須 4文字以内</td>
				</tr>
			</tbody>
		</table>
	</div>
	

JavaScript


class AnimalClass{

	init(){
		let ent = {
				animal_name: '西表山猫',
		};
		
		// // バリデーションエラーメッセージリスト
		let valids = {
				animal_name: '',
		}; 
		
		this.app = new Vue({
				el: '#app1',
				data: {
					ent:ent,
					valids:valids,
					err_msg:'',
				},
				methods:{
					valid_animal_name:(value)=>{
						
						// 必須入力&文字数制限
						let err = '';
						if(value == null || value == ''){
							err = '必須入力です。';
						}else{
							if(value.length > 4){
								err = '4文字以内で入力してください。';
							}
						}
						this.app.valids.animal_name = err;
					},
				},
			});
	}
}

jQuery(() => {
	let animal = new AnimalClass;
	animal.init();
});


	

Vue.jsのバリデーション | 応用

数値、日付、メールアドレス、パスワードなどのサンプル。
初期表示のとき、またはボタンを押したとき、全フィールドのバリデーションを一括で行う機能も掲載。

Demo

HTML


	<div id="app1">
		<table class="tbl2">
			<thead><tr><th>項目名</th><th>入力</th><th>説明</th></tr></thead>
			<tbody>
				<tr>
					<td>名前</td>
					<td>
						<input type="text" v-model="ent.animal_name" v-on:change="valid_animal_name(ent.animal_name)" />
						<div class="text-danger">{{valids.animal_name}}</div>
					</td>
					<td>必須 10文字以内</td>
				</tr>
				<tr>
					<td>数値</td>
					<td>
						<input type="text" v-model="ent.animal_value" v-on:change="valid_animal_value(ent.animal_value)" />
						<div class="text-danger">{{valids.animal_value}}</div>
					</td>
					<td>自然数</td>
				</tr>
				<tr>
					<td>日付</td>
					<td>
						<input type="text" v-model="ent.animal_date" v-on:change="valid_animal_date(ent.animal_date)" />
						<div class="text-danger">{{valids.animal_date}}</div>
					</td>
					<td></td>
				</tr>
				<tr>
					<td>カナ</td>
					<td>
						<input type="text" v-model="ent.animal_kana" v-on:change="valid_animal_kana(ent.animal_kana)" />
						<div class="text-danger">{{valids.animal_kana}}</div>
					</td>
					<td></td>
				</tr>
				<tr>
					<td>ひらがな</td>
					<td>
						<input type="text" v-model="ent.animal_hira" v-on:change="valid_animal_hira(ent.animal_hira)" />
						<div class="text-danger">{{valids.animal_hira}}</div>
					</td>
					<td></td>
				</tr>
				<tr>
					<td>メールアドレス</td>
					<td>
						<input type="text" v-model="ent.animal_mail" v-on:change="valid_animal_mail(ent.animal_mail)" />
						<div class="text-danger">{{valids.animal_mail}}</div>
					</td>
					<td>必須</td>
				</tr>
				<tr>
					<td>電話番号</td>
					<td>
						<input type="text" v-model="ent.animal_tell" v-on:change="valid_animal_tell(ent.animal_tell)" />
						<div class="text-danger">{{valids.animal_tell}}</div>
					</td>
					<td></td>
				</tr>
				<tr>
					<td>郵便番号</td>
					<td>
						<input type="text" v-model="ent.animal_post" v-on:change="valid_animal_post(ent.animal_post)" />
						<div class="text-danger">{{valids.animal_post}}</div>
					</td>
					<td></td>
				</tr>
				<tr>
					<td>パスワード</td>
					<td>
						<input type="text" v-model="ent.animal_password" v-on:change="valid_animal_password(ent.animal_password)" />
						<div class="text-danger">{{valids.animal_password}}</div>
					</td>
					<td>8文字以上の半角英数字(アルファベットと数値を必ず一つ以上入力すること)</td>
				</tr>
				<tr>
					<td>コード</td>
					<td>
						<input type="text" v-model="ent.animal_code" v-on:change="valid_animal_code(ent.animal_code)" />
						<div class="text-danger">{{valids.animal_code}}</div>
					</td>
					<td></td>
				</tr>
	
			</tbody>
		</table>
		
		<div><input type="button" v-on:click="clickBtn1" value="ボタン" class="btn btn-success"/></div>
		<div class="text-danger" v-html="err_msg"></div>
	</div>
	


JavaScript


	class AnimalClass{
	
		init(){
			
			this.cbv = new CrudBaseValidation(); // 汎用バリデーション関数群クラス
			
			let ent = {
					animal_name: '西表山猫',
					animal_value: 1234, 
					animal_date: '2020-3-12',
					animal_kana:'イリオモテヤマネコ',
					animal_hira:'いりおもてやまねこ',
					animal_mail:'iriomote_yamaneko.1.2@example.com',
					animal_tell:'090-xxxx-1234',
					animal_post:'907-1435',
					animal_password:'12345abcd',
					animal_code:'ab-123',
			};
			
			let valids = this._getValids(ent); // バリデーションエラーメッセージリスト
			let methods = this._getValidMethods(); // バリデーションメソッドリスト
			
			// ボタンクリックイベントを追加
			methods['clickBtn1'] = ()=>{
					this.clickBtn1();
			};
			
			this.app = new Vue({
					el: '#app1',
					data: {
						ent:ent,
						valids:valids,
						err_msg:'',
					},
					methods:methods,
				});
			
			this._validationAll(); // エンティティ内の全フィールドを一括バリデーション
	
		}
		
		/**
		 * バリデーションエラーメッセージリスト
		 */
		_getValids(ent){
			let valids = {};
			for(let field in ent){
				valids[field] = '';
			}
			return valids;
		}
		
		/**
		 * バリデーションメソッドリスト
		 */
		_getValidMethods(){
			let methods = {
					valid_animal_name:(value)=>{
						
						// 必須入力&文字数制限
						let err = '';
						if(value == null || value == ''){
							err = '必須入力です。';
						}else{
							if(value.length > 10){
								err = '10文字以内で入力してください。';
							}
						}
						this.app.valids.animal_name = err;
					},
					
					valid_animal_value:(value)=>{
						let err = '';
						
						// 自然数バリデーション
						if(!this.cbv.isNaturalNumber(value)){
							err = '自然数で入力してください。';
						}
						this.app.valids.animal_value = err;
					},
					
					valid_animal_date:(value)=>{
						// 日付チェック
						let err = '';
						if(!this.cbv.isDate(value)){
							err = "日付形式(例:2020-12-31)で入力してください。";
						}
						this.app.valids.animal_date = err;
					},
					
					valid_animal_kana:(value)=>{
						
						// カタカナチェック
						let err = '';
						if(!this.cbv.isKatakana(value)){
							err = 'カタカナで入力してください。';
						}
						this.app.valids.animal_kana = err;
					},
					
					valid_animal_hira:(value)=>{
						
						// ひらがなチェック
						let err = '';
						if(!this.cbv.isHiragana(value)){
							err = 'ひらがなで入力してください。';
						}
						this.app.valids.animal_hira = err;
					},
					
					valid_animal_mail:(value)=>{
						
						// メールアドレスチェック
						let err = '';
						if(!this.cbv.isMail(value)){
							err = '正しいメールアドレス形式で入力してください。';
						}
						this.app.valids.animal_mail = err;
					},
					
					valid_animal_tell:(value)=>{
						
						// 電話番号チェック
						let err = '';
						if(!this.cbv.isTell(value)){
							err = '電話番号形式で入力してください。(例: 080-xxxx-1234)【半角数字】';
						}
						this.app.valids.animal_tell = err;
					},
					
					valid_animal_post:(value)=>{
						// 郵便番号チェック
						let err = '';
						if(!this.cbv.isPost(value)){
							err = '郵便番号形式で入力してください。(例: 123-4567)【半角数字】';
						}
						this.app.valids.animal_post = err;
					},
					
					valid_animal_password:(value)=>{
						
						// パスワードチェック
						let err = '';
						if(!this.cbv.isPassword(value)){
							err = '半角英数字で入力してください。(アルファベットまた数字を最低1字ずつ含めてください。)';
						}
						this.app.valids.animal_password = err;
					},
					
					valid_animal_code:(value)=>{
						
						// パスワードチェック
						let err = '';
						if(!this.cbv.isAlphaNum(value)){
							err = '半角英数字で入力してください。';
						}
						this.app.valids.animal_code = err;
					},
			}
			return methods;
		}
		
		
		/**
		 * ボタンクリックイベント
		 * @note
		 * まとめてバリデーションを行い、一つのエラーメッセージにまとめて表示する。
		 */
		clickBtn1(){
			let err_msg = ''; // エラーメッセージ
			this._validationAll(); // エンティティ内の全フィールドを一括バリデーション
			
			let valids = this.app.valids;
			for(let i in valids){
				let err = valids[i];
				if(err == '' || err == null) continue;
				err_msg +=err + '<br>';
			}
			
			this.app.err_msg = err_msg; // エラーメッセージ表示
		}
		
		/**
		 * エンティティ内の全フィールドを一括バリデーション
		 */
		_validationAll(){
			let methods = this._getValidMethods();
			let ent = this.app.ent;
			
			for(let field in ent){
				let key = 'valid_' + field;
				let validFunction = methods[key];
				if(validFunction == null) continue;
				let value = ent[field];
				validFunction(value);
			}
		}
		
	}
	
	jQuery(() => {
		let animal = new AnimalClass;
		animal.init();
	});
	


CrudBaseValidation


/**
 * バリデーション関数群
 * 
 * @note
 * InputCheckAの後継
 * 
 * @version 5.0.0
 * @date 2009-7-9 | 2020-3-12
 * @license MIT
 */
class CrudBaseValidation{
	
	/**
	 * 文字数チェックのバリデーション
	 * @param v			対象文字列
	 * @param maxLen	制限文字数
	 * @param req		trueは必須入力。0と半角SPは入力ありとみなす。引数省略時はfalse
	 * @return true:正常  false:エラー
	 */
	isMaxLength(v,maxLen,req){

		//必須入力チェック
		if(req==true){
			if(v == null || v === '' || v === false){
				return false;
			}
		}

		//最大文字数チェックをする。
		var n=v.length;
		if (n > maxLen){
			return false;

		}

		return true;
	}
	
	
	/**
	 * 自然数のチェック
	 * @param mixed value
	 * @return true:正常  false:エラー
	 */
	isNaturalNumber(value){

		var regexp = /^[0-9]*$/;
		if(!regexp.test(value)){
			return false;
		}

		return true;
	}
	
	
	/**
	 * 日付チェック
	 * 
	 * @note
	 * yyyy/mm/dd形式とyyyy-mm-dd形式に対応
	 * 閏年に対応
	 * 空値ならfalseを返す。
	 * 
	 * @param value
	 * @returns true:入力OK    false:入力エラー
	 */
	isDate(value){

		var ary=value.split("/");
		if(ary.length != 3){
			ary=value.split("-");
			if(ary.length != 3){
				return false;;
			}
		}
		
		let y = ary[0];
		let m = ary[1];
		let d = ary[2];

		let regexp = /^[0-9]*$/;
		if(!regexp.test(y)) return false;
		if(!regexp.test(m)) return false;
		if(!regexp.test(d)) return false;
		
		var dt=new Date(y,m-1,d);
		if(dt.getFullYear()!=y || dt.getMonth()!=m-1 || dt.getDate()!=d){
			return false;
		}
		
		return true;
	}
	
	
	/**
	 * カタカナチェック
	 * 
	 * @note
	 * 全角スペースが含まれているとエラー
	 * 
	 * @param value
	 * @returns true:入力OK, false:入力エラー
	 */
	isKatakana(value){
		
		var regexp = /^[ァ-ヶー]*$/;
		if(!regexp.test(value)){
			return false;
		}

		return true;

	}
	
	
	/**
	 * ひらがなチェック
	 * 
	 * @note
	 * 全角スペースが含まれているとエラー
	 * 
	 * @param value
	 * @returns true:入力OK, false:入力エラー
	 */
	isHiragana(value){
		
		var regexp = /^[ぁ-ん]*$/;
		if(!regexp.test(value)){
			return false;
		}

		return true;

	}
	
	
	/**
	 * メールアドレスチェック
	 * 
	 * @note
	 * 空値はエラー
	 * 
	 * @param value
	 * @returns true:入力OK, false:入力エラー
	 */
	isMail(value){
		var regexp = /^[A-Za-z0-9]{1}[A-Za-z0-9_.-]*@{1}[A-Za-z0-9_.-]{1,}¥.[A-Za-z0-9]{1,}$/;
		if(!regexp.test(value)){
			return false;
		}
		return true;
	}
	
	
	/**
	 * 電話番号チェック
	 * 
	 * @note
	 * 空値はエラー。
	 * 全角数字はエラー。
	 * 
	 * @param value
	 * @returns true:入力OK, false:入力エラー
	 */
	isTell(value){
		let regexp = /^[0-9+-]*$/;
		if(!regexp.test(value)){
			return false;
		}
		return true;
	}
	
	
	/**
	 * 郵便番号チェック
	 * 
	 * @note
	 * ハイフンなしの7桁数も入力OK
	 * 空値はエラー。
	 * 全角数字はエラー。
	 * 
	 * @param value
	 * @returns true:入力OK, false:入力エラー
	 */
	isPost(value){
		let regexp = /^¥d{3}-?¥d{4}$/;
		if(!regexp.test(value)){

			regexp = /^¥d{7}$/;
			if(!regexp.test(value)){
				return false;
			}
		}
		
		return true;
	}
	
	
	/**
	 * パスワードチェック
	 * 
	 * @note
	 * アルファベットまた数字を最低1字ずつ含める。
	 * 空値はエラー。
	 * 
	 * @param value
	 * @returns true:入力OK, false:入力エラー
	 */
	isPassword(value){
		let regexp = /^(?=.*?[a-zA-Z])(?=.*?¥d)[a-zA-Z¥d]{8,100}$/;
		if(!regexp.test(value)){
			return false;
		}
		
		return true;
	}
	
	
	/**
	 * コードチェック
	 * 
	 * @note
	 * アルファベット、数字、ハイフン、アンダースコア
	 * 空値はエラー。
	 * 
	 * @param value
	 * @returns true:入力OK, false:入力エラー
	 */
	isAlphaNum(value){
		let regexp = /^[a-zA-Z0-9_¥-]+$/;
		if(!regexp.test(value)){
			return false;
		}
		
		return true;
	}
}
	

vue.jsとjQueryの競合により、ファイル要素のチェンジイベントに不具合

Vue.jsの「v-if」を使うとjQueryのchangeイベントは発動しなくなる。
HTML5標準のonchangeイベントなどで対処する。

HTML
	<div v-if="test_flg==1">
		<input type="file" id="img1" />
	</div>
	

JavaScript
	jQuery('#img1').change((e) =>{
		// イベントが発動しない!!
	});
	

Vue.js | style属性を制御 | CSS

Demo

HTML

<div id="app1">
	<div v-bind:style="styles123">
		ですから,私たちはもう子供であってはならず,波にもまれるかのように翻弄されたり,
		風に吹かれるかのようにさまざまな教えに振り回されたりしてはなりません。
		人に欺かれたり,ずる賢いたくらみに乗せられたりしてはならないのです。 
		- 聖書エフェソス4:14 -
	</div>
	<input type="button" value="スタイル変更" v-on:click="changeStyle()"  />
</div>
	

JavaScript

var app;
jQuery(()=>{
	
	let styles123 = {
			color:'#585858',
	}
	
	app = new Vue({
		el: '#app1',
		data: {
			styles123: styles123,
		},
		methods: {
			changeStyle: () => {
						this.app.styles123.color = '#dc4f43';
						this.app.styles123['padding'] = '20px';
						this.app.styles123['border'] = 'solid 4px #f19355';
				}
			}
	});
});
	


文字を入力するたびにイベント | Vueのonclickとonchange | v-on:click v-on:change v-on:input

文字を入力するたびにイベントを起こすには「v-on:input」が良い。

Demo

HTML


	<div id="app1">
		<p>v-on:clickの検証</p>
	  <input v-model="message1" v-on:click="testClick('こんにちわ世界')">
	  <br>
	  
	  <p>v-on:changeの検証</p>
	  <input v-model="message2" v-on:change="testChange">
	  <div>{{ message2 }}</div>
	  <div>{{ message2b }}</div>
	  <br>
	  
	  <p>v-on:inputの検証</p>
	  <input v-model="message3" v-on:input="testInput">
	  <div>{{ message3 }}</div>
	  <div>{{ message3b }}</div>
	</div>
	

JavaScript


	var app; // vue.js
	jQuery(() => {
		app = new Vue({
				el: '#app1',
				data: {
					message1: 'クリックテスト',
					message2: 'チェンジテスト',
					message2b: 'チェンジテスト',
					message3: 'v-on:inputテスト',
					message3b: 'テスト',
				},
				methods:{
			        testClick: function (value) {
						alert(value);
			        },
					testChange: function(){
						app.message2b = app.message2 + '星人';
					},
					testInput: function(){
						app.message3b = app.message3 + '大人';
					}
				}
			})
	});	
	

要素のインナー(innner)に値を表示 {{hoge}} v-html, v-text


  <p v-html="message"></p> ← HTMLのタグを含む値表示(XSS注意)
  <p v-text="message"></p> ← XSSサニタイズして表示
  <p>{{message}}</p> ← v-textと同じ
	

Vue.js 繰り返しの検証 | iterator イテレータ ループ

Demo

HTML

<div id="app">

	<table class="tbl2">
		<thead>
			<tr><th>動物名</th><th>数値</th><th>日付</th></tr>
		</thead>
		<tbody>
		  <tr v-for="ent in data">
		    <td>{{ ent.animal_name }}</td>
		    <td>{{ ent.value }}</td>
		    <td>{{ ent.animal_date }}</td>
		  </tr>
		</tbody>
	</table>
	
	<div style="margin-top:20px;">
		<p>新規入力フォーム</p>
		<form>
			<div>動物名<input type="text" v-model="createEnt.animal_name" /></div>
			<div>数値<input type="number" v-model="createEnt.value" /></div>
			<div>日付<input type="date" v-model="createEnt.animal_date" /></div>
			<div><button type="button" class="btn btn-success" onclick="store()">追加</button></div>
		</form>
	</div>
	
</div>
	

JavaScript

let app; // vue app

$(()=>{
	
	
	var data = [
		{animal_name:'イモリ', value:100, animal_date:'2022-10-13'},
		{animal_name:'ネコ', value:101, animal_date:'2022-10-14'},
		{animal_name:'カンガルー', value:102, animal_date:'2022-10-15'},
		{animal_name:'バイソン', value:103, animal_date:'2022-10-16'},
	];
	
	var createEnt = {animal_name:'-', value:0, animal_date:''};
		
	
	app = new Vue({
			el: '#app',
			data: {
				'data': data,
				'createEnt': createEnt,
			},
		});
	
})

// 新規入力
function store(){
	app.data.push(app.createEnt);
}

Vue.js 入力フォーム動的追加 | 一覧型入力フォームの行追加

Demo

HTML


<div id="app">

	<table class="tbl2">
		<thead>
			<tr><th>動物名</th><th>数値</th><th>日付</th><th>種類</th></tr>
		</thead>
		<tbody>
		  <tr v-for="ent in data">
		    <td>{{ ent.animal_name }} <input type="text" v-model="ent.animal_name" ></td>
		    <td>{{ ent.value }}</td>
		    <td>{{ ent.animal_date }}</td>
		    <td>
		    	<select v-model="ent.animal_type">
		    		<option v-for="(value, key) in animalTypeList" v-bind:value="key">{{value}}</option>
		    	</select>
		    </td>
		  </tr>
		</tbody>
	</table>
	
	<div style="margin-top:20px;">
		<p>新規入力フォーム</p>
		<form>
			<div>動物名<input type="text" v-model="createEnt.animal_name"/></div>
			<div>数値<input type="number" v-model="createEnt.value" /></div>
			<div>日付<input type="date" v-model="createEnt.animal_date" /></div>
			<div>
				<select v-model="createEnt.animal_type">
					<option v-for="(value, key) in animalTypeList" v-bind:value="key">{{value}}</option>
				</select>
			</div>
			<div><button type="button" class="btn btn-success" onclick="store()">追加</button></div>
		</form>
	</div>
	
</div>
	

JavaScript


let app; // vue app

$(()=>{
	
	var animalTypeList = {
		1:'哺乳類',
		2:'爬虫類',
		3:'鳥類',
		4:'両生類',
		5:'魚類',
		6:'無脊椎動物',
	};

	var data = [
		{animal_name:'イモリ', value:100, animal_date:'2022-10-13', animal_type:4},
		{animal_name:'ネコ', value:101, animal_date:'2022-10-14', animal_type:1},
		{animal_name:'カンガルー', value:102, animal_date:'2022-10-15', animal_type:1},
		{animal_name:'バイソン', value:103, animal_date:'2022-10-16', animal_type:1},
	];
	
	var createEnt = {animal_name:'ヌタウナギ', value:3000, animal_date:'2022-10-23', animal_type:5};

	app = new Vue({
			el: '#app',
			data: {
				'data': data,
				'animalTypeList': animalTypeList,
				'createEnt': createEnt,
			},
		});
	
})

// 新規入力
function store(){
	app.data.push(app.createEnt);
}
	

Vue.js バージョン表示


	console.log(Vue.version);
	

Vue.js Laravelのbladeとの競合対策 → {{}}

bladeの「{{}}」はVue.jsと役割が被る。その場合「@」を付与するとVue.jsの「{{}}」になる。「@」を付与していない場合はLaravelのものになる。

@{{vue_message1}}