Vue學習筆記(二)動態繫結、計算屬性和事件監聽
一、為屬性繫結變數
在前面第一部分中,我們已經可以使用Vue
來動態繫結元素中的值了,但是我們該怎樣繫結為元素的屬性繫結一個變數呢?
1. v-bind的基本使用
我們可以使用v-bind
來為一個元素的屬性繫結一個在Vue
例項中定義好的變數,語法為:
v-bind:屬性名="表示式"
如下例所示:
var app = new Vue({
el: '#app',
data: {
imgURL: "https://dss1.baidu.com/6ONXsjip0QIZ8tyhnq/it/u=2296203553,2815843260&fm=58",
aHref: "http://baidu.com",
aName: "百度一下"
}
});
<div id="app"> <!-- 錯誤的做法 --> <!-- <img src="{{imgURL}}" alt=""> --> <img v-bind:src="imgURL" alt=""> <a v-bind:href="aHref">{{aName}}</a> <!-- 語法糖寫法,實際開發主要使用 --> <img :src="imgURL" alt=""> <a :href="aHref">{{aName}}</a> </div>
執行結果:
可以發現元素上屬性的值都可以由變數指定了,而 :屬性名="表示式"
是原始寫法的語法糖。
2. v-bind動態繫結class(物件語法)
語法:
v-bind:class="obj"
其中obj是一個js物件
,它的鍵
(變數名
)是某個類的類名
,值
為bool型別
,決定這個類是否繫結到該元素上
。
示例:
var app = new Vue({ el: '#app', data: { message: "你好啊", active: "active", isActive: true, isLine: true, }, methods: { btnClick: function () { this.isActive = !this.isActive; }, getClasses: function () { return { active: this.isActive, line: this.isLine }; } } });
.active {
color: red;
}
<div id="app">
<h2 class="active">第一個:{{message}}</h2>
<h2 :class="active">第二個:{{message}}</h2>
<!-- <h2 v-bind:class="{key1:value, key2:value}"></h2> -->
<!-- <h2 v-bind:class="{類名1:true, 類名2:false}"></h2> -->
<h2 class="title" v-bind:class="{active:isActive, line:isLine}">TrueOrFalse</h2>
<h2 class="title" v-bind:class="getClasses()">TrueOrFalse</h2>
<button v-on:click="btnClick">變色</button>
</div>
執行結果:
3. v-bind動態繫結class(陣列語法)
語法:
v-bind:class="list"
其中list
是一個js
陣列,其中的各個元素的值(字串
)是要繫結到該html
元素的class。
示例如下:
var app = new Vue({
el:'#app',
data:{
message:"你好啊",
active:"aaaa",
line:"bbbb",
},
methods:{
getClasses:function(){
return ["aaa","bbb"]
}
}
});
<div id="app">
<!-- 有單引號當做字串,無當做變數解析 -->
<h2 :class="['active','line']">{{message}} </h2>
<h2 :class="[active, line]">{{message}} </h2>
<h2 :class="getClasses()">{{message}} </h2>
</div>
執行結果:
4. v-bind動態繫結style(物件語法)
語法:
v-bind:style="obj"
其中obj
是Vue
例項中的一個js
物件,它的鍵
(變數名
)對應著css
的樣式屬性
,而值
對應著該樣式屬性的值,因此我們可以通過改變obj
中的某個鍵的值
來改變某個樣式
。
示例:
var app = new Vue({
el: '#app',
data: {
message: "你好啊",
finalSize: "100px",
finalInt: 100,
finalColor: "red"
},
methods: {
getStyles: function () {
return { fontSize: this.finalInt + 'px', color: this.finalColor }
},
addSize: function () {
if (this.finalInt < 130) {
this.finalInt += 10;
}
},
subSize: function () {
if (this.finalInt > 50) {
this.finalInt -= 10;
}
},
change: function () {
if (this.finalColor == 'blue') {
this.finalColor = 'red';
}
else {
this.finalColor = 'blue';
}
}
}
});
<div id="app">
<!-- <h2 :style="{key(屬性名):value(屬性值)}">{{message}} </h2> -->
<!-- <h2 :style="{fontSize:'50px'}">{{message}} </h2> -->
<!-- <h2 :style="{fontSize: finalSize}">{{message}}</h2> -->
<h2 :style="{fontSize: finalInt+'px', color: finalColor}">{{message}}</h2>
<h2 :style="getStyles()">{{message}}</h2>
<button @click="addSize">+</button>
<button @click="subSize">-</button>
<button @click="change">變色</button>
</div>
5. v-bind動態繫結style(陣列語法)
語法:
v-bind:style="list"
其中list
是一個js
陣列,其中的各個元素的值(物件
)是要繫結到該html
元素的style
鍵值對。其中鍵名
(變數名
)是style屬性名
,值是對應屬性值。
示例:
var app = new Vue({
el:'#app',
data:{
message:"你好啊",
baseStyle:{backgroundColor:'red'},
baseStyle1:{fontSize:'100px'}
},
methods:{}
});
<div id="app">
<h2 :style="[baseStyle, baseStyle1]">{{message}}</h2>
</div>
執行效果:
二、計算屬性
計算屬性被編寫到Vue
例項中的computed
屬性中
語法:
...
computed: {
計算屬性名(一般以名詞命名): function () {
// 相當於一個屬性
return xxx;
}
},
...
在語法上和方法的寫法基本相同。
1. 基本使用
var app = new Vue({
el: '#app',
data: {
firstName: "Lebron",
lastName: "James"
},
computed: {
fullName: function () {
// 相當於一個屬性
return this.firstName + " " + this.lastName;
}
},
methods: {
getFullName: function () {
return this.firstName + " " + this.lastName;
}
}
});
<div id="app">
<h2>{{firstName+" "+lastName}} </h2>
<h2>{{firstName}} {{lastName}} </h2>
<h2>{{getFullName()}} </h2>
<h2>{{fullName}} </h2>
</div>
執行結果:
可以發現使用方法
和計算屬性
都可以得到正確的結果。
2. 計算屬性的setter和getter
語法:
computed:{
計算屬性名:{
set:function(){
...
},
get:function(){
...
}
}
},
且計算屬性一般是沒有set
方法的
3. 計算屬性和method對比
最主要的差別是計算屬性在第一次返回結果後會有快取機制,若結果相同則不會再次計算,如下例所示:
var app = new Vue({
el: '#app',
data: {
firstName: "Kobe",
lastName: "Bryant",
},
computed: {
fullName: function () {
console.log("+++++")
return this.firstName + " " + this.lastName;
}
},
methods: {
getFullName: function () {
console.log("=========")
return this.firstName + " " + this.lastName;
}
}
});
<div id="app">
<h2>{{getFullName()}} </h2>
<h2>{{getFullName()}} </h2>
<h2>{{getFullName()}} </h2>
<h2>{{getFullName()}} </h2>
<!-- 快取機制 -->
<h2>{{fullName}} </h2>
<h2>{{fullName}} </h2>
<h2>{{fullName}} </h2>
<h2>{{fullName}} </h2>
</div>
執行結果:
可以發現getFullName()
方法執行了4次,而fullName
計算屬性只執行了1次
三、事件監聽
v-on的基本使用
可以參照上個部分的計數器。
1. v-on的引數問題
- 如果沒有傳入引數,則預設的引數為undifined
<button @click="click1()">按鈕1</button>
- 如果不寫函式的括號,則會預設將
event
物件傳遞過去
<button @click="click2">按鈕2</button>
- 如何手動獲得瀏覽器產生的event物件(使用
$event
)
<button @click="click3(123, $event)">按鈕3</button>
示例:
var app = new Vue({
el: '#app',
data: {},
methods: {
click1() {
console.log("按鈕1");
},
click2(abc) {
console.log(abc);
},
click3(abc, event) {
console.log(abc, event);
}
}
});
<div id="app">
<button @click="click1()">按鈕1</button>
<!-- 如果沒有傳入引數,則預設引數為undefined -->
<!-- <button @click="click2(123)">按鈕2</button> -->
<!-- <button @click="click2()">按鈕2</button> -->
<!-- 這種情況會將event物件傳遞過去 -->
<button @click="click2">按鈕2</button>
<!-- 如何手動獲得瀏覽器產生的event物件 -->
<button @click="click3(123, $event)">按鈕3</button>
</div>
執行結果:
2. v-on修飾符
click的.stop修飾符
這個修飾符可以阻止事件氣泡往下傳遞
對比:
<div @click="divClick">
inside div
<button @click="btnClick">按鈕</button>
</div>
和:
<div @click="divClick">
inside div
<button @click.stop="btnClick">按鈕</button>
</div>
第一種情況除了btnClick()
方法會被呼叫外,button
元素的父元素div
也會收到點選事件,進而divClick()
函式也會被呼叫。
而第二種情況則使用了.stop
阻止氣泡向下傳遞,只有btnClick()
方法會被呼叫。
click的.prevent修飾符
作用:阻止事件的預設行為,然後執行後面引用的method
。
例如:
<form action="baidu">
<input type="submit" value="提交" @click.prevent="submitClick">
</form>
這樣當點選按鈕時不會提交表單,而之後呼叫submitClick()
方法。
click的.once修飾符
作用:事件只監聽一次
<button @click.once="btn2Click">
按鈕2
</button>
這種情況下多次點選button
,只會執行一次btn2Click()
方法
keydown的.enter修飾符
作用:監聽鍵盤的點選
<input type="text" @keydown.enter="keyDown">