# vue 元件
## 安裝外掛

這樣你註解這段話下面就可以變成html
不然會顯示這樣

## component
結構
* 資料
* 方法,監聽器
* 生命週期
在createApp後才能用
命名規則用 - 連接
裡面資料是分開的
ex
```
<template>
<app-form></app-form>
</template>
import AppForm from './components/form.vue'
export default {
name: 'App',
components:{
AppForm,
}
}
```
### 母模板挖洞(未命名插槽)
**母模板**
寫法一樣,但把要得放在母模板裡面,注意要用元件標籤包起來(app-form)
```
<template>
<app-form>
<form action="">
<div class="help">
<p>test to create for template</p>
</div>
<div class="fields">
<input type="text" placeholder="email" />
<input type="text" placeholder="username" />
<input type="password" placeholder="password" />
</div>
<div class="buttons">
<button>按我</button>
</div>
</form>
</app-form>
</template>
```
**子模板**
slot 投幣口,代表他是挖洞的
如果要預設`<slot>中間寫預設</slot>`
```
<template>
<slot></slot>
</template>
```
### props
https://www.youtube.com/watch?v=bgpkvMtMUvM
用來溝通用
子層可以定義資料跟父層溝通用

不要prop定義名字 在data又定義一個一樣的
### 命名slot(正常使用)
**可以直接{{}}印出來資料
但如果要在子模板做計算跟method要更動一樣要用props**
**子**
```
<form action="">
<div class="help">
<slot name="help"></slot>
</div>
<div class="fields">
<slot name="fields"></slot>
</div>
<div class="buttons">
<slot name="buttons"></slot>
</div>
</form>
```
**母**
```
<template>
<app-form>
<template v-slot:help>
<p>test to create for template</p>
</template>
<template v-slot:fields>
<input type="text" placeholder="email" />
<input type="text" placeholder="username" />
<input type="password" placeholder="password" />
</template>
<template v-slot:buttons>
<button>按我</button>
</template>
</app-form>
</template>
<script>
import AppForm from './components/form.vue'
export default {
name: 'App',
components:{
AppForm,
}
}
</script>
```
### 關於元件 子繼承父 跟挖洞的總結(必看)
跟laravel不一樣在母為主 挖洞跟拉進來都在子,沒有繼承的概念。
用**laravel**舉例
**include的用法**
子模板寫好
母模板直接import然後註冊
```
components:{
AppForm,
}
```
註冊好直接按照命名在template用出來
`<app-form></app-form>`
**挖洞(把一個子模板重複利用)(命名slot)**
在子模板寫好然後在要填洞的地方
`<slot name="help"></slot>`
name是要給填洞的像@yeild
主模板一樣註冊拉進來
`<app-form></app-form>`
在這範圍裡面找要填的地方輸入
`<template v-slot:fields>
這邊包的東西會被拉到子模板合在一起
</template>`
**注意兩點**
v-slot是指令要記得v
v-slot:fields 後面fields這個是名字,**但是**沒有雙引號,記住沒有單雙引號
### 動態元件
利用data資料去切換要顯示哪一個元件
母
```
<template>
<select v-model="componentName">
<option value="Home">Home</option>
<option value="About">About</option>
</select>
<component :is="componentName"></component>
</template>
<script>
import Home from './components/Home.vue'
import About from './components/About.vue'
export default {
name: 'App',
components:{
About,
Home,
},
data(){
return{
componentName:"Home",
};
}
}
</script>
```
子1
```
<template>
<p>home</p>
</template>
```
子2
```
<template>
<p>about</p>
</template>
```
要顯示哪個用
`<component :is="componentName"></component>`
is去判斷,裡面的data就自己看要怎變化
**注意**
切換元件會把元件刪除
可用unmounted生命週期看

所以裡面的資料或甚麼都會不見
如果不要讓她刪除
要存留在記憶體內
用
`<keep-alive></keep-alive>`

### props(data for child)
data放在root
同層的兄弟不能把資料交換
只能父給子 叫做props

data如何傳給子
**father**
建立好data然後把資料的key用在 要放的原件上面
用屬性傳入,傳入屬性自訂,最好跟data的key一樣,記得因為是綁定v-bind,
所以要加:。

**除了data也能傳function**
**child**
props接資料用array 然後就能模板印出

### emit(子傳父)
如果要改值data的才要用$emit事件
不然用computed就好
(如果你要顯示data *2 顯示東西就計算就好 ,要改data才要用emit)
第一步
子層有事件才會改資料
在事件上面放涵式,不能直接放data去改會不給改,不能再子層直接改動data
第二步
有事件在下面寫,然後用this(指向proxy)然後取它裡面的$emit去發送事件給父層,第一個參數是名稱(用-連接),第二參數是數值(可傳可不傳)(不傳的話在父層的涵式內也可,但推薦在來源處寫)

第三部 父層
接受子層來的事件
名稱就跟你發送事件名稱一樣
接收值在下面
**重點** 值不是從function來 是從事件來,所以上面@事件涵式不用加參數

第四部 優化
做完以上會出現這個 無關的事件觸發

解決方法 讓他按照規局走
加入`emits:[]`,
符合規範,方便知道你有把事件傳出去

父層
可直接用event抓

子層觸發

### 全域註冊
### local註冊元件
範例

Greeing

### style
也分為全球跟本地
建議用本地 scope(注意他是依賴在postcss)
https://vue-loader.vuejs.org/zh/guide/scoped-css.html#%E6%B7%B7%E7%94%A8%E6%9C%AC%E5%9C%B0%E5%92%8C%E5%85%A8%E5%B1%80%E6%A0%B7%E5%BC%8F
如果要用sass

https://cli.vuejs.org/zh/guide/css.html
如果遇到 this.getOptions is not a function
降版本就好
https://stackoverflow.com/questions/66082397/typeerror-this-getoptions-is-not-a-function
### 元件驗證
https://v3.cn.vuejs.org/guide/component-props.html#%E4%BC%A0%E5%85%A5%E4%B8%80%E4%B8%AA%E5%B8%83%E5%B0%94%E5%80%BC
**如果type是要多 要[]表示**
資料一定在父層,所以子層的props改成

這樣的意思是 當父層使用到他一定要有用到這個資料
像下面的:age一樣,如果少`:age="age"`就會錯,他是必要的
`<user :age="age" @age-change="udateAge"></user>`
**預設**
當然你可以不要驗證,給他預設也可以,當心你type如果是array,預設也要array。
**自訂驗證規則**

是涵式 然後要return
提醒他是在created之前,所以計算跟method都抓不到,要小心

### 上面都是even的
也能用callback方法建立,父曾把函式帶給子層,但缺點
這邊會看不到事件傳送

###### tags: `Vue`