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. 包含完整的组件通信机制
相关推荐
宋辰月8 分钟前
学习react第三天
前端·学习·react.js
bug总结11 分钟前
更新原生小程序封装(新增缓存订阅)完美解决
前端·缓存·小程序
GISer_Jing18 分钟前
Node.js 开发实战:从入门到精通
javascript·后端·node.js
5335ld36 分钟前
后端给的post 方法但是要求传表单数据格式(没有{})
开发语言·前端·javascript·vue.js·ecmascript
二川bro41 分钟前
第33节:程序化生成与无限地形算法
前端·算法·3d·threejs
QDKuz1 小时前
掌握Vue2转Vue3, Options API 转 Composition API
前端·javascript·vue.js
老前端的功夫1 小时前
前端Echarts性能优化:从卡顿到流畅的百万级数据可视化
前端·javascript
进击的野人1 小时前
深入解析localStorage:前端数据持久化的核心技术
前端·javascript
懵圈1 小时前
第2章:项目启动 - 使用Vite脚手架初始化项目与工程化配置
前端
Mh1 小时前
如何优雅的消除“if...else...”
前端·javascript