Vue コンポーネント
目次
登録・利用
呼び出し
※html
<div id=”app”>
<hello />
</div>
グローバル登録
※js
Vue.component(‘hello‘, {
template: `<div>Hello {{ name }}!</div>`,
data: function(){
return {
name: ‘global’,
};
}
});
new Vue({
el: ‘#app’,
});
結果→Hello global!
ローカル登録
※js
let hello = {
template: `<div>Hello {{ name }}!</div>`,
data: function(){
return {
name: ‘local’,
};
}
};
new Vue({
el: ‘#app’,
components: {
’hello‘: hello,
}
});
結果→Hello local!
props
親→子へデータ送信
※html
<div id=”app”>
<hello name=”props利用” />
</div>
※js
let hello = {
template: `<div>Hello {{ name }}!</div>`,
通常
props: [‘name‘]
型制限
props: {
name: {
type: String, String/Number/Boolean/Function/Object/Array/Date/Symbol
required: true, true/false
規定値
default: ‘〜’,
規定値(Object型)
default: function(){
return {
value: ‘test’
}
}
検証ルール
validator: 〜
検証ルール例(5文字以下)
validator: function(value){
return value <= 5;
}
}
},
};
new Vue(〜);
結果→Hello props利用!
emit
子→親へデータ送信
※html(親)
<div id=”app”>
{{ current }}
plusイベント発生時、onPlusメソッドを実行する
<counter step=”1″ v-on:plus=”onPlus”></counter>
<counter step=”-1″ v-on:plus=”onPlus”></counter>
</div>
※js(子)
let counter = {
template: `<button type=”button” v-on:click=”onClick”>STEP:{{ step }}</button>`,
props: [‘step’],
methods: {
onClick: function(){
親componentでplusイベントを発生させる
this.$emit(‘plus‘, Number(this.step));
}
}
};
new Vue({
el: ‘#app’,
components: {
’counter’: counter,
},
data: {
current: 0,
},
methods: {
onPlus: function(e){
this.current += e;
}
}
});
refs
親→子へデータ送信
※html(親)
<div id=”app”>
<my-child ref=”child”></my-child>
</div>
※js(子)
let MyChild = {
data : function(){
return {
message: ”,
}
},
template: `<p>子:{{ message }}</p>`,
};
new Vue({
el: ‘#app’,
components: {
’my-child’: MyChild,
},
data: {
message: ”,
},
mounted: function(){
this.$refs.child.message = ‘親から設定(this.$refs.child.message)’;
}
});
parent
子→親へデータ送信
※html(親)
<div id=”app”>
<p>親:{{ message }}</p>
</div>
※js(子)
let MyChild = {
template: `<p>子:{{ message }}</p>`,
mounted: function(){
this.$parent.message = ‘子から設定(this.$parent.message)’;
↓ も可
this.$root.message = ‘子から設定(this.$root.message)’;
}
};
new Vue({
el: ‘#app’,
components: {
’my-child’: MyChild,
},
});
slot
親→子へデータ埋め込み
※html(親)
<div id=”app”>
米良太が子コンポーネントのslotタグに埋め込まれる
<my-slot>米良太</my-slot>
</div>
※js(子)
let MySlot = {
ゲストが親コンポーネントにより置換される
template: `<div>Hello <slot>ゲスト</slot>!</div>`,
};
new Vue({
el: ‘#app’,
components: {
’my-slot’: MySlot,
},
});
結果→Hello 米良太!
名前付きslot(複数のslot利用)
<div id=”app”>
<my-slot>
<template v-slot:header>Welcome</template>
Vue.js
↓ も可
<template v-slot:default>Vue.js</template>
<template v-slot:footer>Thank You…</template>
</my-slot>
</div>
<script>
let MySlot = {
template: `
<div>
<header>
<slot name=”header“>DEFAULT</slot>
</header>
<div>
<slot>DEFAULT</slot>
↓ と同じ意味
<slot name=”default“>DEFAULT</slot>
</div>
<footer>
<slot name=”footer“>DEFAULT</slot>
</footer>
</div>`,
};
new Vue({
el: ‘#app’,
components: {
’my-slot’: MySlot,
},
});
</script>
結果→
Welcome
Vue.js
Thank You…
動的コンポーネント
バナーの切り替え例
<div id=”app”>
指定のコンポーネントを読み込み
<component v-bind:is=”curretBanner” />
</div>
<script>
バナー用コンポーネント登録
Vue.component(‘banner-member’, {
template: `
<div class=”banner”>
<h3>バナーHeder(member)</h3>
<p>バナーBody(member)</p>
</div>`,
});
Vue.component(‘banner-new’, {
template: 〜
});
Vue.component(‘banner-env’, {
template: 〜
});
new Vue({
el: ‘#app’,
created: function(){
let that = this;
this.interval = setInterval(function(){
0、1、2の数値を3秒毎に入れ替える
that.current = (that.current + 1) % that.components.length;
}, 3000);
},
beforeDestroy: function(){
clearInterval(this.interval);
},
computed: {
curretBanner: function(){
バナー名の配列を返す
return ‘banner-’ + this.components[this.current];
},
},
data: {
current: 0,
components: [
’member’,
’new’,
’env’,
],
}
});
</script>
タブの利用例
<div id=”app”>
<div id=”container”>
<ul>
<li v-for=”tab in tabNames”>
<a href=”#” v-on:click.prevent=”onClick(tab)”>{{ tabs[tab] }}</a>
</li>
</ul>
※タブの切り替え時に入力値を残す
componentの値をキャッシュする
<keep-alive>
指定のコンポーネントを読み込み
<component v-bind:is=”currentTab” />
</keep-alive>
</div>
</div>
<script>
タブ用コンポーネント登録
Vue.component(‘tab-member’, {
template: `
<div class=”tab”>
<input type=”text” v-model=”name” />
<input type=”submit” value=”登録” />
</div>
`,
data: function(){
return {
name: ”,
};
},
});
Vue.component(‘tab-new’, {
template: `〜`,
});
Vue.component(‘tab-env’, {
template: `〜`,
});
new Vue({
el: ‘#app’,
methods: {
onClick: function(tab){
this.current = tab;
}
},
computed: {
tabNames: function(){
return Object.keys(this.tabs);
},
currentTab: function(){
return `tab-${this.current}`;
},
},
data : {
current: ‘member’,
tabs: {
’member’: ‘メンバー募集’,
’new’: ‘新刊紹介’,
’env’: ‘環境設定’,
},
}
});
</script>