web-dev-qa-db-ja.com

VueJSのコンポーネントテンプレートからVuetifyダイアログを開く

私はVueJS Vuetifyフレームワーク を使用しており、別のテンプレートからダイアログを開く必要があります-これはコンポーネントテンプレートとしてインポートされます。 MenuボタンinApp.vueクリックすると、モーダルが開きます。私のセットアップは次のとおりです。

  • App.vue =メニューボタン付きのナビゲーションテンプレート
  • Modal.vue =モーダルテンプレート、main.jsでグローバルとしてインポート

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>

ダイアログを開く方法は?

22
Tom

カスタムイベントと 親子通信以外のイベントバス を使用して、ダイアログを開くことができます。

アプリケーションがもう少し複雑になる場合は、 Vuex for state management を使用することをお勧めします。


イベントバスソリューション:

main.jsまたは新しいファイルで、新しいVueインスタンスを作成してエクスポートします。

export const bus = new Vue()

app.vuebusをインポートし、イベントを発行します。

<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>
10
Soleno

イベントバスは不要で、vモデル

更新:

最初にこれに答えたとき、私はその答えを「回避策」として投稿しました。当時は完全に「正しい」とは感じず、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>
53

モーダルを開くか閉じるかを管理できる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>
10
roli roli

シンプルな最小限の作業例

codepen

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はありません。

3
Traxo

最も簡単な方法は次のとおりです。

コンポーネントの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();
  }
2
Marco

App.vuetemplate内にこれを追加

<modal></model>

現在のModal.vueテンプレートをv-btnv-dialogでレンダリングします

その中には、モーダルをクリックするとbutton-Open Dialogが1つ表示されます。

1
Hardik Satasiya