私はVueJS Vuetifyフレームワーク を使用しており、別のテンプレートからダイアログを開く必要があります-これはコンポーネントテンプレートとしてインポートされます。 MenuボタンinApp.vueクリックすると、モーダルが開きます。私のセットアップは次のとおりです。
main.js
import Modal from './components/Modal.vue'
Vue.component('modal', Modal)
Modal.vueテンプレート:
<template>
<v-layout row justify-center>
<v-btn color="primary" dark @click.native.stop="dialog = true">Open Dialog</v-btn>
<v-dialog v-model="dialog" max-width="290">
<v-card>
<v-card-title class="headline">Use Google's location service?</v-card-title>
<v-card-text>Let Google help apps determine location. This means sending anonymous location data to Google, even when no apps are running.</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="green darken-1" flat="flat" @click.native="dialog = false">Disagree</v-btn>
<v-btn color="green darken-1" flat="flat" @click.native="dialog = false">Agree</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</v-layout>
</template>
<script>
export default {
data () {
return {
dialog: false
}
}
}
</script>
ダイアログを開く方法は?
カスタムイベントと 親子通信以外のイベントバス を使用して、ダイアログを開くことができます。
アプリケーションがもう少し複雑になる場合は、 Vuex for state management を使用することをお勧めします。
イベントバスソリューション:
main.jsまたは新しいファイルで、新しいVueインスタンスを作成してエクスポートします。
export const bus = new Vue()
app.vueでbus
をインポートし、イベントを発行します。
<template>
<div>
<button @click.prevent="openMyDialog()">my button</button>
</div>
</template>
<script>
import {bus} from '../main' // import the bus from main.js or new file
export default {
methods: {
openMyDialog () {
bus.$emit('dialog', true) // emit the event to the bus
}
}
}
</script>
modal.vueでもバスをインポートし、作成されたフックでイベントをリッスンします。
<script>
import {bus} from '../main'
export default {
created () {
var vm = this
bus.$on('dialog', function (value) {
vm.dialog = value
})
}
}
</script>
最初にこれに答えたとき、私はその答えを「回避策」として投稿しました。当時は完全に「正しい」とは感じず、Vue.jsを初めて使用したからです。 v-modelディレクティブを使用してダイアログを開いたり閉じたりしたかったのですが、そこに到達できませんでした。しばらくして、 ドキュメントでこれを行う方法 を見つけ、入力イベントとvalue property、そしてこれがイベントバスなしでそれを行うべきだと思う方法です。
親コンポーネント:
<template>
<v-btn color="accent" large @click.stop="showScheduleForm=true">
<ScheduleForm v-model="showScheduleForm" />
</template>
<script>
import ScheduleForm from '~/components/ScheduleForm'
export default {
data () {
return {
showScheduleForm: false
}
},
components: {
ScheduleForm
}
}
</script>
子コンポーネント(ScheduleForm):
<template>
<v-dialog v-model="show" max-width="500px">
<v-card>
<v-card-actions>
<v-btn color="primary" flat @click.stop="show=false">Close</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>
<script>
export default {
props: {
value: Boolean
},
computed: {
show: {
get () {
return this.value
},
set (value) {
this.$emit('input', value)
}
}
}
}
</script>
グローバルイベントバスを必要とせずに、これを回避できました。
ゲッターとセッターで計算されたプロパティを使用しました。 Vueは親プロパティを直接変更することについて警告するので、セッターでは単に親にイベントを発行しました。
コードは次のとおりです。
親コンポーネント:
<template>
<v-btn color="accent" large @click.stop="showScheduleForm=true">
<ScheduleForm :visible="showScheduleForm" @close="showScheduleForm=false" />
</template>
<script>
import ScheduleForm from '~/components/ScheduleForm'
export default {
data () {
return {
showScheduleForm: false
}
},
components: {
ScheduleForm
}
}
</script>
子コンポーネント(ScheduleForm):
<template>
<v-dialog v-model="show" max-width="500px">
<v-card>
<v-card-actions>
<v-btn color="primary" flat @click.stop="show=false">Close</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>
<script>
export default {
props: ['visible'],
computed: {
show: {
get () {
return this.visible
},
set (value) {
if (!value) {
this.$emit('close')
}
}
}
}
}
</script>
モーダルを開くか閉じるかを管理できるVuex、Event Bus、Propsなど、さまざまな方法があります。
.sync
修飾子を使用して私のお気に入りの方法を紹介します。
最初に質問(コード部分)を簡略化します
親コンポーネント
<template>
<div>
<button @click="dialog=true">Open Dialog</button>
<Child :dialog.sync="dialog" />
</div>
</template>
<script>
import Child from './Child.vue'
export default {
components: {
Child
},
data: {
return {
dialog: false
}
}
}
</script>
子(ダイアログ)コンポーネント
<template>
<v-layout row justify-center>
<v-dialog v-model="dialog" persistent max-width="290">
<v-card>
<v-card-title class="headline">Use Google's location service?</v-card-title>
<v-card-text>Let Google help apps determine location. This means sending anonymous location data to Google, even when no apps are running.</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="green darken-1" flat @click.native="close">Close</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</v-layout>
</template>
<script>
export default {
props: {
dialog: {
default: false
}
},
methods: {
close() {
this.$emit('update:dialog', false)
}
}
}
</script>
value
propをvalue
としてv-dialog
コンポーネントに渡し、子ダイアログからinput
イベントを閉じたいときにいつでも発行します。
//CustomDialog.vue
<v-dialog :value="value" @input="$emit('input')">
<v-btn color="red" @click.native="$emit('input')">Close</v-btn>
</v-dialog>
...
props:['value']
親にv-modelを追加します
//Parent.vue
<custom-dialog v-model="dialog">
したがって、カスタムイベントバス、data
、_watch
、_computed
はありません。
最も簡単な方法は次のとおりです。
コンポーネントのdata()で、属性、たとえばダイアログを返します。
コンポーネントを含めると、コンポーネントタグへの参照を設定できます。例えば。:
import Edit from '../payment/edit.vue';
<edit ref="edit_reference"></edit>
次に、コンポーネント内でメソッドを設定しました:
open: function () {
var vm = this;
vm.dialog = true;
}
最後に、私は親からそれを呼び出すことができます:
editar(item)
{
var vm = this;
vm.$refs.edit_reference.open();
}
App.vue
template
内にこれを追加
<modal></model>
現在のModal.vue
テンプレートをv-btn
とv-dialog
でレンダリングします
その中には、モーダルをクリックするとbutton
-Open Dialog
が1つ表示されます。