今回も参考記事をもとに進めさせていただきます。
コンポーネントの基本こちらも見させていただきます。
##◆コンポーネント
コンポーネントは、ページの部品ごとに、html/js/cssをまとめちゃおうという考え方(管理がしやすく再利用性も高い)
Vue.jsにはコンポーネントをグローバル・ローカルに登録して利用することができます。
<body>
<div id="sample">
<sample></sample>
</div>
</body>
<script src=" {{ asset('js/app.js') }} "></script>
<script>
Vue.component('sample', {
template: '<h1>こんにちは</h1>'
});
const vue = new Vue({
el: '#sample',
});
</script>
<body>
<div id="sample">
<sample></sample>
</div>
</body>
<script src=" {{ asset('js/app.js') }} "></script>
<script>
const sample = {
template: '<h1>こんにちは</h1>'
};
const vue = new Vue({
el: '#sample',
components: {
sample: sample
}
});
</script>
注意点として、コンポーネントはVueインスタンスを作成する前に定義してからVueインスタンスを作成することで、呼び出すことができます。また、コンポーネントでは、dataは複数のコンポーネントが同じオブジェクトを参照するという問題が発生するため、関数でないといけません。
data(){
return{
message: 'こんにちは'
}
}
##◆コンポーネント間のデータ渡し
参考記事
###親から子へデータを渡す
<body>
<div id="sample">
<child message="こんにちは"></child>
</div>
</body>
<script src=" {{ asset('js/app.js') }} "></script>
<script>
Vue.component('child', {
template: '<h1>@{{ message }}</h1>',
props: ['message']
});
const vue = new Vue({
el: '#sample',
});
</script>
親から子へデータを渡すときに、子で受け取り変数はpropsで定義しておきます。
親で使うときにその変数に値を入れて渡します。
データ変数を渡したい場合、
<child :message="message"></child>
として、親のdataでmessageを定義してあげれば連動できます。
propsはデータ型も指定できます。データ型一覧
バリデーションのようなものと感じました。
###子から親のイベント発火
参考記事
子から親へデータを渡す際に必要となるのが$emitとカスタムv-onです。
<body>
<div id="sample">
<child @child-event="parentEvent"></child>
</div>
</body>
<script src=" {{ asset('js/app.js') }} "></script>
<script>
Vue.component('child', {
template: '<button @click="sendParent">クリック</button>',
methods:{
sendParent(){
this.$emit('child-event');
}
}
});
const vue = new Vue({
el: '#sample',
methods:{
parentEvent(){
alert('親要素が反応しました。')
}
}
});
</script>
子コンポーネントから見ていきますと、templateとしてclickイベントを備えたボタンを用意しました。
ボタンをクリックすると親コンポーネントの'child-event'が発火します。
親では、カスタムv-on(今回は省略して@child-event)が発火すると、親メソッドのparentEventが発火するようにしています。
注意点としては、@child-eventをキャメルケース(childEvent)で書いてしまうと動かなくなります。
$emitは第二引数を指定すると、好みのパラメータも渡せます。
##親子以外のコンポーネントのイベント発火
イベントバスと呼ばれるものを利用します。具体的は関係ない二つのコンポーネント用に共通のVueインスタンスを用意して、
イベントを発火させるほうに、$emit、イベントを待ち受けるほうにmoutedもしくはcreatedのタイミングで、$onを使用してイベントを検知します。参考記事
##親から子のイベント発火
こちらも$emitと$onを使用しますが、違う点はrefと$refsも使用します。この二つは、前回直接DOMをいじるときに使いました。使い方はそれと同じです。
<body>
<div id="sample">
<child ref="child"></child>
<button @click="click">クリック</button>
</div>
</body>
<script src=" {{ asset('js/app.js') }} "></script>
<script>
Vue.component('child', {
template: '<h1>子コンポーネント</h1>',
created: function(){
this.$on('alert', function () {
alert('子コンポーネントのイベント発火')
})
}
});
const vue = new Vue({
el: '#sample',
methods:{
click(){
this.$refs.child.$emit('alert');
}
}
});
</script>
子コンポーネントでは、createdで$onでイベント検知用にセット
それを親からrefと$refsと$emitを利用して呼び出しています。
##◆スロット
親コンポーネントと子コンポーネントででslotを埋め込むことにより、より部品的に再利用性の高いコンポーネントを作成することが可能です。
<child>
<h1 slot="message">親コンポーネント</h1>
</child>
<section class="child">
<slot name="message">
<h1>子コンポーネント</h1>
</slot>
</section>
これで表示の時はデフォルトは「子コンポーネント」で「親コンポーネント」で文字を上書きしている。
データ変数で渡すことも可能