从VueJS中的组件模板打开Vuetify对话框

Tom*_*Tom 26 javascript vue-component vuejs2 vuetify.js

我正在使用VueJS Vuetify框架,我需要从另一个模板打开一个对话框 - 它作为组件模板导入.单击App.vue中Menu按钮后,Modal应该打开.这是我的设置:

  • App.vue =带菜单按钮的导航模板
  • Modal.vue =模态模板,在main.js中作为全局导入

main.js

import Modal from './components/Modal.vue'
Vue.component('modal', Modal)
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

如何打开对话框?

Mat*_*zol 58

不需要事件总线和v-model

更新:

当我第一次回答这个问题时,我把答案称为"解决方法",因为它当时并没有完全"正确",而且我是Vue.js的新手.我想通过使用v-model指令打开或关闭对话框,但我无法到达那里.过了一段时间,我发现如何在文档中使用输入事件值属性,这就是我认为应该在没有事件总线的情况下完成的.

父组件:

<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>
Run Code Online (Sandbox Code Playgroud)

子组件(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>
Run Code Online (Sandbox Code Playgroud)

原始答案:

我能够在不需要全局事件总线的情况下解决这个问题.

我使用了一个带有getter和setter的计算属性.由于Vue警告你直接改变父属性,因此在setter中我只是向父节点发出了一个事件.

这是代码:

父组件:

<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>
Run Code Online (Sandbox Code Playgroud)

子组件(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>
Run Code Online (Sandbox Code Playgroud)

  • 在我看来,这是最好的解决方案。无需活动巴士! (3认同)
  • 我认为这是绝对完美的答案。谢谢。这很完美! (2认同)
  • 试过了,它可以根据需要工作。最好把这个带到顶部! (2认同)
  • 如果上述方法不起作用,请将您孩子的计算属性更改为使用 $attrs,如下所示: `show: { get () { return this.$attrs.value }, set (value) { this.$emit('input' , 值) } }` (2认同)

rol*_*oli 11

有很多方法可以做到这一点,比如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>
Run Code Online (Sandbox Code Playgroud)

子(对话)组件

<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>
Run Code Online (Sandbox Code Playgroud)


Sol*_*eno 10

您可以使用自定义事件打开对话框,并使用事件总线进行非父子通信.

如果您的应用程序变得更复杂,我建议您使用Vuex进行状态管理.


活动总线解决方案

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>
Run Code Online (Sandbox Code Playgroud)

modal.vue中还导入总线并在创建的钩子中侦听事件:

<script>
  import {bus} from '../main'    
  export default {
    created () {
      var vm = this
      bus.$on('dialog', function (value) {
        vm.dialog = value
      })
    }
  }
</script>
Run Code Online (Sandbox Code Playgroud)

  • 哦对不起!我更正了答案!当然,我们必须以“调制”版本导出和导入总线。为了避免再次混乱,我还测试了代码:)再次抱歉,我对此不满意。 (2认同)

Tra*_*axo 5

简单的最小工作示例

码笔

valueprop 传递valuev-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']
Run Code Online (Sandbox Code Playgroud)

并添加v模型到您的父母

//Parent.vue
<custom-dialog v-model="dialog">
Run Code Online (Sandbox Code Playgroud)

所以没有自定义事件总线,不data,不watch,不computed