Vue3 组件完全指南代码

or: (val) => 'primary', 'success', 'warning', 'danger'.includes(val)

},

label: String,

disabled: Boolean

})

const emit = defineEmits('click')

const handleClick = (e) => {

if (!props.disabled) {

emit('click', e)

}

}

</script>

<style scoped>

.btn {

padding: 8px 16px;

border-radius: 4px;

cursor: pointer;

transition: all 0.3s;

}

.primary {

background-color: #409eff;

color: white;

}

.success {

background-color: #67c23a;

color: white;

}

/* 其他样式省略 */

</style>

<template>

<Transition name="fade">

<div v-if="visible" class="modal-mask">

<div class="modal-container">

<div class="modal-header">

<h3>{{ title }}</h3>

<button @click="close">×</button>

</div>

<div class="modal-body">

<slot></slot>

</div>

<div class="modal-footer">

<BaseButton @click="close">取消</BaseButton>

<BaseButton type="primary" @click="confirm">确认</BaseButton>

</div>

</div>

</div>

</Transition>

</template>

<script setup>

import { ref } from 'vue'

import BaseButton from '../BaseButton.vue'

const props = defineProps({

title: String,

visible: Boolean

})

const emit = defineEmits('close', 'confirm')

const close = () => emit('close')

const confirm = () => emit('confirm')

</script>

<style scoped>

.modal-mask {

position: fixed;

top: 0;

left: 0;

width: 100%;

height: 100%;

background-color: rgba(0, 0, 0, 0.5);

display: flex;

justify-content: center;

align-items: center;

}

/* 其他样式省略 */

</style>

import { createApp, h, ref } from 'vue'

import Modal from '../components/Modal/Modal.vue'

export function useModal() {

const visible = ref(false)

const show = (options) => {

visible.value = true

const container = document.createElement('div')

document.body.appendChild(container)

const app = createApp({

render() {

return h(Modal, {

title: options.title,

visible: visible.value,

onClose: () => {

hide()

options?.onClose?.()

},

onConfirm: () => {

hide()

options?.onConfirm?.()

}

}, options.content)

}

})

const hide = () => {

visible.value = false

app.unmount()

document.body.removeChild(container)

}

app.mount(container)

return hide

}

return { show }

}

import { createApp } from 'vue'

import App from './App.vue'

import BaseButton from './components/BaseButton.vue'

const app = createApp(App)

// 全局注册基础组件

app.component('BaseButton', BaseButton)

app.mount('#app')

<template>

<div class="app">

<BaseButton

type="primary"

@click="showModal"

>

打开模态框

</BaseButton>

</div>

</template>

<script setup>

import { useModal } from './hooks/useModal'

const { show } = useModal()

const showModal = () => {

show({

title: '提示',

content: '这是一个通过函数调用的模态框组件',

onConfirm: () => console.log('确认操作'),

onClose: () => console.log('关闭操作')

})

}

</script>

代码实现要点:

  1. 基础按钮组件采用组合式API封装,支持类型校验和插槽内容34
  2. 模态框组件实现Transition动画效果和具名插槽59
  3. 通过useModal Hook实现函数式调用组件18
  4. 全局注册常用基础组件提升复用性26
  5. 采用TypeScript接口规范props类型3
  6. 样式使用scoped隔离避免污染1112
  7. 包含完整的组件通信机制
相关推荐
kyriewen15 小时前
别再每次都 Google 了:我整理了前端日常最常踩的 10 个 Git 坑,附速查表
前端·javascript·git
一颗奇趣蛋15 小时前
Web 视频开发完全指南:从入门到精通
前端
非洲农业不发达15 小时前
windows终端体验大升级,让你拥有macos级别的美化
前端·后端
妙码生花15 小时前
从 PHP 到 AI + Golang,程序员自救转型手记(十七):登录接口完善,登录页接口整合,解决跨域
前端·后端·ai编程
唐诗15 小时前
改 3 行配置,我的 Tauri dev 冷启动从 100 秒干到 4 秒
前端·客户端
SmartBoyW16 小时前
深入ECMAScript规范:彻底搞懂JS隐式类型转换与底层ToPrimitive机制
前端·javascript
牧艺16 小时前
Cursor Rules / Skills 分层设计:让 Agent 像「团队新同事」
前端·人工智能·cursor
咪库咪库咪16 小时前
vue3-组件
vue.js
光影少年16 小时前
react navite 跨端核心原理
前端·react native·react.js
用户8524950718416 小时前
解密 JavaScript 中的 this:谁才是真正的调用者?
javascript·面试