【问题标题】:Vue js - Get Answer from Dialog to confirm navigation w/ Vue Router + VuetifyVue js - 从对话框中获取答案以使用 Vue Router + Vuetify 确认导航
【发布时间】:2018-08-09 06:05:19
【问题描述】:

如果我有一个带有 vuetify 对话框的 vue 模板(但实际上是任何对话框),我如何使用它在 vue-router 的 beforeRouteLeave 方法中确认导航离开页面?

dialogTest.vue:

<template>
    <v-container>
        <v-layout>
            <v-dialog v-model="dialog" max-width="290" ref="popup">
                <v-card>
                    <v-card-title class="headline">Are you sure you wish to leave this page?</v-card-title>
                    <v-card-text>Better think long and hard.</v-card-text>
                    <v-card-actions>
                        <v-spacer></v-spacer>
                        <v-btn color="primary darken-1" flat="flat" @click.native="dialog = false">Nah</v-btn>
                        <v-btn color="primary darken-1" flat="flat" @click.native="dialog = false">Yah</v-btn>
                    </v-card-actions>
                </v-card>
            </v-dialog>
        </v-layout>
    </v-container>
</template>

<script src="./dialogTest.ts"></script>

dialogTest.ts:

import Vue from 'vue';
import { Component } from 'vue-property-decorator';

Component.registerHooks([
    'beforeRouteLeave'
]);

@Component
export default class DialogTestComponent extends Vue {

    dialog: boolean = false;

    beforeRouteLeave(to: Object, from: Object, next: Function) {
        console.log('beforeRouteLeave');

        //this works, but obviously doesn't use our dialog -> how do we get yah or nah response from dialog instead?
        const answer =  window.confirm('Do you really want to leave? you have unsaved changes!')
        if (answer) {
            next()
        } else {
            next(false)
        }
    }
}

【问题讨论】:

    标签: vue.js vuejs2 vue-component vue-router vuetify.js


    【解决方案1】:

    如果你不想使用 $refs 并且你的组件中有一个 v-dialog

    模板:

    <v-dialog v-model="openDialog">
       <v-btn @click="dialogResponse(true)">Yes</v-btn>
       <v-btn @click="dialogResponse(false)">No</v-btn>
    </v-dialog>
    

    脚本:

    data() { return { openDialog: false, functionResolve: null } },
    
    beforeRouteLeave(to, from, next) {
        this.openDialog = true
        this.createPromise().then(res => {
          next(res)
        })
    },
    
    methods: {
      createPromise() {
        return new Promise(resolve => {
          this.functionResolve = resolve;
        })
      },
      dialogResponse(response) {
        this.functionResolve(response)
      },
    }
    

    【讨论】:

      【解决方案2】:

      @bbsimonbb - 感谢您的快速回答。

      这是我在 ts 中的决赛:

      在父组件中(包含我们的带有 ref="confirmLeavePopup" 的 ConfirmLeaveDialog 组件):

      async beforeRouteLeave(to: Object, from: Object, next: Function) {
          next(await (this.$refs.confirmLeavePopup as ConfirmLeaveDialog).pop()); 
      }
      

      在 ConfirmLeaveDialog vue 类组件中(我将组件的 resolve func 存储改名为“answer”):

      import Vue from 'vue';
      import { Component, Prop } from 'vue-property-decorator';
      
      @Component
      export default class ConfirmLeaveDialog extends Vue {
      
          @Prop({ default: 'Are you sure you wish to leave this page?' })
          question: any;
      
          active: boolean = false;
          answer: Function = () => { return false }; //. had to provide the type and initialize
      
          pop(): Promise<boolean> {
              this.active = true;
              return new Promise<boolean>((resolve: Function, reject: Function) => { //. note the arrow function here such that 'this' refers to the component, NOT the calling context
                  this.answer = resolve;
              });
          };
      
          confirmLeave(): void {
              this.active = false;
              this.answer(true);
          };
      
          abortLeave(): void {
              this.active = false;
              this.answer(false);
          }
      }
      

      【讨论】:

      • 任何使用 typescript 的 Vuejs 教程链接。
      【解决方案3】:

      我喜欢用承诺来做这件事。给你的对话框一个 pop() 方法来返回一个 promise,然后当你的用户选择时用 true 或 false 来解决这个 promise。或者从您的单元测试中调用 clickYah()。像这样的……

      // in your dialog component....
      data(){
          return {active : false, resolve: null};
      }
      methods : {
          pop(){
              this.active = true;
              return new Promise(function(resolve, reject){
                  this.resolve = resolve;
              });
          },
          clickYah(){
              this.active = false;
              this.resolve(true);
          },
          clickNah(){
              this.active = false;
              this.resolve(false);
          }
      }
      
      // then to call it...
      this.$refs.modalDialog.pop()
      .then(confirmResult => next(confirmResult));
      

      【讨论】:

      • 感谢它对我有用。但是在 pop 函数中,promise 应该是: return new Promise( (resolve, reject) => { this.resolve = resolve }) 。如果你不使用箭头函数,那么 this.resolve 将是未定义的。
      猜你喜欢
      • 2021-03-24
      • 2019-09-22
      • 2019-04-17
      • 2017-05-21
      • 2022-06-15
      • 2022-01-17
      • 2019-07-24
      • 2019-05-24
      • 2020-10-23
      相关资源
      最近更新 更多