#### 組件基礎
1. 定義和使用簡單組件
- 
```vue
<!-- 在App.vue里 -->
<script setup>import HelloWorld from './components/HelloWorld.vue'
</script>
<template><HelloWorld></HelloWorld></template>
<!-- 在HelloWorld.vue里 -->
<template><h2>Hello,Vue3!</h2></template>
<script setup></script>
```
2. 傳遞屬性(Props)
```vue
<!-- 在App.vue里 -->
<script setup>
import HelloWorld from './components/HelloWorld.vue'
</script>
<template>
<HelloWorld title="李煥英"></HelloWorld>
<HelloWorld title="生命一號"></HelloWorld>
<HelloWorld title="希望一號"></HelloWorld>
<HelloWorld title="神州20號"></HelloWorld>
</template>
<!-- 在HelloWorld.vue里 -->
<template>
<h2>Hello,{{title}}!</h2>
</template>
<script setup>
defineProps(['title'])
</script>
```
3. 自定義事件
- 注意:【reactive({num1:0,num2:0})】【v-model="obj.num1"】
```vue
<!-- 在App.vue里 -->
<template>
? <ButtonCounter :count="count" @update:count="A"></ButtonCounter>
? <p>父組件中的計數值:{{ count }}</p>
</template>
<script setup>
import ButtonCounter from './components/ButtonCounter.vue'
import {ref} from 'vue'
let count = ref(0)
const A = (newA)=>{
? count.value = newA
}
</script>
<!-- ButtonCounter.vue里 -->
<template>
? <input type="button" :value="'點擊次數:'+count" @click="btn">
</template>
<script setup>
? import { defineEmits,defineProps } from 'vue';
? const props = defineProps(['count'])
? const emit = defineEmits(['update:count'])
? const btn = ()=>{
? ? emit('update:count',props.count + 1)
? }
</script>
```
?
### 筆記
#### 組件基礎
1. 單文件組件 :一般用于構建步驟,將組件定義在一個單獨的 .vue 文件中
- 在 `ButtonCounter.vue` 文件中:
```vue
<script setup>
? import { ref } from 'vue'
? const count = ref(0)
</script>
<template>
? <button @click="count++">{{ count }}</button>
</template>
```
2. JavaScript 對象定義組件:不使用構建步驟時,組件以包含 Vue 特定選項的 JavaScript 對象來定義
```vue
<template>
? <button @click="count++">{{ count }}</button>
</template>
<script>
import { ref } from 'vue'
export default {
? setup() {
? ? const count = ref(0)
? ? return { count }
? }
}
</script>
```
#### 傳遞 props
1. 概念:Props 是一種特別的 attributes,用于向組件中傳遞數據。例如,構建博客時,向博客文章組件傳遞標題和內容等數據就會使用到 props。
- 在組件中需要先聲明 props。使用 `<script setup>` 時,可通過 `defineProps` 宏來聲明
? - 在 `ButtonCounter.vue` 文件中:
? ```vue
? <script setup>
? ? defineProps(['title'])
? </script>
? <template>
? ? <h4>{{ title }}</h4>
? </template>
? ```
- 若未使用 `<script setup>`,則需以 `props` 選項的方式聲明,`props` 對象會作為 `setup()` 函數的第一個參數被傳入。
```js
? ? export default {
? props: ['title'],
? setup(props) {
? ? console.log(props.title)
? }
}
```
2. 傳遞 props** :在使用組件時,以自定義 attribute 的形式傳遞數據給組件。`<BlogPost title="My journey with Vue" />`
?
#### 監聽事件
1. 場景:有時子組件需要與父組件進行交互。在博客文章組件中實現點擊按鈕放大文字的功能
- 在子組件中添加按鈕,并通過 `$emit` 方法拋出事件。
? - 在 `BlogPost.vue` 文件中:
? ```vue
? <template>
? ? <div class="blog-post">
? ? ? <h4>{{ title }}</h4>
? ? ? <button @click="$emit('enlarge-text')">Enlarge text</button>
? ? </div>
? </template>
? - 父組件監聽該事件并做出響應
? ? ? <BlogPost ?@enlarge-text="postFontSize += 0.1"/>
? ```
2. 事件聲明:可通過 `defineEmits` 宏來聲明需要拋出的事件,還可以對事件的參數進行驗證。
- 在 `BlogPost.vue` 文件中
```vue
<script setup>
? defineProps(['title'])
? defineEmits(['enlarge-text'])
</script>
```
3. 若未使用 `<script setup>`,可通過 `emits` 選項定義組件會拋出的事件,并從 `setup()` 函數的第二個參數,即 `setup` 上下文對象上訪問到 `emit` 函數
```js
export default {
? emits: ['enlarge-text'],
? setup(props, ctx) {
? ? ctx.emit('enlarge-text')
? }
}
```
#### 模板引用
1. 用途:在某些情況下需要直接訪問底層 DOM 元素,可使用特殊的 `ref attribute`。
- 獲取引用:`useTemplateRef()`
```vue
<script setup>
? import { useTemplateRef, onMounted } from 'vue'
? const input = useTemplateRef('my-input')
? onMounted(() => {
? ? input.value.focus()
? })
</script>
<template>
? <input ref="my-input" />
</template>`
```
?
### 示例代碼
- ButtonCount.vue
```vue
<template>
? {{ title }}-{{ author }}
</template>
<script>
export default {
? props: ['title', 'author'],
? setup(props) {
? ? console.log(props)
? ? return { }
? }
}
</script>
```
或使用 `<script setup>`:
```vue
<script setup>
let props = defineProps(['title', 'author'])
console.log(props)
</script>
<template>
? {{ title }}-{{ author }}
</template>
```
2. App.vue
```vue
<script setup>
import { ref } from 'vue'
import ButtonCount from './components/ButtonCount.vue'
function uu() {
? console.log("我是一個自定義的事件,名叫uu")
}
let txt = ref("九九艷陽天")
</script>
<template>
? <input type="text" ref="txtUsername" @keypress.enter="uu">
? <ButtonCount :title="txt"></ButtonCount>
</template>
```