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. 包含完整的组件通信机制
相关推荐
码上成长1 小时前
JavaScript 数组合并性能优化:扩展运算符 vs concat vs 循环 push
开发语言·javascript·ecmascript
老陈聊架构2 小时前
『AI辅助Skill』掌握三大AI设计Skill:前端独立完成产品设计全流程
前端·人工智能·claude·skill
油丶酸萝卜别吃2 小时前
Mapbox GL JS 表达式 (expression) 条件样式设置 完全指南
开发语言·javascript·ecmascript
Ulyanov2 小时前
从桌面到云端:构建Web三维战场指挥系统
开发语言·前端·python·tkinter·pyvista·gui开发
cypking2 小时前
二、前端Java后端对比指南
java·开发语言·前端
摘星编程2 小时前
用React Native开发OpenHarmony应用:timing定时动画参数
javascript·react native·react.js
糠帅傅蓝烧牛肉面2 小时前
单实例多MCP聚合服务:两种实现方案深度对比
前端·docker·ai
JosieBook3 小时前
【Vue】12 Vue技术—— Vue 事件修饰符详解:掌握事件处理的高级技巧
前端·javascript·vue.js
摘星编程3 小时前
在OpenHarmony上用React Native实现AnimatedValue补间动画
javascript·react native·react.js
摘星编程3 小时前
React Native鸿蒙版:AnimatedXY双轴动画完整代码
javascript·react native·react.js