# 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> 延伸 ![image](https://hackmd.io/_uploads/BJ-FtW5HT.png) 解決方式 ![image](https://hackmd.io/_uploads/B1Ulcb9r6.png)