《 練習成果 》
《 學習重點 》
v-bind
屬性綁定 / 1–4 Vue.js的黑魔法:指令v-on
事件綁定 / 1–5 事件處理v-if、v-else-if、v-else
/ 1–6 條件判斷與列表渲染
《 學習過程:筆記整理》
在這次的範例中,橫跨了教學指南裡面比較多的篇章,以下會將有運用到的部分做整理與紀錄,有興趣的捧油或是未來的我自己,可以再看看教學指南這幾個篇章裡其他的內容,像是以下:
◎ v-model
表單綁定 / 1–4 Vue.js的黑魔法:指令
◎ v-model
與修飾子 / 1–4 Vue.js的黑魔法:指令
◎ v-text
、v-html
、v-once
、v-pre
模板綁定/ 1–4 Vue.js的黑魔法:指令
◎ v-on
與修飾子 / 1–5 事件處理
◎ v-for
/ 1–6 條件判斷與列表渲染
在回到本次範例中,學習的重點統整 >>
◆ v-bind 屬性綁定:
- 用於標籤的「屬性」上,像是常見的
id
、class
、圖片的src
、連結的href
…等。 - 原完整寫法為
v-bind:屬性名稱=""
,可簡寫成:屬性名稱=""
。
[ html ]
<div id="app">
<p :id="aaa">show the idName = "{{ aaa }}"</p> <!-- 利用v-bind將data中的變數帶入 -->
<button :disabled="cantclick">Click</button> <!-- 利用v-bind將data中的變數帶入 -->
</div>
[ vue.js ]
Vue.createApp({
data(){
return{
aaa: 'Hello_idName', // 將要取的id名稱存入 data 變數中
cantclick: true, // 將disabled 設定為 true 存入 data 變數中
}
}
}).mount('#app')
◆ v-on 事件綁定:
- 使用方式 :
v-on:事件名稱="運算式or呼叫方法"
,可直接寫在html中進行運算,也可將運算式寫在methods的方法內,再於html中呼叫methods的方法。 - 除了完整寫法
v-on:事件名稱="運算式or呼叫方法"
,也可簡寫成@事件名稱="運算式or呼叫方法"
。
[ html ]
<div id="app">
<div class="container">
<div>
<input v-model="fullCount">
<button @click="fullCount++">運算式寫在html中</button> <!-- 寫在html中的運算式不需要加this-->
<span>@click="fullCount++"</span>
</div>
<div>
<input v-model="shortCount">
<button @click="shortWriting">methods呼叫方法</button>
<span>@click="shortWriting"</span>
</div>
</div>
</div>
[ vue.js ]
Vue.createApp({
data(){
return{
fullCount: 0,
shortCount: 1,
}
},
methods:{
shortWriting(){
this.shortCount++;
}
}
}).mount('#app')
◆ v-if、v-else-if、v-else:
- 如同Javascript中的if、else if、else一樣,針對不同的條件設定進行判斷。
[ html ]
<div id="app">
<input v-model="count">
<button @click="count++">plus</button>
<button @click="count = 0">reset</button>
<h4 v-if="count===0" style="color:red;">TestA</h4> <!-- 判斷數字0時,字體顏色為紅色 -->
<h4 v-else-if="count <= 3" style="color:blue;">TestB</h4> <!-- 判斷數字<=3時,字體顏色為藍色 -->
<h4 v-else style="color:green;">TestB</h4> <!-- 判斷數字不是0,也不是<=3時,字體顏色為綠色 -->
</div>
[ vue.js ]
Vue.createApp({
data(){
return{
count: 0,
}
},
}).mount('#app')
§ 補充紀錄:
- 若要顯示或隱藏某個元素,可使用上述說的
v-if
或是v-show
來完成,兩個顯示出來的成效差不多,但在元素為隱藏時v-if
會直接移除元素,而v-show
會保留原素,僅透過css的display:none將元素隱藏。 v-if
資源耗損較高;v-show
資源耗損較低。
《 學習過程:範例實作》
透過以上的學習,在這次的範例練習中,我們先將不同表情的圖片放進data,並且在methods中設定「增加」以及「減少」的按鈕,另外我希望數字的range只在0~10之間,所以分別在「增加」的按鈕中判斷數字最多加到10,在「減少」的按鈕中判斷數字最少減到0。(↓)
[ vue.js ]
Vue.createApp({
data(){
return{
count: 0,
body:'./vueTest5/link/body.png', // 身體和臉
face1:'./vueTest5/link/face-1.png', // 哭哭表情
face2:'./vueTest5/link/face-2.png', // 委屈表情
face3:'./vueTest5/link/face-4.png', // 開心表情
}
},
methods:{
// 設定增加的按鈕
plus(){
// 數字小於10時,每按一次增加1
if(this.count < 10){
this.count++;
}
// 當數字到達10時,就無法再往上加
else{
this.count = 10;
}
},
// 設定減少的按鈕
minus(){
// 數字大於10時,每按一次增加1
if(this.count > 0){
this.count--;
}
// 當數字到達0時,就無法再往下減
else{
this.count = 0;
}
}
}
}).mount('#app')
接下來就是將以上的設定,在html中的元素上進行綁定的動作(↓)
[ html ]
<div class="scoreArea text-center">
<div class="point-title">心情指數</div>
<div class="d-flex justify-content-center align-items-center">
<div @click="minus" class="countBtn px-1 d-flex justify-content-center align-items-center"> <!--將「增加」的方法,利用v-on:click進行事件綁定-->
<i class="fa-solid fa-minus"></i>
</div>
<p class="score p-1">{{count}}</p>
<div @click="plus" class="countBtn p-1 d-flex justify-content-center align-items-center"> <!--將「減少」的方法,利用v-on:click進行事件綁定-->
<i class="fa-solid fa-plus"></i>
</div>
</div>
</div>
為了將數字的range只在0~10之間顯示出來能夠更明顯,所以我在「增加」以及「減少」的按鈕上,將已設置好的css className,利用 v-bind屬性綁定
的方式給予判斷是否要增加className。(↓)
[ css ]
/* ------------- 背景呈現灰色 ------------- */
.bg-gray{
background-color: #d9d9d9;
}
[ html ]
<div class="scoreArea text-center">
<div class="point-title">心情指數</div>
<div class="d-flex justify-content-center align-items-center">
<div @click="minus" class="countBtn px-1 d-flex justify-content-center align-items-center" :class="{'bg-gray': count === 0}"> <!-- 利用v-bind屬性綁定,並判斷數字為0加上className -->
<i class="fa-solid fa-minus"></i>
</div>
<p class="score p-1">{{count}}</p>
<div @click="plus" class="countBtn p-1 d-flex justify-content-center align-items-center" :class="{'bg-gray': count === 10}"> <!-- 利用v-bind屬性綁定,並判斷數字為10加上className -->
<i class="fa-solid fa-plus"></i>
</div>
</div>
</div>
最後就是圖片表情的部分,利用 v-if
、v-else-if
、 v-else
來判斷什麼表情要在數字到達多少的時候進行變換。(↓)
[ html ]
<div class="face-box">
<img :src="face1" v-if="count <=3" > <!-- 哭哭表情,在數字<=3時顯示 -->
<img :src="face2" v-else-if="count <= 6" > <!-- 委屈表情,在數字<=6時顯示 -->
<img :src="face3" v-else> <!-- 開心表情,在數字不是以上數字的範圍時顯示 -->
</div>
基本上就大功告成拉!d(`・∀・)b
《 完整程式碼紀錄 》
※需先引入Vue.js 3.0、Bootstrap 5、fontAwesome 6.4.0
◆ Html :
<div id="app">
<div class="container">
<div class="content d-flex flex-column justify-content-center align-items-center vh-100">
<div class="title text-center">
<h3 class="CN-title m-0">情緒表情管理</h3>
<p class="EG-title">Emotions Character</p>
</div>
<div class="imgBox mb-2">
<div class="body-box">
<img :src="body"></img>
</div>
<div class="face-box">
<img :src="face1" v-if="count <=3" > <!-- 哭哭表情,在數字<=3時顯示 -->
<img :src="face2" v-else-if="count <= 6" > <!-- 委屈表情,在數字<=6時顯示 -->
<img :src="face3" v-else> <!-- 開心表情,在數字不是以上數字的範圍時顯示 -->
</div>
</div>
<div class="scoreArea text-center">
<div class="point-title">心情指數</div>
<div class="d-flex justify-content-center align-items-center">
<div @click="minus" class="countBtn px-1 d-flex justify-content-center align-items-center" :class="{'bg-gray': count === 0}"> <!-- 利用v-bind屬性綁定,並判斷是否加上className -->
<i class="fa-solid fa-minus"></i>
</div>
<p class="score p-1">{{count}}</p>
<div @click="plus" class="countBtn p-1 d-flex justify-content-center align-items-center" :class="{'bg-gray': count === 10}"> <!-- 利用v-bind屬性綁定,並判斷是否加上className -->
<i class="fa-solid fa-plus"></i>
</div>
</div>
</div>
</div>
</div>
</div>
◆ Javascript :
Vue.createApp({
data(){
return{
count: 0,
body:'./vueTest5/link/body.png', // 身體和臉
face1:'./vueTest5/link/face-1.png', // 哭哭表情
face2:'./vueTest5/link/face-2.png', // 委屈表情
face3:'./vueTest5/link/face-4.png', // 開心表情
}
},
methods:{
// 設定增加的按鈕
plus(){
// 數字小於10時,每按一次增加1
if(this.count < 10){
this.count++;
}
// 當數字到達10時,就無法再往上加
else{
this.count = 10;
}
},
// 設定減少的按鈕
minus(){
// 數字大於10時,每按一次增加1
if(this.count > 0){
this.count--;
}
// 當數字到達0時,就無法再往下減
else{
this.count = 0;
}
}
}
}).mount('#app')
◆ Css:
.content{
margin: auto;
}
/* ------------- 標題區 ------------- */
.CN-title{
font-size: 3rem;
color: #98c05b;
font-weight: 600;
}
.EG-title{
font-size: 2.2rem;
color: #e39952;
font-weight: 600;
}
/* ------------- 圖片區 ------------- */
.imgBox{
width: 60%;
position: relative;
}
@media screen and (min-width:768px){
.imgBox{
width: 45%;
position: relative;
}
}
@media screen and (min-width:992px){
.imgBox{
width: 25%;
position: relative;
}
}
.imgBox img{
width: 100%;
}
.face-box{
width: 55%;
position: absolute;
top: 15%;
left: 50%;
transform: translate(-50%, 50%);
}
/* ------------- 計分區 ------------- */
.scoreArea{
width: 100%;
}
.point-title{
color: #98c05b;
font-weight: 600;
font-size: 1.6rem;
}
.score{
width: 30%;
outline: 2px solid #98c05b;
color: #e39952;
font-weight: 600;
border-radius: 30px;
margin: 0 15px;
font-size: 1.2rem;
}
.countBtn{
width: 35px;
height: 35px;
border-radius: 35px;
cursor: pointer;
background-color: #98c05b;
}
i{
color: #fff;
}
.bg-gray{
background-color: #d9d9d9;
}