Initial commit
This commit is contained in:
251
docs/vue/component.md
Normal file
251
docs/vue/component.md
Normal file
@@ -0,0 +1,251 @@
|
||||
# 组件开发
|
||||
|
||||
## 组件基础
|
||||
|
||||
### 定义组件
|
||||
|
||||
```vue
|
||||
<!-- MyButton.vue -->
|
||||
<template>
|
||||
<button :class="['btn', `btn-${type}`]" @click="handleClick">
|
||||
<slot></slot>
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const props = defineProps({
|
||||
type: {
|
||||
type: String,
|
||||
default: 'default',
|
||||
validator: (value) => ['default', 'primary', 'danger'].includes(value)
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits(['click'])
|
||||
|
||||
function handleClick(event) {
|
||||
emit('click', event)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.btn {
|
||||
padding: 8px 16px;
|
||||
border-radius: 4px;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.btn-default {
|
||||
background: #f0f0f0;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background: #42b883;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-danger {
|
||||
background: #ff4d4f;
|
||||
color: white;
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
### 使用组件
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<MyButton type="primary" @click="handleButtonClick">
|
||||
点击我
|
||||
</MyButton>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import MyButton from './MyButton.vue'
|
||||
|
||||
function handleButtonClick() {
|
||||
console.log('按钮被点击')
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
## Props
|
||||
|
||||
### Props声明
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
// 简单声明
|
||||
const props = defineProps(['title', 'content'])
|
||||
|
||||
// 带类型的声明
|
||||
const props = defineProps({
|
||||
title: String,
|
||||
content: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
count: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
items: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
})
|
||||
</script>
|
||||
```
|
||||
|
||||
### Props验证
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
const props = defineProps({
|
||||
status: {
|
||||
type: String,
|
||||
required: true,
|
||||
validator: (value) => ['active', 'inactive', 'pending'].includes(value)
|
||||
},
|
||||
callback: {
|
||||
type: Function,
|
||||
default: () => {}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
```
|
||||
|
||||
## 事件
|
||||
|
||||
### 定义事件
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
const emit = defineEmits(['update', 'delete', 'change'])
|
||||
|
||||
function handleUpdate() {
|
||||
emit('update', { id: 1, name: '更新数据' })
|
||||
}
|
||||
|
||||
function handleDelete(id) {
|
||||
emit('delete', id)
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
### v-model
|
||||
|
||||
```vue
|
||||
<!-- CustomInput.vue -->
|
||||
<template>
|
||||
<input
|
||||
:value="modelValue"
|
||||
@input="$emit('update:modelValue', $event.target.value)"
|
||||
>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
defineProps(['modelValue'])
|
||||
defineEmits(['update:modelValue'])
|
||||
</script>
|
||||
|
||||
<!-- 使用 -->
|
||||
<CustomInput v-model="text" />
|
||||
```
|
||||
|
||||
## 插槽
|
||||
|
||||
### 默认插槽
|
||||
|
||||
```vue
|
||||
<!-- Card.vue -->
|
||||
<template>
|
||||
<div class="card">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 使用 -->
|
||||
<Card>
|
||||
<h2>标题</h2>
|
||||
<p>内容</p>
|
||||
</Card>
|
||||
```
|
||||
|
||||
### 具名插槽
|
||||
|
||||
```vue
|
||||
<!-- Layout.vue -->
|
||||
<template>
|
||||
<div class="layout">
|
||||
<header>
|
||||
<slot name="header"></slot>
|
||||
</header>
|
||||
<main>
|
||||
<slot></slot>
|
||||
</main>
|
||||
<footer>
|
||||
<slot name="footer"></slot>
|
||||
</footer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 使用 -->
|
||||
<Layout>
|
||||
<template #header>
|
||||
<h1>页面标题</h1>
|
||||
</template>
|
||||
|
||||
<p>主要内容</p>
|
||||
|
||||
<template #footer>
|
||||
<p>页脚信息</p>
|
||||
</template>
|
||||
</Layout>
|
||||
```
|
||||
|
||||
### 作用域插槽
|
||||
|
||||
```vue
|
||||
<!-- List.vue -->
|
||||
<template>
|
||||
<ul>
|
||||
<li v-for="item in items" :key="item.id">
|
||||
<slot :item="item" :index="index"></slot>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
defineProps(['items'])
|
||||
</script>
|
||||
|
||||
<!-- 使用 -->
|
||||
<List :items="users">
|
||||
<template #default="{ item, index }">
|
||||
<span>{{ index }}. {{ item.name }}</span>
|
||||
</template>
|
||||
</List>
|
||||
```
|
||||
|
||||
## 生命周期
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
import { onMounted, onUpdated, onUnmounted } from 'vue'
|
||||
|
||||
onMounted(() => {
|
||||
console.log('组件已挂载')
|
||||
})
|
||||
|
||||
onUpdated(() => {
|
||||
console.log('组件已更新')
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
console.log('组件已卸载')
|
||||
})
|
||||
</script>
|
||||
```
|
||||
Reference in New Issue
Block a user