はじめに
UIフレームワークのelement-ui使ってみました。
今までbootstrapばっかりだったので、ちょっと覚えるの大変だなーと思ってたんですが、そこまで大変じゃなかったです。
表題のdialogはbootstrapでいうmodalですが、こちらも簡単でした。
ただ、nuxtを使用しつつ使う場合に、親コンポーネントとdialog用のコンポーネントと連携でハマっちゃった(初心者だからですが・・・)ので忘れないように記載しときます。
やってみた
TestMain.vue
<template>
<div>
<test-list v-on:onModal="onModal(true)" />
<test-modal
v-bind:dialogTableVisible="dialogTableVisible"
v-on:onModal="onModal(false)"
/>
</div>
</template>
<script>
import TestList from '~/components/test/TestList.vue'
import TestModal from '~/components/test/TestModal.vue'
export default {
layout: 'default',
components: {
TestList,
TestModal
},
data: function() {
return {
dialogTableVisible: false
}
},
methods: {
onModal: function(dialogTableVisible) {
this.dialogTableVisible = dialogTableVisible
}
}
}
</script>
TestList.vue
このvueは例えば、管理画面のデータリストを想定したコンポーネントです。
実際はel-tableでデータのリストを表示して、それぞれのレコードに編集などのボタンが付き、それをdialogで表示するようなイメージです。
<template> <el-row class="test-list-field"> <el-col :span="24"> <el-card class="box-card"> <el-button type="primary" @click="showModal">モーダル表示</el-button> </el-card> </el-col> </el-row> </template> <script> export default { methods: { showModal() { this.$emit('onModal') } } } </script>
TestModal.vue
<template>
<el-dialog
title="テストモーダル"
:visible.sync="$props.dialogTableVisible"
:before-close="hideModal"
>
<span slot="footer" class="dialog-footer">
<el-button type="info" @click="hideModal">モーダル閉じる</el-button>
</span>
</el-dialog>
</template>
<script>
export default {
props: {
dialogTableVisible: {
type: Boolean
}
},
methods: {
hideModal() {
this.$emit('onModal')
}
}
}
</script>

結果、自分の以前の記事で使っていた、親 ⇔ 子の通信部分で使用した方法で行けました。
- propsで、dialogのopen/closeを取り扱うデータを送る
- v-onで親のonModal()をlistenする
- el-dialogの
:before-closeで$emitを実行するメソッドを設定する - クリック時に$emitで子から、カスタムイベントを発火させる
重要なのは3で、これを設定しとかないと、$propsのデータを編集使用してしまうようで、以下のエラーになっちゃいました。
Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "dialogTableVisible"
終わりに
かんたんな話でしたが、とりあえずこのような感じでした。
現場からは以上です。