0

我正在构建一个 Vue 应用程序。我有两个相互关联的组件。其中一个被调用loginRegister.vue,其代码在这里:

登录注册.vue:

<template>
<BaseModal idBtn = "regis" btnOneText="Cancel" :btnTwoText="button2Text['register']" v-show="showModal1" @close="showModal1 = false" @submitForm="registerUser(regLogPara['register'])" :popoverVue = "showToolTip.register">
            <!-- the material that must be shown in modal comes here. it is better to use bootstrap "card" classes for compatible design -->
            <!-- ################ -->
            <!-- transition part -->
            <!-- ################ -->
  <transition name="fade">
    <div v-if="modalAlert==='form'" key="item1">
      <h4 class="card-title text-center my-3">Create Your Account</h4>
    </div>
    <!-- showing success message -->
    <div v-else-if="modalAlert==='success'" key="item2">
      <p>you succeed</p>
    </div>
    <!-- showing error message -->
    <div v-else key="item3">
      <p>there is an error!</p>
    </div>
  </transition>
</BaseModal>
</template>

<script>
import BaseButton from './BaseButton.vue';
import BaseInput from './BaseInput.vue'
import BaseModal from './BaseModal.vue';
import { onMounted, reactive, ref } from 'vue';


export default {
  name: "loginRegister",
  components: {
    BaseModal,
    BaseButton,
    BaseInput
  },

  setup(props) {
    const showModal = ref(false);
    const showModal1 = ref(false);
    const modalAlert = ref("form");
    
    const registerUser = async (checkPara) => {
      /* This function is responsible for sending form data to backend and getting the result from backend */
      if (checkPara == "reset") {
        /* for showing form again if there is a back-end error */
        console.log("reset form");
        modalAlert.value = "form";
        button2Text["login"] = "Submit";
        button2Text["register"] = "Submit";
        regLogPara["login"] = "login";
        regLogPara["register"] = "register";
      } else {
        /* for submiting form */
        modalAlert.value = "error";
        button2Text[checkPara] = "Try again";
        regLogPara[checkPara] = "reset";
        console.log("register function");
      }
    }
    
  return {
      registerUser,
      showModal,
      showModal1,
      validation,
      blurInput,
      loginValid,
      registerValid,
      finalCheck,
      showToolTip,
      store,
      modalAlert,
      button2Text,
      regLogPara
    }
  }
};
</script>

另一个调用BaseModal.vue,代码在这里:

BaseModal.vue:

<template>
  <div class="modal-overlay container-fluid p-0">
    <div class="row align-items-center justify-content-center" @click.self="$emit('close')">
      <div class="col-md-6">
        <div class="card">
          <div class="card-body">
            <!-- text and other html comes here in the slot -->
            <!-- ############## -->
            <!-- this is the slot part -->
            <!-- ############## -->
            <slot></slot>
            <div class="card-footer d-flex justify-content-around align-items-center">
              <base-button 
              large
              v-if="btnOneText"
              kind = "btn-secondary"
              :textBtn = "btnOneText" 
              @click="$emit('close')"
              >
              </base-button>

              <base-button 
              large
              v-if="btnTwoText"
              kind = "btn-secondary"
              :textBtn = "btnTwoText" 
              @click="popoverFunc"
              @blur="popoverDisable"
              :id="idBtn"
              >
              </base-button>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import BaseButton from './BaseButton.vue';
import bootstrap from "bootstrap/dist/js/bootstrap.bundle.min.js";

export default {
  // $emit('submitForm'),
  name: "BaseModal",
  props: {
    btnOneText: {
      type: String
    },
    btnTwoText: {
      type: String
    },
    popoverVue: {
      type: Boolean
    },
    idBtn: {
      type: String
    }
  },
  computed: {
    popOverData: function () {
      return this.popoverVue;
    },
    popVar: function() {
      return new bootstrap.Popover(document.getElementById(this.idBtn), {
            trigger: "manual",
            title: "Notice:",
            content: "Please fill all fields in the correct way to submit your information!",
            customClass: "myPopover",
            placement: "top"
          })
    }
  },
  data() {
      return {
          showPopOver: false
      }
  },
  emits: ["close", "submitForm"],
  components: {
    BaseButton
  },
  watch: {
    popOverData: function (newState, oldState) {
      if(newState === true) {
        this.showPopOver = true;
        this.popoverFinal();
      } else {
        this.showPopOver = false;
        this.popoverFinal();
      }
    }
  },
  methods: {
    popoverFunc: function() {
      this.$emit('submitForm');
      if (this.popOverData) {
        this.showPopOver = true;
        this.popoverFinal();
      }
    },
    popoverDisable: function() {
      console.log("popoverDisable");
      this.showPopOver = false;
      this.popoverFinal();
    },
    popoverFinal: function() {
      console.log(this.showPopOver);
      /* this function is responsible for showing and hiding the popover according to "showPopOver" data */
      if (this.showPopOver) {
        this.popVar.show();
      } else {
        this.popVar.hide();
      }
    }
  }
  
};
</script>

<style scoped src="../assets/css/compoStyles/baseModal.css"></style>

有一些代码与这个问题无关,我也试图简化代码并澄清与我的组件代码相关的transition部分slot

尽管代码可能看起来很长或很复杂,但我想要达到的目标很简单。我想在模态组件中提交注册表单。实际上,我的应用程序中的用户单击注册按钮,然后BaseModal.vue显示该组件。在这种情况下,注册表单(为简单起见,我用h4标签代替)是用户可以看到的默认内容。根据流程成功或出现错误提交表单后,我想向用户显示一条消息并将按钮的文本从提交更改为如果出现错误重试。之后,当用户单击try again按钮时,表单(h4标签)必须再次淡入。所以我在我的组件中尝试了v-if/v-else-if/v-elseVue 的结构。loginRegister.vue我使用的代码transition part与使用Vue文档的代码类似,但转换无法正常工作。在我的本地开发环境中,h4标签顺利消失,然后再次单击标签淡入后try again没有显示任何消息。h4同样在控制台中我可以看到这个警告:

[Vue warn]: <transition> can only be used on a single element or component. Use <transition-group> for lists. 
  at <BaseTransition mode=undefined appear=false persisted=false  ... > 
  at <Transition name="fade" > 
  at <BaseModal idBtn="regis" btnOneText="Cancel" btnTwoText="Try again"  ... > 
  at <LoginRegister> 
  at <App>

但我认为这与我的问题无关,因为我没有在我的应用程序的多元素上使用过渡。那么有人可以帮我看看我的代码有什么问题吗?

4

1 回答 1

0

似乎您希望 baseModal.vue 位于 loginRegister.vue 中,并且 baseModal 在某些状态发生变化时进行某种转换?试试<transition></transition>改成<transition-group></transition-group>

于 2022-02-07T15:39:36.007 回答