# Vue 樣板語法
### 嵌入純文字
標籤內使用 {{ 嵌入的變數 }} 語法
```
組建名稱.vue
<script setup>
let data="Hello";
</script>
<template>
<div>{{ data }}</div>
</template>
<style scoped>
/*CSS設定*/
</style>
```
### 嵌入Html語法
標籤屬性設定 v-html="嵌入的變數"
```
組建名稱.vue
<script setup>
let htmlData="<u>Hello</u>";
</script>
<template>
<div v-html="htmlData"></div>
</template>
<style scoped>
/*CSS設定*/
</style>
```
### 屬性
- 嵌入屬性值(將變數中的資料帶入到標籤中的屬性中)
v-bind:屬性名稱="嵌入的變數"
簡寫->
:屬性名稱="嵌入的變數"
```
組建名稱.vue
<script setup>
let name="content";
</script>
<template>
<div v-bind:class="name">Hello</div>
//簡寫-> <div:class="name">Hello</div>//
</template>
<style scoped>
/*CSS設定*/
</style>
```
### 程式語句
- 透過程式語句產生標籤內文
標籤內使用 {{ 程式語句 }}語法
```
組建名稱.vue
<script setup>
let data="Hello";
</script>
<template>
<div>{{ data.toUpperCase()}}</div>
</template>
<style>
/*CSS設定*/
</style>
```
- 透過程式語句產生標籤屬性值
- 標籤屬性設定
:屬性名稱="程式語句"
```
組建名稱.vue
<script setup>
let data="true";
</script>
<template>
<div :class="data?'dark':'light'">Hello</div>
</template>
<style scoped>
/*CSS設定*/
</style>
```
### 判斷式
- if 判斷式
v-if="布林值"
```
組建名稱.vue
<script setup>
let data = true;
let number = 3000;
</script>
<tamplate>
<div v-if="data">顯示</div>
<div v-if="!data">不顯示</div>
<div v-if="number>2000">大於2000</div>
</tamplate>
<style scoped>
/*CSS設定*/
</style>
```
- if...else判斷式
使用v-else語法,必須搭配v-if使用
```
組建名稱.vue
<script setup>
let number = 1000;
</script>
<template>
<div v-if="number>2000">大於2000</div>
<div v-else>小於等於2000</div>
</template>
<style scoped>>
/*CSS設定*/
</style>
```
- if...else if...else判斷式
使用v-else-if="布林值"語法,必須搭配v-if使用,可搭配v-else
```
組建名稱.vue
<script setup>
let number = 15;
</script>
<template>
<div v-if="number<20">小於20</div>
<div v-else-if="number<20">小於10</div>
<div v-else>小於5</div>
</template>
<style scoped>
/*CSS設定*/
</style>
```
### 迴圈
- for迴圈-陣列
使用v-for="變數in陣列"語法
```
<script setup>
let data=[1,2,3];
</script>
<template>
<div v-for="n in data">Item{{ n }}</div>
</template>
<style scoped>
/*CSS設定*/
</style>
```
- for迴圈-陣列索引
使用v-for="(變數,變數)in陣列"語法
```
<script setup>
let data=["A","B","C"];
</script>
<template>
<div v-for="(text,index)in data">
{{ index }}-{{ text }}
</div>
</template>
<style scoped>
/*CSS設定*/
</style>
```
- for迴圈-物件
使用v-for="(變數,變數)in物件"語法
```
<script setup>
let data=["x"=3,"y"=4];
</script>
<template>
<div v-for="(value,key)in data">
物件屬性{{ key }}為{{ value }}
</div>
</template>
<style scoped>
/*CSS設定*/
</style>
```
### 基本事件處理
- 基本事件處理
使用v-on:事件名稱="函式名稱"語法
```
<script setup>
let handler = function(){
console.log("Click");
};
</script>
<template>
<span v-on:click="handler"> </span>
</template>
<style scoped>
/*CSS設定*/
</style>
```
- 基本事件處理(簡寫)
使用@事件名稱="函式名稱"語法
```
<script setup>
let clickHandler = function(){
console.log("Click");
}
let mouseoverHandler = function(){
console.log("MouseOver");
}
</script>
<template>
<span
@click = "clickHandler"
@mouseover = "mouseoverHandler">文字
</span>
</template>
<style scoped>
/*CSS設定*/
</style>
```
### 使用修飾字
- 使用once表達事件只觸發一次
v-on:事件名稱.once="函式名稱"
@事件名稱.once="函式名稱"
```
<script setup>
let handler = function(){
console.log("Click");
};
</script>
<template>
<span v-on:click.once="handler"> </span>
</template>
<style scoped>
/*CSS設定*/
</style>
```
- 使用prevent表達停止預設行為
v-on:事件名稱.prevent="函式名稱"
@事件名稱.prevent="函式名稱"
```
<script setup>
let handler = function(){
console.log("Click");
};
</script>
<templte>
<a href="http://training.pada-x.com/"
v-on:click.prevent="handler"
>我的網站</a>
</templte>
<style scoped>
/*CSS設定*/
</style>
```
### 響應式狀態
#### 非響應式的狀態
資料和畫面沒有連動
```
<script setup>
let content = "網站的內容";
let handler = function(){
content = "新的網站內容";
}
</script>
<template>
<div>{{ content }}</div>
<button @click = "handler">點擊</button>
</template>
<style scoped>
/*CSS設定*/
</style>
```
#### 響應式狀態
資料和畫面有連動
- 載入Vue的ref函式
`import{ref}form "vue";`
- 呼叫ref函式建立響應式狀態
`let content = ref(資料);`
- 在樣板中使用、顯示資料
`<div>{{content}}</div>`
- 更新響應式狀態的資料
`content.value="新的資料";`
```
<script setup>
import{ref}from "vue";
let content = ref("網站的內容");
let handler = function(){
content.value = "新的網站內容";
}
</script>
<template>
<div>{{ content }}</div>
<button @click = "handler">點擊</button>
</template>
<style scoped>
/*CSS設定*/
</style>
```
```
<script setup>
let name = ref("title");
let handler = function(){
name.value = "title highlight"
}
</script>
<template>
<div :class="name">段落標題</div>
<button @click = "handler">點擊</button>
</template>
<style scoped>
.title{font-weight:bold}
.highlight{color:red}
</style>
```
```
:class="name" 语法将 CSS 类绑定到 name 变量,实际上是将 name 的值用作元素的 CSS 类名称。因此,当 name 的值与你的 CSS 类名匹配时,相关的样式将应用于元素。
在你的代码中,name 的初始值是 "title",这正好与你定义的 .title CSS 类的名称匹配。因此,在页面加载时,<div> 元素将应用名为 "title" 的 CSS 类,从而应用了与 .title 类相关的样式。
```
```
練習:
<script setup>
import {ref} from "vue";
let state = ref({
title : "網站標題",
className : "title"
});
let handler = function(){
state.value.title = "新的網站標題";
state.value.className = "highlight";
};
</script>
<template>
<div :class= "state.className"> {{ state.title }}</div>
<button @click ="handler" >按鈕</button>
</template>
<style>
.title{color:grey}
.highlight{color:red}
</style>
```
### 表單輸入元件
接受使用者輸入的HTML元件
- 單行、多行文字輸入
<input type="text"/>
<textarea></textarea>>
- 多選方框、單選圓框
<input type="checkbox"/>
<input type="radio"/>
- 下拉式選單
<select>
<option></option>
<option></option>
</select>
### 輸入元件、和響應式的綁定
- 使用v-model="響應式狀態名稱"
輸入的資料和響應式狀態連動
```
<script setup>
import {ref} form "vue";
let text = ref("預設的文字");
</script>
<template>
<input type="text" v-model="text"/>
<div>輸入文字:{{ text }}</div>
</template>
<style scoped>
/*CSS設定*/
</style>
```
#### 單選框範例
多個選擇框綁定同一個響應式狀態
資料和標籤的value屬性對應
```
<script setup>
import { ref } from "vue";
let gender = ref(null);
</script>
<template>
<input type="radio" value="male" v-model="gender" id="male"/><label for="male" class="male">男</label>
<input type="radio" value="female" v-model="gender" id="female"/><label for="female" class="female">女</label>
<div>選擇的性別:<span :class="gender">{{ gender }}</span></div>
</template>
<style scoped>
.male{color: lightblue;}
.female{color: pink;}
</style>
```
#### 多選框範例
綁定的響應式狀態使用陣列資料
資料和標籤的value屬性對應
```
<script setup>
import {ref} from "vue";
let fruits = ref([]);
</script>
<template>
<input type="checkbox" v-model="fruits" value="apple"/>蘋果
<input type="checkbox" v-model="fruits" value="gruava"/>芭樂
<input type="checkbox" v-model="fruits" value="grape"/>葡萄
<div>選擇的水果:{{ fruits }}</div>
</template>
<style scoped>
/*CSS設定*/
</style>
```
#### 下拉式選單範例
v-model綁定select標籤
資料和option標籤的value屬性對應
```
<script setup>
import {ref} from "vue";
let gender = ref("");
</script>
<template>
<select v-model="gender">
<option value="">請選擇</option>
<option value="male">男</option>
<option value="female">女</option>
</select>
<div>選擇的性別是:{{ gender }}</div>
</template>
<style scoped>
/*CSS設定*/
</style>
```
```
練習:
<script setup>
import {ref} from "vue";
let name = ref("");
let reset = function(){
name.value = "";
}
let gender = ref("");
let interest = ref([]);
let mood = ref("");
</script>
<template>
<h3>單行輸入匡</h3>
請輸入名字:<input type="text" v-model="name">
<button @click="reset">清空輸入匡</button>
<br>
我的名字是:{{ name }}
<h3>單選匡</h3>
性別:<input type="radio" value="male" v-model="gender">男生<input type="radio" value="female" v-model="gender">女生
<br>
我的性別是:{{ gender }}
<h3>多選匡</h3>
<input type="checkbox" value="打棒球" v-model="interest">打棒球
<input type="checkbox" value="看電影" v-model="interest">看電影
<input type="checkbox" value="吃美食" v-model="interest">吃美食
<input type="checkbox" value="運動" v-model="interest">運動
<input type="checkbox" value="看書" v-model="interest">看書
<br>
我的興趣是:<ul>
<li v-for="myInterest in interest">{{ myInterest }}</li>
</ul>
<h3>下拉式選單</h3>
今天心情怎麼樣:<select name="" id="" v-model="mood">
<option value="">請選擇</option>
<option value="普通">普通</option>
<option value="平靜">平靜</option>
<option value="焦慮">焦慮</option>
<option value="累">累</option>
<option value="無奈">無奈</option>
</select>
<br>
<div>我今天的心情:{{ mood }}</div>
</template>
<style>
</style>
```
### 單一組件
整個網頁由單一組件組成
```
<script setup>
//Javascript程式碼
console.log("我的首頁");
</script>
<template>
<!--HTML樣板結構-->
<nav>
網頁導覽列
</nav>
<main>
<div>網頁主區塊一</div>
<div>網頁主區塊二</div>
</main>
</template>
<style scoped>
/*CSS設定*/
nav{font-weight:bold};
main{padding:30px 0xp}
</style>
```
### 組件的切割
- 將網頁根據實際的畫面區塊切割成多個組件
將上述單一組建網頁架構分為:App.vue + Nav.vue + Main.vue
```
App.vue:
<script setup>
import Nav from "./Nav.vue";
import Main from "./Main.vue";
</script>
<template>
<Nav></Nav>
<Main></Main>
</template>
<style scoped>
</style>
```
```
Nav.vue:
<script setup>
console.log("導覽頁相關的程式碼");
</script>
<template>
<nav>
網頁導覽列
</nav>
</template>
<style scoped>
nav{font-weight:bold};
</style>
```
```
Main.vue:
<script setup>
console.log("主區塊相關的程式碼");
</script>
<template>
<main>
<div>網頁主區塊一</div>
<div>網頁主區塊二</div>
</main>
</template>
<style scoped>
main{padding:30px 0xp};
</style>
```
### 載入組件
- 在程式中載入其他的組件
import 組建名稱 from "組建檔案路徑";
```
範例:
<script setup>
import NavComp from "./Nav.vue";
</script>
```
### 使用載入的組件
- 在樣板中使用載入的組件
`<組建名稱></組建名稱>`
```
範例:
<script setup>
import NavComp from "./Nav.vue";
</script>
<template>
<NavComp></NavComp>
</template>
```
練習:
```
單一組件:
<script setup>
import {ref} from "vue";
let text = ref("主要的網站內容");
let change = function(){
text.value = "新的網站內容";
};
</script>
<template>
<nav>基本的導覽列</nav>
<main>
<div @click = "change">{{ text }}</div>
</main>
</template>
<style>
nav{padding:10px}
main{padding:10px;background-color:pink;};
</style>
```
```
App.vue:
<script setup>
import NavComp from "./Nav.vue";
import MainComp from "./Main.vue";
</script>
<template>
<NavComp></NavComp>
<MainComp></MainComp>
</template>
<style>
</style>
```
```
Nav.vue:
<script setup>
</script>
<template>
<nav>基本的導覽列</nav>
</template>
<style scoped>
nav{padding:10px}
</style>
```
```
Main.vue:
<script setup>
import {ref} from "vue";
let text = ref("主要的網站內容");
let change = function(){
text.value = "新的網站內容";
};
</script>
<template>
<main>
<div @click = "change">{{ text }}</div>
</main>
</template>
<style scoped>
main{padding:10px;background-color:pink;};
</style>
```
### 自訂屬性
組件的使用,自訂屬性;就像是HTML標籤的屬性一樣
- 載入組件
import 組件名稱 from "組件檔案路徑";
- 在樣板中使用載入的組件,並設定屬性
```
<組件名稱
屬性名稱="資料" 屬性名稱="資料"...
></組件名稱>
```
```
App.vue:
<script setup>
import Nav from "./Nav.vue";
import Main from "./Main.vue";
</script>
<template>
<Nav title="任意的標題"></Nav>
<Main></Main>
</template>
<style scoped>
</style>
```
```
Nav.vue
<script setup>
defineProps(["title"]);
</script>
<template>
<nav>
{{ title }}
</nav>
</template>
<style scoped>
</style>
```
- 定義、接受並使用屬性
定義要接收的屬性名稱語法
`defineProps(["屬性名稱","屬性名稱"],...)`
```
App.vue:
<script setup>
import NavComp from "./Nav.vue";
import MainComp from "./Main.vue";
</script>
<template>
<NavComp title ="標題哈囉!!!"></NavComp>
<MainComp fontcolor="white" bgcolor="black"></MainComp>
</template>
<style>
</style>
```
```
Nav.vue:
<script setup>
defineProps(["title"]);
</script>
<template>
<nav>{{ title }}</nav>
</template>
<style scoped>
nav{padding:10px}
</style>
```
```
Main.vue:
<script setup>
import {ref} from "vue";
let text = ref("主要的網站內容");
let change = function(){
text.value = "新的網站內容";
};
defineProps(["fontcolor","bgcolor"]);
</script>
<template>
<main :style="{color:fontcolor,backgroundColor:bgcolor}">
<div @click = "change">{{ text }}</div>
</main>
</template>
<style scoped>
main{padding:10px;background-color:pink;};
</style>
```
注意此寫法:
:style="{**backgroundColor**:bgcolor}">
### 自訂事件處理
#### 建立組件的自訂事件
使用@符號+自訂事件名稱
- 載入組件
import 組件名稱 from "組件檔案路徑";
- 在樣板中使用載入的組件,並建立自訂事件
<組件名稱
@自訂事件名稱="處理函式"
@自訂事件名稱="處理函式"
...></組件名稱>
```
範例:
<script setup>
import Nav from "./Nav.vue";
let 函式名稱=function(){...};
</script>
<template>
<Nav @handler="函式名稱"></Nav>
</template>
```
#### 組件內部呼叫自訂事件方法(一)
樣板語法的標準事件中使用
`$emit('自訂事件名稱')`
範例
```
App.vue:
<script setup>
import NavComp from "./Nav.vue";
import MainComp from "./Main.vue";
import {ref} from "vue";
let text = ref("測試文字");
let change = function(){
text.value="修改的文字";
};
</script>
<template>
<NavComp></NavComp>
<MainComp @changeText="change"></MainComp>
<div>{{ text }}</div>
</template>
<style>
</style>
```
```
Nav.vue:
<script setup>
</script>
<template>
<main>
<button @click="$emit('changeText')">按鈕</button>
</main>
</template>
<style scoped>
main{padding:10px;background-color:pink;};
</style>
```
#### 組件內部呼叫自訂事件方法(二)
JavaScript程式中使用
`defineEmits(["自訂事件名稱",...])`
範例
```
App.vue:
<script setup>
import Nav from "./Nav.vue";
</script>
<template>
<Nav @handler="函式名稱"></Nav>
</template>
Nav.vue:
<script setup>
let emit = defineEmits(["handler"]);
//呼叫defineEmits(["handler"]會回傳一個可以讓我呼叫自定義組件的函式emit
let 函式名稱 = funtion(){ emit("handler");};
</script>
<template>
<nav>
<button @click="函式名稱">按鈕</button>
</nav>
</template>
```
<hr>
延伸

解決方式
