Inhaltsverzeichnis
Warum haben Sie diese Idee?
要封装什么
封装Dialog
header
Footer
Content
剩下一些细节处理
DialogCmp1
封装hooks
useDialog
useDialog Demo
useDialogState 和 useDialogWithForm
useDialogState
useDialogWithForm
useDialogWithForm Demo
仓库地址
Heim Web-Frontend View.js Lassen Sie uns darüber sprechen, wie Sie mit Vue3+Hook Popup-Komponenten schneller und effizienter schreiben können

Lassen Sie uns darüber sprechen, wie Sie mit Vue3+Hook Popup-Komponenten schneller und effizienter schreiben können

Dec 28, 2022 pm 08:55 PM
vue vue3

Lassen Sie uns darüber sprechen, wie Sie mit Vue3+Hook Popup-Komponenten schneller und effizienter schreiben können

Warum haben Sie diese Idee?

Im Entwicklungsprozess des Management-Backends sind zu viele Pop-up-Business-Pop-ups beteiligt, von denen die häufigsten „XX-Daten hinzufügen“ und „XX-Daten bearbeiten“ sind „, „XX detaillierte Daten anzeigen“ und andere Popup-Fenstertypen sind am häufigsten. [Verwandte Empfehlungen: vuejs-Video-Tutorial, Web-Front-End-Entwicklung]

Viele der Codes für diese Popup-Komponenten sind gleich, z. B. Komponentenstatus, Methoden im Zusammenhang mit Formularkomponenten ...

Also , I einfach Die sekundäre Kapselung und Hooks der Dialog-Komponente reduzieren einige wiederholte CodesDialog组件进行的二次封装和hooks,减少了一些重复的代码

要封装什么

如果是普通弹窗使用的话,直接使用el-dialog组件已经足够了

但我还是一个比较爱折腾的人,我们先看看官方dialog文档有什么可以添加的功能

...

大概看了一下,我打算封装一下功能

  • 提供全屏操作按钮(右上角)
  • 默认提供“确认”,“关闭”按钮
  • 内部添加Loading效果

封装Dialog

确定了要封装的功能之后,先来一个简单的dialog组件。

把双向绑定处理一下,这样外部就可以直接通过v-model直接控制弹窗了。

<template>
    <el-dialog :model-value="props.modelValue"></el-dialog>
</template>
<script setup>
interface PropsType {
  modelValue?: boolean;
}

const props = withDefaults(defineProps<PropsType>(), {
  modelValue: false,
});

const emits = defineEmits<{
  (e: "update:modelValue"): void;
}>();
</script>
Nach dem Login kopieren

这里使用到图标库@element-plus/icons-vue

如没有安装,请执行npm install @element-plus/icons-vue

使用el-dialog提供的header插槽,将全屏图表和关闭图标放置到右上角中。给el-dialog传递show-close属性关闭默认图标。

<template>
  <el-dialog :model-value="props.modelValue" :show-close="false">
    <template #header>
      <div>
        <span>{{ props.title }}</span>
      </div>
      <div>
        <el-icon><FullScreen /></el-icon>
        <el-icon><Close /></el-icon>
      </div>
    </template>
  </el-dialog>
</template>
<script setup>
import { FullScreen, Close } from "@element-plus/icons-vue";
</script>
<style scoped>
// 处理样式
:deep(.el-dialog__header) {
  border-bottom: 1px solid #eee;
  display: flex;
  padding: 12px 16px;
  align-items: center;
  justify-content: space-between;
  margin: 0;
}
.dialog-title {
  line-height: 24px;
  font-size: 18px;
  color: #303133;
}
.btns {
  display: flex;
  align-items: center;
  i {
    margin-right: 8px;

    font-size: 16px;
    cursor: pointer;
  }
  i:last-child {
    margin-right: 0;
  }
}
</style>
Nach dem Login kopieren

弹窗的标题文字内容通过props进行传递,默认为空(&#39;&#39;

<script lang="ts" setup>
interface PropsType {
  // 忽略之前的代码
  title?: string;
}

const props = withDefaults(defineProps<PropsType>(), {
  title: "",
});

</script>
Nach dem Login kopieren

我们看看现在头部的效果(这里没传入标题,默认为&#39;&#39;

Lassen Sie uns darüber sprechen, wie Sie mit Vue3+Hook Popup-Komponenten schneller und effizienter schreiben können

现在这个按钮只有样式效果,还没有写上对应的功能 ~

给他们先绑定上对应的事件和指令

<template>
    <el-dialog
    :model-value="props.modelValue"
    :show-close="false"
    :fullscreen="attrs?.fullscreen ?? isFullscreen"
    >
        <template #header>
        <div>
            <span class="dialog-title">{{ props.title }}</span>
        </div>
        <div class="btns">
            <el-icon v-if="isFullScreenBtn" @click="handleFullscreen"
            ><FullScreen
            /></el-icon>
            <el-icon @click="handleClose"><Close /></el-icon>
        </div>
        </template>
    </el-dialog>
</template>
<script setup lang="ts">
import { FullScreen, Close } from "@element-plus/icons-vue";

interface PropsType {
  title?: string;
  modelValue?: boolean;
  hiddenFullBtn?: boolean;
}

const props = withDefaults(defineProps<PropsType>(), {
  title: "",
  modelValue: false,
  hiddenFullBtn: false,
});

const emits = defineEmits<{
  (e: "update:modelValue"): void;
  (e: "close"): void;
}>();

// 当前是否处于全屏状态
const isFullscreen = ref(false);
// 是否显示全屏效果图标
const isFullScreenBtn = computed(() => {
  if (props.hiddenFullBtn) return false;
  if (attrs?.fullscreen) return false;
  return true;
});

// 开启、关闭全屏效果
const handleFullscreen = () => {
  if (attrs?.fullscreen) return;
  isFullscreen.value = !isFullscreen.value;
};

// 关闭弹窗时向外部发送close事件
const handleClose = () => {
  emits("close");
};
</script>
Nach dem Login kopieren

再点击下全屏图标看看效果怎么样

Lassen Sie uns darüber sprechen, wie Sie mit Vue3+Hook Popup-Komponenten schneller und effizienter schreiben können

NICE 头部功能也就完成了

接下来,再处理下底部内容,默认提供两个按钮,分别是“确定”和“关闭”,这个名称也是可以通过props属性修改的。

两个按钮绑定点击事件,向外发送不同的事件。

<template>
  <div class="">
    <el-dialog
      v-bind="attrs"
      :model-value="props.modelValue"
      :show-close="false"
      :fullscreen="attrs?.fullscreen ?? isFullscreen"
    >
      <template #footer>
        <!-- 如果没有提供其他footer插槽,就使用默认的 -->
        <span v-if="!slots.footer" class="dialog-footer">
          <el-button type="primary" @click="handleConfirm">{{
            props.confirmText
          }}</el-button>
          <el-button @click="handleClose">{{ props.cancelText }}</el-button>
        </span>
        <!-- 使用传入进来的插槽 -->
        <slot v-else name="footer"></slot>
      </template>
    </el-dialog>
  </div>
</template>
<script setup lang="ts">
import { useSlots } from "vue";
// 获取插槽
const slots = useSlots();
interface PropsType {
    title?: string;
    width?: string | number;
    isDraggable?: boolean;
    modelValue?: boolean;
    hiddenFullBtn?: boolean;
    confirmText?: string;
    cancelText?: string;
}

const props = withDefaults(defineProps<PropsType>(), {
    title: "",
    isDraggable: false,
    modelValue: false,
    hiddenFullBtn: false,
    confirmText: "确认",
    cancelText: "关闭",
});
const handleClose = () => {
    emits("close");
};
const handleConfirm = () => {
    emits("confirm");
};
</script>
Nach dem Login kopieren

Lassen Sie uns darüber sprechen, wie Sie mit Vue3+Hook Popup-Komponenten schneller und effizienter schreiben können

又搞定了一部分了,就剩下Content了 ~

Content

弹窗内容通过默认插槽的方式传入进来,在外层的div元素上添加v-loading标签,实现加载态。

如果你想整个弹窗实现loading效果,请把v-loading移到最外层元素即可。 注意不能是el-dialog元素上,否则无法实现 可能是el-dialog使用了teleport组件,导致v-loading无法正常工作。 等有空研究一下 ~

<template>
  <div class="">
    <el-dialog
      v-bind="attrs"
      :model-value="props.modelValue"
      :show-close="false"
      :fullscreen="attrs?.fullscreen ?? isFullscreen"
    >
        <div class="content" v-loading="props.loading">
            <slot></slot>
        </div>
    </el-dialog>
  </div>
</template>
<script lang="ts" setup>
interface PropsType {
  loading?: boolean;
}

const props = withDefaults(defineProps<PropsType>(), {
  loading: false,
});

</script>
Nach dem Login kopieren

试试看中间的loading效果

Lassen Sie uns darüber sprechen, wie Sie mit Vue3+Hook Popup-Komponenten schneller und effizienter schreiben können

剩下一些细节处理

el-dialog组件提供了很多个props属性供用户选择,但我们现在封装的dialog组件只使用到了一小部分props属性。当用户想要使用其他的props属性时该怎么办?

例如使用width属性时,难道要在我们封装的组件中接收props.width再传递给<el-dialog :width="props.width" />组件吗?

不不不,还有另外一种方法,还记得刚刚在做全屏操作的时候使用到的useAttrs辅助函数吗

它可以获取当前组件传递进来的属性。有了这个方法之后,再配合并即可将外部传递进来的函数再传递到el-dialog组件上面啦

<el-dialog
    v-bind="attrs"
    :model-value="props.modelValue"
    :show-close="false"
    :fullscreen="attrs?.fullscreen ?? isFullscreen"
    :before-close="handleClose"
>
    <!-- 忽略其他代码 -->
</el-dialog>
Nach dem Login kopieren

为了避免内部传递的props被覆盖掉,v-bind="attrs"需要放在最前面

在使用时,可能会给before-close属性传递一个函数,但到了后面被内部的handleClose

Was zu kapseln ist

🎜Wenn Wenn Es wird für gewöhnliche Popup-Fenster verwendet. Es reicht aus, die el-dialog-Komponente direkt zu verwenden. Aber ich bin immer noch eine Person, die gerne herumspielt. Werfen wir einen Blick auf die offizielle < code>dialog Dokumentieren Sie zuerst, welche Funktionen hinzugefügt werden können rechte Ecke)
  • Stellen Sie standardmäßig die Schaltfläche „Bestätigen“ bereit.
  • Fügen Sie den Ladeeffekt intern hinzu
  • Encapsulate Dialog🎜🎜Confirm to encapsulate Nach der Funktion beginnen wir mit einer einfachen dialog-Komponente. 🎜🎜 Verarbeiten Sie die bidirektionale Bindung so, dass die Außenseite das Popup-Fenster direkt über v-model steuern kann. 🎜
    const handleClose = () => {
      if (
        Reflect.has(attrs, "before-close") &&
        typeof attrs["before-close"] === "function"
      ) {
        attrs["before-close"]();
      }
      emits("close");
    };
    Nach dem Login kopieren
    Nach dem Login kopieren

    header🎜
    🎜Hier wird die Icon-Bibliothek @element-plus/icons-vue verwendet🎜
    🎜Wenn diese nicht installiert ist, bitte Führen Sie npm install @element-plus/icons-vue aus🎜
    🎜Verwenden Sie den von el-dialog bereitgestellten header-Slot, um das Vollbilddiagramm und das Schließsymbol zu platzieren in der oberen rechten Ecke. Übergeben Sie das Attribut show-close an el-dialog, um das Standardsymbol zu schließen. 🎜
    import { ref } from "vue";
    
    export default function useDialog() {
      const visible = ref(false);
      const loading = ref(false);
      const openDialog = () => (visible.value = true);
      const closeDialog = () => (visible.value = false);
      const openLoading = () => (loading.value = true);
      const closeLoading = () => (loading.value = false);
      return {
        visible,
        loading,
        openDialog,
        closeDialog,
        openLoading,
        closeLoading,
      };
    }
    Nach dem Login kopieren
    Nach dem Login kopieren
    🎜Der Inhalt des Titeltextes des Popup-Fensters wird über props weitergeleitet und der Standardwert ist leer ('') 🎜
    <template>
    <el-button @click="openDialog1">普通弹窗</el-button>
    <DialogCmp
      title="DialogCmp1"
      :hiddenFullBtn="true"
      v-model="visible1"
      @confirm="handleConfirm"
      @close="handleClose"
    >
      <h3 id="DialogCmp">DialogCmp1</h3>
    </DialogCmp>
    </template>
    <script setup lang="ts">
    import useDialog from "./components/useDialog";
    import DialogCmp from "./components/Dialog.vue";
    
    const {
      visible: visible1,
      openDialog: openDialog1,
      closeDialog: closeDialog1,
    } = useDialog();
    </script>
    Nach dem Login kopieren
    Nach dem Login kopieren
    🎜Werfen wir einen Blick darauf Wirkung des aktuellen Kopfes (hier nicht übergeben) Geben Sie den Titel ein, der Standard ist '')🎜🎜Lassen Sie uns darüber sprechen, wie Sie mit Vue3+Hook Popup-Komponenten schneller und effizienter schreiben können🎜🎜Jetzt hat diese Schaltfläche nur noch Stileffekte und die entsprechende Funktion wurde noch nicht geschrieben~🎜🎜Binden Sie die entsprechenden Ereignisse und Anweisungen für sie zuerst🎜
    export enum MODE {
      ADD,  EDIT,
    }
    Nach dem Login kopieren
    Nach dem Login kopieren
    🎜 Klicken Sie dann auf das Vollbildsymbol. Mal sehen, wie es funktioniert🎜🎜Lassen Sie uns darüber sprechen, wie Sie mit Vue3+Hook Popup-Komponenten schneller und effizienter schreiben können🎜🎜NICE Die Header-Funktion ist jetzt abgeschlossen🎜

    Footer🎜🎜Als nächstes verarbeiten Sie den unteren Inhalt werden standardmäßig bereitgestellt, nämlich „OK“ und „Close“. Dieser Name kann auch über das Attribut props geändert werden. 🎜🎜Zwei Schaltflächen binden Klickereignisse und senden verschiedene Ereignisse aus. 🎜
    import { ref } from "vue";
    import { MODE } from "./types";
    export default function useDialogState() {
      const mode = ref<MODE>(MODE.ADD);
      const visible = ref(false);
      const updateMode = (target: MODE) => {
        mode.value = target;
      };
      return { mode, visible, updateMode };
    }
    Nach dem Login kopieren
    Nach dem Login kopieren
    🎜Lassen Sie uns darüber sprechen, wie Sie mit Vue3+Hook Popup-Komponenten schneller und effizienter schreiben können🎜🎜 Ein weiterer Teil ist erledigt, nur der Inhalt bleibt übrig~🎜

    Content🎜🎜Der Popup-Inhalt wird über den Standard-Slot übergeben und der äußere div</ hinzugefügt <code>v-loading-Tag zum Code>-Element hinzufügen, um den Ladezustand zu erreichen. 🎜
    🎜Wenn Sie möchten, dass das gesamte Popup-Fenster den Ladeeffekt erzielt, verschieben Sie das V-Laden bitte auf das äußerste Element. Beachten Sie, dass es sich nicht auf dem El-Dialog-Element befinden darf, da es sonst nicht implementiert werden kann. Es kann sein, dass el-dialog die Teleport-Komponente verwendet, was dazu führt, dass das Laden von V-Dateien nicht richtig funktioniert. Studieren Sie es, wenn Sie Zeit haben~🎜
    import { FormInstance } from "element-plus";
    import { Ref, ref } from "vue";
    import { MODE } from "./types";
    import useDialogState from "./useDialogState";
    
    export default function useDialogFn(
      formInstance: Ref<FormInstance>
    ) {
      const { visible, mode, updateMode } = useDialogState();
    
      const closeDialog = () => {
        formInstance.value.resetFields();
        visible.value = false;
      };
      const openDialog = (target: MODE) => {
        updateMode(target);
        visible.value = true;
      };
      return { visible, mode, openDialog, closeDialog };
    }
    Nach dem Login kopieren
    Nach dem Login kopieren
    🎜Versuchen Sie, den loading-Effekt in der Mitte zu sehen🎜🎜Lassen Sie uns darüber sprechen, wie Sie mit Vue3+Hook Popup-Komponenten schneller und effizienter schreiben können🎜

    Es sind noch einige Details zu klären 🎜🎜 in el-dialogDie Komponente stellt viele props-Attribute zur Auswahl für Benutzer bereit, aber die dialog-Komponente, die wir derzeit kapseln, verwendet nur einen kleinen Teil davon die Eigenschaft props. Was sollte der Benutzer tun, wenn er andere props-Eigenschaften verwenden möchte? 🎜🎜Müssen wir beispielsweise bei Verwendung des width-Attributs props.width in unserer gekapselten Komponente empfangen und es dann an <el-dialog :width="props.width" übergeben? " />< /code> Komponente?🎜🎜Nein, nein, es gibt einen anderen Weg. Erinnern Sie sich an die Hilfsfunktion <code>useAttrs, die Sie gerade beim Vollbildbetrieb verwendet haben?🎜🎜Sie kann den Strom abrufen Komponentenübertragung Kommen Sie in Eigenschaften. Mit dieser Methode können Sie dann zusammenarbeiten und die von außen übergebenen Funktionen an die el-dialog-Komponente übergeben🎜
    <template>
      <Dialog
        :before-close="customClose"
        @confirm="confirm"
        v-model="visible"
        :title="mode == MODE.ADD ? &#39;添加数据&#39; : &#39;编辑信息&#39;"
        :confirm-text="mode == MODE.ADD ? &#39;添加&#39; : &#39;修改&#39;"
      >
        <el-form
          label-width="100px"
          :model="formData"
          ref="formDataRef"
          style="max-width: 460px"
          :rules="rules"
        >
          <el-form-item label="姓名" prop="name">
            <el-input v-model="formData.name" />
          </el-form-item>
          <el-form-item label="年龄" prop="age">
            <el-input v-model="formData.age" />
          </el-form-item>
          <el-form-item label="手机号码" prop="mobile">
            <el-input v-model="formData.mobile" />
          </el-form-item>
        </el-form>
      </Dialog>
    </template>
    <script setup>
    import { ElMessage, FormInstance } from "element-plus";
    import { Ref, ref } from "vue";
    import Dialog from "./Dialog.vue";
    import { MODE } from "./types";
    import useDialogWithForm from "./useDialogWithForm";
    
    const rules = {
      name: {
        type: "string",
        required: true,
        pattern: /^[a-z]+$/,
        trigger: "change",
        message: "只能是英文名称哦",
        transform(value: string) {
          return value.trim();
        },
      },
      age: {
        type: "string",
        required: true,
        pattern: /^[0-9]+$/,
        trigger: "change",
        message: "年龄只能是数字哦",
        transform(value: string) {
          return value.trim();
        },
      },
      mobile: {
        type: "string",
        required: true,
        pattern:
          /^(?:(?:\+|00)86)?1(?:(?:3[\d])|(?:4[5-79])|(?:5[0-35-9])|(?:6[5-7])|(?:7[0-8])|(?:8[\d])|(?:9[189]))\d{8}$/,
        trigger: "change",
        message: "请输入正确的手机号码",
        transform(value: string) {
          return value.trim();
        },
      },
    };
    
    interface FromDataType {
      name: string;
      age: string;
      mobile: string;
    }
    
    const formDataRef = ref<FormInstance | null>(null);
    
    let formData = ref<FromDataType>({
      name: "",
      age: "",
      mobile: "",
    });
    
    const { visible, closeDialog, openDialog, mode } = useDialogWithForm(
      formDataRef as Ref<FormInstance>
    );
    const confirm = () => {
      if (!formDataRef.value) return;
      formDataRef.value.validate((valid) => {
        if (valid) {
          console.log("confirm");
          ElMessage({
            message: "提交成功",
            type: "success",
          });
          closeDialog();
        }
      });
    };
    
    const customClose = () => {
      ElMessage({
        message: "取消提交",
        type: "info",
      });
      closeDialog();
    };
    defineExpose({
      closeDialog,
      openDialog,
    });
    </script>
    <style scoped></style>
    Nach dem Login kopieren
    Nach dem Login kopieren
    🎜Um zu verhindern, dass die intern übergebenen Requisiten überschrieben werden, v-bind="attrs" muss vorne platziert werden🎜
    🎜Bei Verwendung kann eine Funktion an das Attribut before-close übergeben werden, dies wird jedoch der Fall sein Die interne Methode handleClose wird überschrieben. 🎜

    解决方案是在handleClose函数中,获取attrs.[&#39;before-close&#39;]属性,如果类型是函数函数,先执行它。

    const handleClose = () => {
      if (
        Reflect.has(attrs, "before-close") &&
        typeof attrs["before-close"] === "function"
      ) {
        attrs["before-close"]();
      }
      emits("close");
    };
    Nach dem Login kopieren
    Nach dem Login kopieren

    有关于el-dialog组件的封装就到这里了

    封装hooks

    利用Vue composition Api再封装一下在使用el-dialog组件状态的管理hook

    useDialog

    简单处理显示和加载态开关的hook

    import { ref } from "vue";
    
    export default function useDialog() {
      const visible = ref(false);
      const loading = ref(false);
      const openDialog = () => (visible.value = true);
      const closeDialog = () => (visible.value = false);
      const openLoading = () => (loading.value = true);
      const closeLoading = () => (loading.value = false);
      return {
        visible,
        loading,
        openDialog,
        closeDialog,
        openLoading,
        closeLoading,
      };
    }
    Nach dem Login kopieren
    Nach dem Login kopieren

    useDialog Demo

    Lassen Sie uns darüber sprechen, wie Sie mit Vue3+Hook Popup-Komponenten schneller und effizienter schreiben können

    <template>
    <el-button @click="openDialog1">普通弹窗</el-button>
    <DialogCmp
      title="DialogCmp1"
      :hiddenFullBtn="true"
      v-model="visible1"
      @confirm="handleConfirm"
      @close="handleClose"
    >
      <h3 id="DialogCmp">DialogCmp1</h3>
    </DialogCmp>
    </template>
    <script setup lang="ts">
    import useDialog from "./components/useDialog";
    import DialogCmp from "./components/Dialog.vue";
    
    const {
      visible: visible1,
      openDialog: openDialog1,
      closeDialog: closeDialog1,
    } = useDialog();
    </script>
    Nach dem Login kopieren
    Nach dem Login kopieren

    useDialogState 和 useDialogWithForm

    useDialogState

    针对开发管理后台弹窗状态封装的一个hook,搭配下面的useDialogWithForm使用。

    export enum MODE {
      ADD,  EDIT,
    }
    Nach dem Login kopieren
    Nach dem Login kopieren
    import { ref } from "vue";
    import { MODE } from "./types";
    export default function useDialogState() {
      const mode = ref<MODE>(MODE.ADD);
      const visible = ref(false);
      const updateMode = (target: MODE) => {
        mode.value = target;
      };
      return { mode, visible, updateMode };
    }
    Nach dem Login kopieren
    Nach dem Login kopieren

    useDialogWithForm

    针对表单弹窗组件封装的hooks,接收一个formRef实例,负责控制弹窗内标题及清空表单中的校验结果,减少多余的代码 ~

    import { FormInstance } from "element-plus";
    import { Ref, ref } from "vue";
    import { MODE } from "./types";
    import useDialogState from "./useDialogState";
    
    export default function useDialogFn(
      formInstance: Ref<FormInstance>
    ) {
      const { visible, mode, updateMode } = useDialogState();
    
      const closeDialog = () => {
        formInstance.value.resetFields();
        visible.value = false;
      };
      const openDialog = (target: MODE) => {
        updateMode(target);
        visible.value = true;
      };
      return { visible, mode, openDialog, closeDialog };
    }
    Nach dem Login kopieren
    Nach dem Login kopieren

    useDialogWithForm Demo

    Lassen Sie uns darüber sprechen, wie Sie mit Vue3+Hook Popup-Komponenten schneller und effizienter schreiben können

    <template>
      <Dialog
        :before-close="customClose"
        @confirm="confirm"
        v-model="visible"
        :title="mode == MODE.ADD ? &#39;添加数据&#39; : &#39;编辑信息&#39;"
        :confirm-text="mode == MODE.ADD ? &#39;添加&#39; : &#39;修改&#39;"
      >
        <el-form
          label-width="100px"
          :model="formData"
          ref="formDataRef"
          style="max-width: 460px"
          :rules="rules"
        >
          <el-form-item label="姓名" prop="name">
            <el-input v-model="formData.name" />
          </el-form-item>
          <el-form-item label="年龄" prop="age">
            <el-input v-model="formData.age" />
          </el-form-item>
          <el-form-item label="手机号码" prop="mobile">
            <el-input v-model="formData.mobile" />
          </el-form-item>
        </el-form>
      </Dialog>
    </template>
    <script setup>
    import { ElMessage, FormInstance } from "element-plus";
    import { Ref, ref } from "vue";
    import Dialog from "./Dialog.vue";
    import { MODE } from "./types";
    import useDialogWithForm from "./useDialogWithForm";
    
    const rules = {
      name: {
        type: "string",
        required: true,
        pattern: /^[a-z]+$/,
        trigger: "change",
        message: "只能是英文名称哦",
        transform(value: string) {
          return value.trim();
        },
      },
      age: {
        type: "string",
        required: true,
        pattern: /^[0-9]+$/,
        trigger: "change",
        message: "年龄只能是数字哦",
        transform(value: string) {
          return value.trim();
        },
      },
      mobile: {
        type: "string",
        required: true,
        pattern:
          /^(?:(?:\+|00)86)?1(?:(?:3[\d])|(?:4[5-79])|(?:5[0-35-9])|(?:6[5-7])|(?:7[0-8])|(?:8[\d])|(?:9[189]))\d{8}$/,
        trigger: "change",
        message: "请输入正确的手机号码",
        transform(value: string) {
          return value.trim();
        },
      },
    };
    
    interface FromDataType {
      name: string;
      age: string;
      mobile: string;
    }
    
    const formDataRef = ref<FormInstance | null>(null);
    
    let formData = ref<FromDataType>({
      name: "",
      age: "",
      mobile: "",
    });
    
    const { visible, closeDialog, openDialog, mode } = useDialogWithForm(
      formDataRef as Ref<FormInstance>
    );
    const confirm = () => {
      if (!formDataRef.value) return;
      formDataRef.value.validate((valid) => {
        if (valid) {
          console.log("confirm");
          ElMessage({
            message: "提交成功",
            type: "success",
          });
          closeDialog();
        }
      });
    };
    
    const customClose = () => {
      ElMessage({
        message: "取消提交",
        type: "info",
      });
      closeDialog();
    };
    defineExpose({
      closeDialog,
      openDialog,
    });
    </script>
    <style scoped></style>
    Nach dem Login kopieren
    Nach dem Login kopieren

    仓库地址

    useDialog

    在线demo地址

    7 (1).gif

    如果您觉得本文对您有帮助,请帮帮忙点个star

    您的反馈 是我更新的动力!

    (学习视频分享:vuejs入门教程编程基础视频

    Das obige ist der detaillierte Inhalt vonLassen Sie uns darüber sprechen, wie Sie mit Vue3+Hook Popup-Komponenten schneller und effizienter schreiben können. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

    Erklärung dieser Website
    Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

    Heiße KI -Werkzeuge

    Undresser.AI Undress

    Undresser.AI Undress

    KI-gestützte App zum Erstellen realistischer Aktfotos

    AI Clothes Remover

    AI Clothes Remover

    Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

    Undress AI Tool

    Undress AI Tool

    Ausziehbilder kostenlos

    Clothoff.io

    Clothoff.io

    KI-Kleiderentferner

    Video Face Swap

    Video Face Swap

    Tauschen Sie Gesichter in jedem Video mühelos mit unserem völlig kostenlosen KI-Gesichtstausch-Tool aus!

    Heiße Werkzeuge

    Notepad++7.3.1

    Notepad++7.3.1

    Einfach zu bedienender und kostenloser Code-Editor

    SublimeText3 chinesische Version

    SublimeText3 chinesische Version

    Chinesische Version, sehr einfach zu bedienen

    Senden Sie Studio 13.0.1

    Senden Sie Studio 13.0.1

    Leistungsstarke integrierte PHP-Entwicklungsumgebung

    Dreamweaver CS6

    Dreamweaver CS6

    Visuelle Webentwicklungstools

    SublimeText3 Mac-Version

    SublimeText3 Mac-Version

    Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

    So verwenden Sie Bootstrap in Vue So verwenden Sie Bootstrap in Vue Apr 07, 2025 pm 11:33 PM

    Die Verwendung von Bootstrap in Vue.js ist in fünf Schritte unterteilt: Startstrap installieren. Bootstrap in main.js. Verwenden Sie die Bootstrap -Komponente direkt in der Vorlage. Optional: benutzerdefinierter Stil. Optional: Verwenden Sie Plug-Ins.

    So fügen Sie Funktionen zu Schaltflächen für Vue hinzu So fügen Sie Funktionen zu Schaltflächen für Vue hinzu Apr 08, 2025 am 08:51 AM

    Sie können der VUE -Taste eine Funktion hinzufügen, indem Sie die Taste in der HTML -Vorlage an eine Methode binden. Definieren Sie die Methode und schreiben Sie die Funktionslogik in der VUE -Instanz.

    So verweisen Sie auf die JS -Datei mit Vue.js So verweisen Sie auf die JS -Datei mit Vue.js Apr 07, 2025 pm 11:27 PM

    Es gibt drei Möglichkeiten, sich auf JS -Dateien in Vue.js zu beziehen: Geben Sie den Pfad direkt mit dem & lt; Skript & gt an. Etikett;; Dynamischer Import mit dem montierten () Lebenszyklushaken; und importieren über die Vuex State Management Library.

    So verwenden Sie Watch in Vue So verwenden Sie Watch in Vue Apr 07, 2025 pm 11:36 PM

    Mit der Watch -Option in Vue.js können Entwickler auf Änderungen in bestimmten Daten anhören. Wenn sich die Daten ändert, löst sich eine Rückruffunktion aus, um Aktualisierungsansichten oder andere Aufgaben auszuführen. Zu den Konfigurationsoptionen gehören unmittelbar, die festlegen, ob ein Rückruf sofort ausgeführt werden soll, und Deep, das feststellt, ob Änderungen an Objekten oder Arrays rekursiv anhören sollen.

    Was bedeutet VUE Multi-Page-Entwicklung? Was bedeutet VUE Multi-Page-Entwicklung? Apr 07, 2025 pm 11:57 PM

    VUE Multi-Page-Entwicklung ist eine Möglichkeit, Anwendungen mithilfe des Vue.js-Frameworks zu erstellen, in dem die Anwendung in separate Seiten unterteilt ist: Code-Wartung: Die Aufteilung der Anwendung in mehrere Seiten kann das Verwalten und Wartungsbereich erleichtern. Modularität: Jede Seite kann als separates Modul für eine einfache Wiederverwendung und den Austausch verwendet werden. Einfaches Routing: Die Navigation zwischen Seiten kann durch einfache Routing -Konfiguration verwaltet werden. SEO -Optimierung: Jede Seite hat eine eigene URL, die SEO hilft.

    So kehren Sie von Vue zur vorherigen Seite zurück So kehren Sie von Vue zur vorherigen Seite zurück Apr 07, 2025 pm 11:30 PM

    VUE.JS hat vier Methoden, um zur vorherigen Seite zurückzukehren: $ router.go (-1) $ router.back () verwendet & lt; Router-Link to = & quot;/& quot; Komponentenfenster.history.back () und die Methodenauswahl hängt von der Szene ab.

    So verwenden Sie Vue Traversal So verwenden Sie Vue Traversal Apr 07, 2025 pm 11:48 PM

    Es gibt drei gängige Methoden für Vue.js, um Arrays und Objekte zu durchqueren: Die V-für-Anweisung wird verwendet, um jedes Element zu durchqueren und Vorlagen zu rendern; Die V-Bind-Anweisung kann mit V-für dynamisch Attributwerte für jedes Element verwendet werden. und die .MAP -Methode kann Array -Elemente in Neuarrays umwandeln.

    Wie man einen Tag zum Vue springt Wie man einen Tag zum Vue springt Apr 08, 2025 am 09:24 AM

    Zu den Methoden zum Implementieren des Sprung eines Tags in VUE gehören: Verwenden des A -Tags in der HTML -Vorlage, um das HREF -Attribut anzugeben. Verwenden Sie die Router-Link-Komponente des Vue-Routings. Verwenden Sie dies. $ Router.push () Methode in JavaScript. Parameter können durch den Abfrageparameter weitergeleitet werden, und Routen sind in den Routeroptionen für dynamische Sprünge konfiguriert.

    See all articles