Vue 3 + TypeScript 模态框组件实现

Vue 3 + TypeScript 模态框组件实现

在这篇文章中,我们将讨论如何使用 Vue 3 和 TypeScript 构建一个简单的模态框组件。这个模态框组件包含标题、文本、提示信息和按钮,所有这些内容都是通过 props 来传递的,并且我们将使用 emit 来处理模态框的关闭事件。

组件模板代码解析

首先,让我们来看看模态框的 HTML 结构和 Vue 模板部分:

<template>
    <view class="model-wrap">
        <view class="content-wrap">
            <view
                v-show="title"
                class="c-title font-bold"
            >
                {{ title }}
            </view>
            <view
                v-show="tip"
                class="c-tip"
            >
                {{ tip }}
            </view>
            <view
                v-show="txt"
                class="c-txt"
                v-for="(item,index) in txt"
                :key="index"
            >
               <view class="title font-bold">{{item.title}}</view>
                <view class="des">{{item.des}}</view>
            </view>

            <view
                class="c-btn"
                @tap="onClose"
            >
                {{ btnTxt }}
            </view>
        </view>
    </view>
</template>

模板中的结构说明

  • model-wrap 是模态框的最外层容器,它覆盖整个屏幕以显示背景遮罩。
  • content-wrap 包含模态框的实际内容,包括标题、提示信息、文本列表和按钮。
  • v-show 用于根据 props 的值来决定是否显示相应的部分。
  • 文本列表使用 v-for 循环来渲染,这样我们可以动态传递一个文本数组,每个数组项都有 titledes 字段。

组件逻辑实现

接下来是 script 部分,这里我们使用了 Vue 3 的 setup 语法糖,并结合 TypeScript 对 props 进行类型定义。

<script setup lang="ts">
const { title, txt, tip, btnTxt } = defineProps({
    visible: {
        type: Boolean,
        default: false,
    },
    title: {
        type: String,
        default: '',
    },
    txt: {
        type: Array as PropType<{ title: string, des: string }[]>,
        default: () => [],
    },
    tip: {
        type: String,
        default: '',
    },
    btnTxt: {
        type: String,
        default: '我知道了',
    },
    onClose: {
        type: Function,
        default: () => {},
    },
});

const emit = defineEmits(['update:visible']);

const onClose = () => {
    emit('update:visible', false);
};
</script>

逻辑部分说明

  • 使用 defineProps 定义组件的 props,并且为每个 prop 提供了类型和默认值。
    • titletipbtnTxt 是简单的字符串。
    • txt 是一个数组,数组项包含 titledes 字段。
  • 使用 defineEmits 定义事件发射器,这里我们监听并触发 update:visible 事件,以便父组件能够控制模态框的显示和隐藏。
  • onClose 方法负责发射关闭事件,模态框的关闭通过将 visible 设置为 false 来实现。

样式设计

模态框组件的样式通过 Less 进行编写,并使用了 scoped 关键字来确保样式作用范围仅限于当前组件。

<style lang="less" scoped>
.model-wrap {
    position: fixed;
    top: 0;
    left: 0;
    z-index: 999999999;
    width: 100vw;
    height: 100vh;
    background-color: rgba(0, 0, 0, 0.5);

    .content-wrap {
        position: absolute;
        left: 50%;
        top: 50%;
        width: 620px;
        background-color: var(--cr-bg);
        border-radius: 24px;
        transform: translate(-50%, -50%);

        .c-title {
            width: 620px;
            height: 84px;
            line-height: 84px;
            margin-top: 32px;
            font-size: var(--font-ex-midder);
            color: var(--cr-font-color2);
            text-align: center;
        }

        .c-txt {
            padding: 0px 48px 40px 48px;
            box-sizing: border-box;
            font-size: var(--font-middle);
            color: var(--cr-font-color2);
            text-align: justify;
            line-height: 48px;

            .title {
                font-size: 32px;
                color: #222222;
                line-height: 32px;
            }

            .des {
                font-size: 28px;
                color: #666666;
                text-align: justify;
                line-height: 42px;
                margin-top: 16px;
            }
        }

        .c-tip {
            margin: 0 47px 35px 49px;
            box-sizing: border-box;
            letter-spacing: 0;
            line-height: 46px;
            font-size: 32px;
            color: #222222;
        }

        .c-btn {
            display: flex;
            justify-content: center;
            align-items: center;
            width: 100%;
            height: 118px;
            font-size: var(--font-ex-midder);
            color: var(--text-tag-good);
            border-top: 1px solid #e5e5e5;
        }
    }
}
</style>

样式部分说明

  • model-wrap 使用了固定定位和全屏宽高来创建模态框的背景遮罩,并且设置了半透明黑色背景来模糊页面内容。
  • content-wrap 是模态框的内容区域,它使用绝对定位并居中。
  • 标题、提示信息、文本和按钮都通过相应的类名进行了样式定义,使用了字体大小、颜色、行高等属性来确保在 UI 上的整洁显示。

使用示例

我们可以通过父组件来控制模态框的显示和关闭,并传递必要的 props

<template>
  <Modal 
    :visible="isVisible" 
    title="提示" 
    :txt="modalText"
    tip="这是一个提示信息"
    btnTxt="关闭"
    @update:visible="isVisible = false"
  />
  <button @click="isVisible = true">打开模态框</button>
</template>

<script setup lang="ts">
import { ref } from 'vue';
const isVisible = ref(false);
const modalText = [
  { title: '标题1', des: '描述内容1' },
  { title: '标题2', des: '描述内容2' }
];
</script>

父组件部分说明

  • 通过 isVisible 控制模态框的显示状态。
  • modalText 是一个包含标题和描述的数组,传递给子组件。
  • 点击按钮时,模态框会打开;关闭模态框时,通过监听 update:visible 事件,将 isVisible 设置为 false

总结

在这篇文章中,我们展示了如何使用 Vue 3 和 TypeScript 构建一个模态框组件。通过使用 propsemit,我们能够实现灵活的数据传递和事件处理,并且通过样式设计让模态框在页面中以美观的方式展现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值