はじめに
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"
終わりに
かんたんな話でしたが、とりあえずこのような感じでした。
現場からは以上です。