Vue的基礎(chǔ)語(yǔ)法(續(xù))
一、ES6基本語(yǔ)法學(xué)習(xí)
? 在后面的學(xué)習(xí)中需要使用到ES6的一些相關(guān)語(yǔ)法。所以,先對(duì)ES6的一些基本語(yǔ)法有些認(rèn)識(shí)
1.塊級(jí)作用域
在ES5中,不管是什么類(lèi)型的變量都是直接var就完事兒了,但是var是沒(méi)有塊級(jí)作用域。ES5中只有全局作用域和函數(shù)作用域
{
var i = 0;
}
console.log(i);
通過(guò)這個(gè)簡(jiǎn)單的例子就可以看出var是沒(méi)有塊級(jí)作用域的概念的,因?yàn)樵诖a塊外面是可以訪問(wèn)在代碼塊中定義的i變量的。
{
let i = 0;
}
console.log(i);
而let定義的變量是有塊級(jí)作用域的,因?yàn)樵诖a塊外面是無(wú)法訪問(wèn)到在代碼塊中定義的i變量的,說(shuō)明這個(gè)i變量的作用域就只是在代碼塊中。
沒(méi)有塊級(jí)作用域會(huì)引起什么不好的影響呢,下面我們通過(guò)一個(gè)例子來(lái)觀察一下。
<button>按鈕1</button>
<button>按鈕2</button>
<button>按鈕3</button>
<button>按鈕4</button>
<button>按鈕5</button>
<script>
var btns = document.getElementsByTagName("button");
for(var i = 0;i < btns.length;i++){
btns[i].addEventListener("click",function () {
console.log("第" + i + "個(gè)按鈕被點(diǎn)擊了");
});
}
</script>
在var定義的i進(jìn)行for循環(huán)中,每次循環(huán)的i都是同一個(gè)i變量,所以不管點(diǎn)擊哪一個(gè)都會(huì)打印第5個(gè)按鈕被點(diǎn)擊了,這很明顯無(wú)法滿足我們的需求。所以若是以ES5的語(yǔ)法來(lái)解決這個(gè)問(wèn)題呢就得找一個(gè)ES5中有作用域的東西,很明顯就是閉包了。
var btns = document.getElementsByTagName("button");
for(var i = 0;i < btns.length;i++){
(function(num) {
btns[num].addEventListener("click",function () {
console.log("第" + num + "個(gè)按鈕被點(diǎn)擊了");
});
})(i)
}
雖然這樣子能夠解決這個(gè)問(wèn)題,但是代碼看起來(lái)真的挺繁瑣的,而let就剛好解決了這個(gè)問(wèn)題
const btns = document.getElementsByTagName("button");
for(let i = 0;i < btns.length;i++){
btns[i].addEventListener("click",function () {
console.log("第" + i + "個(gè)按鈕被點(diǎn)擊了");
});
}
是不是太神奇了,其實(shí)這是因?yàn)槊恳淮窝h(huán)時(shí),i都在這一次循環(huán)中進(jìn)行了一次let聲明,這樣每次循環(huán)的i的作用域就只限于本次循環(huán),這樣就不會(huì)去干擾其它的循環(huán)了。
2.常量使用const定義
在ES6中還能將不需要改變的變量聲明為常量,使用關(guān)鍵字const,就和java中的final差不多,在代碼中若是能夠聲明為const的盡量聲明為const。
3.對(duì)象字面量的增強(qiáng)寫(xiě)法
ES5中這樣來(lái)定義對(duì)象中的屬性和方法
const app = {
name:"張三",
age:15,
sayName:function () {
console.log(this.name);
}
}
console.log(app.name);
app.sayName();
在ES6中可以這樣子來(lái)定義
let name = "張三";
let age = 15;
const app = {
name,
age,
sayName(){
console.log(this.name);
}
}
console.log(app.name);
app.sayName();
這就是ES6的對(duì)象增強(qiáng)寫(xiě)法
二、事件監(jiān)聽(tīng)
好的,接下來(lái)就繼續(xù)基礎(chǔ)知識(shí)的學(xué)習(xí),之前就學(xué)習(xí)過(guò)事件監(jiān)聽(tīng),就是通過(guò)v-on指令來(lái)進(jìn)行事件的監(jiān)聽(tīng)。
事件監(jiān)聽(tīng)時(shí)調(diào)用函數(shù)的參數(shù)問(wèn)題
1.若是不需要傳參數(shù),是可以省略不寫(xiě)小括號(hào)的。
<div id="app">
<h2>計(jì)數(shù)器:{{counter}}</h2>
<button @click="increment">+</button>
<button @click="decrement">-</button>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
counter:0
},
methods:{
increment(){
this.counter++;
},
decrement(){
this.counter--;
}
}
});
</script>
2.若是有一個(gè)形參,而調(diào)用的時(shí)候什么都不傳,則瀏覽器將事件對(duì)象傳進(jìn)去
<div id="app">
<h2>計(jì)數(shù)器:{{counter}}</h2>
<button @click="increment">+</button>
<button @click="decrement">-</button>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
counter:0
},
methods:{
increment(event){
this.counter++;
console.log("+++++++++++",event);
},
decrement(event){
this.counter--;
console.log("----------",event);
}
}
});
</script>
3.可以手動(dòng)的將事件對(duì)象傳入
<div id="app">
<h2>計(jì)數(shù)器:{{counter}}</h2>
<button @click="increment(name,$event)">+</button>
<button @click="decrement(name,$event)">-</button>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
name:"KOBE",
counter:0
},
methods:{
increment(name,event){
this.counter++;
console.log(name,"+++++++++++",event);
},
decrement(name,event){
this.counter--;
console.log(name,"----------",event);
}
}
});
</script>
直接通過(guò)$event就可以獲得事件對(duì)象
4.v-on的修飾符
? 有時(shí)候,在點(diǎn)擊一個(gè)超鏈接的時(shí)候我們不想要進(jìn)行跳轉(zhuǎn),就是想要阻止它的默認(rèn)行為,還有些時(shí)候觸發(fā)子元素的事件的時(shí)候我們不想要父元素的同類(lèi)事件也被觸發(fā),就是想要阻止事件冒泡。若是以前,我們就是通過(guò)事件對(duì)象的preventDefault和stopPropagation方法來(lái)實(shí)現(xiàn),而現(xiàn)在通過(guò)v-on的修飾符就能實(shí)現(xiàn)這些功能。
4.1 在點(diǎn)擊一個(gè)超鏈接的時(shí)候我們不想要進(jìn)行跳轉(zhuǎn),prevent修飾符的使用
<div id="app">
<a href="baidu" @click.prevent="btnClick">百度一下</a>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊,李銀河!'
},
methods:{
btnClick(){
console.log("the a tag is clicked...");
}
}
});
</script>
4.2 在點(diǎn)擊子元素時(shí)不想要父元素也響應(yīng),stop修飾符的使用
<div id="app" @click="fatherClick">
<label for="userName">
<input type="text" id="userName" placeholder="用戶名">
</label>
<h2 @click.stop="sonClick">{{message}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊,李銀河!'
},
methods:{
fatherClick(){
console.log("father is clicked...");
},
sonClick(){
console.log("son is clicked...");
}
}
});
</script>
4.3若是只希望某個(gè)事件只發(fā)生一次,在jQuery中通過(guò)One()來(lái)綁定事件,而Vue中只需要加一個(gè)once修飾符就可以了。
<div id="app" >
<h2 @click.once="sonClick">{{message}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊,李銀河!'
},
methods:{
sonClick(){
console.log("the title is clicked...");
}
}
});
</script>
4.4若是想要監(jiān)聽(tīng)某個(gè)鍵觸發(fā)的事件,在原生js中我們可能需要將事件對(duì)象傳入事件回調(diào)函數(shù)中進(jìn)行判斷,當(dāng)?shù)拇_是我們想要監(jiān)聽(tīng)的鍵時(shí)才做相應(yīng)的操作。而在Vue中只需要將這個(gè)鍵的鍵值或者英文名作為修飾符就可以做到了。語(yǔ)法格式:@keyUp(某些鍵觸發(fā)的事件).{keyCode | keyAlias} - 只當(dāng)事件是從特定鍵觸發(fā)時(shí)才觸發(fā)回調(diào)。
<div id="app" >
<input type="text" @keyUp.enter="enterKeyUp"/>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊,李銀河!'
},
methods:{
enterKeyUp(){
console.log("the enter keyUp...");
}
}
});
</script>
三、條件判斷
1.條件判斷簡(jiǎn)述
條件判斷主要由三個(gè)指令構(gòu)成,分別是v-if、v-else-if和v-else,其實(shí)和js的條件判斷,和jstl核心庫(kù)的if指令都差不多,語(yǔ)法格式:v-if="這里放一個(gè)能夠產(chǎn)生布爾值的表達(dá)式、變量或者函數(shù)"。
<div id="app">
<h2 v-if="score>=90">優(yōu)秀</h2>
<h2 v-else-if="score>=80">良好</h2>
<h2 v-else-if="score>=60">及格</h2>
<h2 v-else>不及格</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
score: 90
}
});
</script>
需要注意,只有以if結(jié)尾的才需要加判斷表達(dá)式或者變量,v-else就直接是上面所有條件并集的取反,是不需要再加判斷式的。就像是else后面沒(méi)有()寫(xiě)判斷表達(dá)式一樣.
<div id="app">
<button @click="btnClick">點(diǎn)擊隱藏下面文字</button>
<h2 v-if="isShow">我現(xiàn)在正在顯示</h2>
<h2 v-else>我被隱藏了</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
isShow : true
},
methods:{
btnClick(){
this.isShow = !this.isShow;
}
}
});
</script>
2.登錄切換方式小案例
在很多網(wǎng)站登錄時(shí)都有個(gè)選擇登錄形式,比如說(shuō)用戶賬號(hào)或者郵箱這種登錄方式,下面就做一個(gè)這種小案例。
<div id="app">
<label for="inputType">
<select id="inputType" :value="type" @change="changeType($event)">
<option value="userName">用戶賬號(hào)</option>
<option value="email">郵箱</option>
</select>
</label>
<span v-if="type == 'userName'">
<label for="username">用戶賬號(hào)</label>
<input type="text" id="username" placeholder="用戶賬號(hào)">
</span>
<span v-else>
<label for="email">用戶郵箱</label>
<input type="text" id="email" placeholder="用戶郵箱">
</span>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
type:"userName"
},
methods:{
changeType($event){
this.type = $event.target.value;
}
}
});
</script>
上面的例子我是將下拉框和vue實(shí)例進(jìn)行了一個(gè)雙向的綁定,后面我們會(huì)學(xué)到一個(gè)叫做v-model的指令就是這種原理。
3.Vue的元素復(fù)用
? 上面的小案例有個(gè)小問(wèn)題,就是切換時(shí)原來(lái)輸入的東西沒(méi)有被清空而是完完全全的留在了另外類(lèi)型的輸入框中,這是因?yàn)閂ue在進(jìn)行DOM渲染時(shí),出于性能考慮,它會(huì)先去找有沒(méi)有能夠復(fù)用的元素,有的話就比較可復(fù)用元素和目標(biāo)元素的不同,進(jìn)行修改后直接顯示,而value值不會(huì)被修改。所以,想要解決這種問(wèn)題的話就要給每一個(gè)輸入框添加一個(gè)key,只要key不同它就判斷這是不能復(fù)用的,就會(huì)重新創(chuàng)建一個(gè)輸入框了。
<div id="app">
<label for="inputType">
<select id="inputType" :value="type" @change="changeType($event)">
<option value="userName">用戶賬號(hào)</option>
<option value="email">郵箱</option>
</select>
</label>
<span v-if="type == 'userName'">
<label for="username">用戶賬號(hào)</label>
<input type="text" id="username" placeholder="用戶賬號(hào)" key="userName">
</span>
<span v-else>
<label for="email">用戶郵箱</label>
<input type="text" id="email" placeholder="用戶郵箱" key="email">
</span>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
type:"userName"
},
methods:{
changeType($event){
this.type = $event.target.value;
}
}
});
</script>
4.v-show指令的使用以及和v-if等指令的差別
<div id="app">
<h2 v-show="isShow">
{{message}}
</h2>
<h2 v-if="isShow">
{{message}}
</h2>
<button @click="toggleShow">點(diǎn)擊切換顯示</button>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊,李銀河!',
isShow:true
},
methods:{
toggleShow(){
this.isShow = !this.isShow;
}
}
});
</script>
易知,v-show指令若是不滿足的時(shí)候就只是設(shè)置display:none,而若是條件判斷指令v-if、v-else、v-else-if指令就是直接從整個(gè)頁(yè)面中刪除掉整個(gè)html代碼塊。
四、循環(huán)遍歷
1、v-for指令的使用
v-for指令可以用來(lái)遍歷數(shù)組數(shù)據(jù),將數(shù)組中的數(shù)據(jù)都拿出來(lái)進(jìn)行顯示。也能遍歷對(duì)象中的數(shù)據(jù),將這個(gè)對(duì)象的所有屬性拿出來(lái)進(jìn)行顯示。
<div id="app">
<ul>
<li v-for="(movie,index) in movies">{{index}}-{{movie}}</li>
</ul>
<ul>
<li v-for="(movie,index) of movies">{{index}}-{{movie}}</li>
</ul>
<ul>
<li v-for="(value,key,index) in author">{{index}}-{{key}}:{{value}}</li>
</ul>
<ul>
<li v-for="(value,key,index) of author">{{index}}-{{key}}:{{value}}</li>
</ul>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
movies:['海賊王','進(jìn)擊的巨人','刀劍神域','哆啦A夢(mèng)'],
author:{
name:'waigo',
age:20,
sex:'男',
height:180
}
}
});
</script>
這里有個(gè)有趣的點(diǎn),就是使用v-for指令的時(shí)候,我分別使用了in和of,我們知道在普通的for循環(huán)中使用in關(guān)鍵之取出來(lái)的是元素的下標(biāo),而使用of取出來(lái)的是這個(gè)元素的本身,但是在v-for指令中,不管是in還是for取出來(lái)的都是這個(gè)元素本身,而且控制臺(tái)也沒(méi)有報(bào)錯(cuò)。
還需要注意的一個(gè)點(diǎn),在遍歷一個(gè)對(duì)象的時(shí)候某個(gè)屬性的value是先被拿出來(lái)的,要把value放在key的前面。這個(gè)順序還是有考究的,重要的東西它會(huì)先取出來(lái),所以我們?cè)诒闅v數(shù)組的小括號(hào)中要把movie放在index前面。在遍歷對(duì)象的屬性中要把value放在最前面,key隨后,index最后,不然它賦值會(huì)出問(wèn)題的。
若是小括號(hào)就一個(gè)值那么傳進(jìn)去的就是value,若是兩個(gè)值,那就是value,key
五、key屬性
前面我們?cè)谧銮袚Q登錄形式的小案例的時(shí)候提到過(guò)Vue復(fù)用的問(wèn)題,那時(shí)候我說(shuō)若是Key相同就會(huì)直接復(fù)用,從而提高效率?,F(xiàn)在我們?cè)賮?lái)簡(jiǎn)單了解一下這個(gè)key屬性,Vue的官網(wǎng)推薦我們?cè)谑褂胿-for的時(shí)候給每個(gè)元素或組件添加一個(gè)key屬性。
這其中的原因和Vue的虛擬DOM的Diff算法有關(guān),我目前不清楚Diff算法是怎么運(yùn)算的,我的理解是這樣。如果v-for遍歷的那個(gè)數(shù)組或者屬性發(fā)生了改變,那么Vue就會(huì)先去比對(duì)已經(jīng)存在的元素的key和目標(biāo)元素的key 若是Key相同的,再比較其中的其它屬性啊什么的,就是看有哪些差別,然后就修改差別后直接復(fù)用原先的元素就可以了。所以若是v-for遍歷的那個(gè)對(duì)象或者數(shù)組中間插入了一個(gè)新的數(shù)據(jù),那么若是將key設(shè)置為數(shù)據(jù)本身(就是遍歷時(shí)候取出來(lái)的item),那么比對(duì)Key的時(shí)候就會(huì)發(fā)現(xiàn)兩個(gè)是一模一樣的,就不用修改什么直接復(fù)用了,這樣就能提高效率了。
<div id="app">
<ul>
<li v-for="word in letters" :key="word">{{word}}</li>
</ul>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
letters: ['A', 'B', 'C', 'D', 'E']
}
})
</script>
就是這樣來(lái)寫(xiě)那個(gè)key??梢栽诳刂婆_(tái)使用splice方法在B和C中間插入一個(gè)F,雖然也看不出效率有沒(méi)有提高。
六、數(shù)組方法,以及那些數(shù)組操作是響應(yīng)式的?
對(duì)數(shù)組進(jìn)行響應(yīng)式操作的主要有:
splice(賊強(qiáng)的一個(gè)方法,基本上接下來(lái)的方法能做的它都能做,別人做不了的它也能做),shift,unshift,reverse,push,sort,pop
1.splice方法,能夠插入元素,替換元素,刪除元素,返回一個(gè)空數(shù)組
語(yǔ)法格式: splice(開(kāi)始索引,刪除幾個(gè)元素,想要插入的數(shù)據(jù))
2.shift方法,將數(shù)組第一個(gè)元素刪除,返回刪除的元素
3.unshift方法,在最前面添加一個(gè)元素,返回當(dāng)前數(shù)組長(zhǎng)度
4.push和pop,就像是壓棧和彈棧一樣,一個(gè)是往最后添加一個(gè)元素,一個(gè)是刪除最后一個(gè)元素
? 4.1 pop,返回刪除的元素
? 4.2 push,返回當(dāng)前數(shù)組長(zhǎng)度
5.sort,對(duì)數(shù)組中的元素進(jìn)行排序,返回排序好的數(shù)組
6.reverse翻轉(zhuǎn)數(shù)組,就是跟蚯蚓掉頭一樣,返回排序好的數(shù)組
<div id="app">
<ul>
<li v-for="(movie,index) in movies">{{index}}-{{movie}}</li>
</ul>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
movies:['海賊王','進(jìn)擊的巨人','刀劍神域','哆啦A夢(mèng)']
}
});
</script>
通過(guò)這個(gè)案例,在控制臺(tái)使用上述方法,易知這些方法都是響應(yīng)式的,但是對(duì)數(shù)組索引對(duì)應(yīng)的值進(jìn)行操作不是響應(yīng)式的,像是app.movies[0] = "迪迦奧特曼",雖然元素的確改變了,但是渲染出來(lái)的數(shù)據(jù)并沒(méi)有改變。
七、小案例:遍歷電影,點(diǎn)擊某個(gè)電影,點(diǎn)擊的電影變成紅色
<style>
.active {
color: red;
}
</style>
</head>
<body>
<div id="app">
<ul>
<li
v-for="(movie,index) in movies"
:class="{active:currentIndex === index}"
@click="movieChoose(index)"
>{{index + 1}}-{{movie}}</li>
</ul>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
movies: ['海王', '海賊王', '加勒比海盜', '海爾兄弟'],
currentIndex : 0
},
methods: {
movieChoose(index){
this.currentIndex = index;
}
}
})
</script>
八、階段性案例,書(shū)籍購(gòu)物車(chē)案例
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="app">
<table>
<thead>
<tr>
<th></th>
<th>書(shū)籍名稱</th>
<th>出版日期</th>
<th>價(jià)格</th>
<th>購(gòu)買(mǎi)數(shù)量</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="(book,index) in books">
<td>{{book.id}}</td>
<td>{{book.name}}</td>
<td>{{book.date}}</td>
<td>{{book.price | priceFilter}}</td>
<td>
<button @click="decrement(index)" :disabled="book.count<=1">-</button>
{{book.count}}
<button @click="increment(index)">+</button>
</td>
<td><button @click="removeBook(index)">移除</button></td>
</tr>
</tbody>
</table>
<h2>總價(jià)格:{{totalPrice}}</h2>
</div>
<script src="../js/vue.js"></script>
<script src="./main.js"></script>
</body>
</html>
CSS
table {
border: 1px solid #e9e9e9;
border-collapse: collapse;
border-spacing: 0;
}
th, td {
padding: 8px 16px;
border: 1px solid #e9e9e9;
text-align: left;
}
th {
background-color: #f7f7f7;
color: #5c6b77;
font-weight: 600;
}
JS
const app = new Vue({
el:"#app",
data:{
books: [
{
id: 1,
name: '《算法導(dǎo)論》',
date: '2006-9',
price: 85.00,
count: 1
},
{
id: 2,
name: '《UNIX編程藝術(shù)》',
date: '2006-2',
price: 59.00,
count: 1
},
{
id: 3,
name: '《編程珠璣》',
date: '2008-10',
price: 39.00,
count: 1
},
{
id: 4,
name: '《代碼大全》',
date: '2006-3',
price: 128.00,
count: 1
},
]
},
methods:{
increment(index){
this.books[index].count++;
},
decrement(index){
this.books[index].count--;
},
removeBook(index){
this.books.splice(index,1);
}
},
filters:{
priceFilter(price){
return "¥" + price.toFixed(2);
}
},
computed:{
totalPrice(){
//遍歷books計(jì)算總價(jià)格
// let total = 0;
// for(let i = 0;i < this.books.length;i++){
// total += this.books[i].count*this.books[i].price;
// }
// return total;
// let total = 0;
// for(let book of this.books){
// total += book.count*book.price;
// }
// return total;
//使用js高階函數(shù)計(jì)算總價(jià)格
return this.books.reduce(function (preValue,book) {
return preValue+ book.count * book.price;
},0);
}
}
});
上面使用到了Vue實(shí)例對(duì)象中的一個(gè)叫做filters的屬性,下面介紹一下這個(gè)屬性。就是可以在這里定義一些方法,然后在用Mustache語(yǔ)法顯示數(shù)據(jù)的時(shí)候可以對(duì)值做一些處理,使用也很簡(jiǎn)單就是直接{{想要處理的值 | 對(duì)這個(gè)值進(jìn)行處理的fliter方法}},然后Vue會(huì)自動(dòng)將這個(gè)值作為參數(shù)傳入filter方法并且將這個(gè)方法的返回值展示出來(lái)。
九、JS高階函數(shù)
<div id="app">
<!-- 需求:將num數(shù)組中的數(shù)據(jù)中小于100的數(shù)據(jù)取出來(lái)并且乘以2,然后返回他們的和-->
<h2>處理后的數(shù)據(jù)為:{{resolveData}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
num: [10, 20, 111, 222, 444, 40, 50]
},
computed:{
resolveData(){
let arr = this.num.filter(function (n) {
//filter遍歷數(shù)組,每次需要返回一個(gè)布爾值
return n < 100;
});
console.log(arr);//返回每次遍歷中返回true的元素組成的數(shù)組
arr = arr.map(function (n) {
return n*2;//返回每次遍歷時(shí)做的處理,然后存入一個(gè)新數(shù)組中
});//返回一個(gè)新數(shù)組
console.log(arr);
//reduce方法對(duì)數(shù)組進(jìn)行匯總
arr = arr.reduce(function (preVal,curVal) {
//preVal是上一次遍歷的結(jié)果,curVal是當(dāng)前數(shù)據(jù)
return preVal + curVal;
},0);//0是第一次時(shí)的preVal,初始值
console.log(arr);
//就是遞歸的那種思想
//第一次時(shí)
//preVal + curVal ==> 0 + 20
//第二次時(shí)
//preVal + curVal ==> (0 + 20)+ 40
//第三次時(shí)
//preVal + curVal ==> ((0 + 20)+ 40)+ 80
//第一次時(shí)
//preVal + curVal ==> (((0 + 20)+ 40)+ 80) + 100 ===> 240
return arr;
}
}
});
</script>
當(dāng)然上面的例子還能這么寫(xiě)
return this.num.filter(n => n < 100).map(n => n*2).reduce((preVal,curVal) => preVal+curVal);
或者,這么寫(xiě)
return this.num.filter(function (n) {
return n<100;
}).map(function (n) {
return n*2;
}).reduce(function (preVal,curVal) {
return preVal+curVal;
},0)
這就是鏈?zhǔn)骄幊?,函?shù)式編程的思想
十、v-model
在之前寫(xiě)用戶登錄形式的切換小案例的時(shí)候,我曾經(jīng)寫(xiě)過(guò)一個(gè)雙向綁定,然后說(shuō)之后有個(gè)叫做v-model的指令可以進(jìn)行雙向綁定,現(xiàn)在就學(xué)一下v-model。
1.v-model的基本使用
<div id="app">
<label for="message">
輸入Message
<input type="text" v-model="message" id="message">
</label>
<h2>{{message}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊,李銀河!'
}
});
</script>
這個(gè)小例子就是展現(xiàn)了v-model的基本用法,就是將某個(gè)具有value的Dom元素綁定到data中的某個(gè)變量上。
2.v-model的原理
<div id="app">
<label for="message">
輸入Message
<input type="text" :value="message" id="message" @input="message = $event.target.value">
</label>
<h2>{{message}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊,李銀河!'
}
});
</script>
其實(shí)像這樣,我們也是能自己寫(xiě)一個(gè)雙向綁定的,不過(guò)監(jiān)聽(tīng)input事件改變message的值和人家v-model比起來(lái)還是有不足之處,就是用戶其實(shí)還沒(méi)輸入進(jìn)輸入框,還在打拼音的時(shí)候就已經(jīng)修改了message的值了。
3.v-model結(jié)合radio類(lèi)型
<div id="app">
<label for="male">
<input type="radio" id="male" value="男" v-model="sex">男
</label>
<label for="female">
<input type="radio" id="female" value="女" v-model="sex">女
</label>
<h2>您選擇的性別是:{{sex}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
sex : "男"
}
});
</script>
在之前做單選框的時(shí)候我們需要為每一個(gè)radio添加相同的name才能不會(huì)同時(shí)選上,現(xiàn)在綁定同一個(gè)變量就可以解決這個(gè)問(wèn)題了。
4.v-model結(jié)合checkbox類(lèi)型
<div id="app">
<input type="checkbox" value="唱" v-model="hobbies">唱
<input type="checkbox" value="跳" v-model="hobbies">跳
<input type="checkbox" value="rap" v-model="hobbies">rap
<input type="checkbox" value="籃球" v-model="hobbies">籃球
<input type="checkbox" value="抽煙" v-model="hobbies">抽煙
<input type="checkbox" value="喝酒" v-model="hobbies">喝酒
<input type="checkbox" value="燙頭" v-model="hobbies">燙頭
<ul>您的愛(ài)好是:
<li v-for="hobby in hobbies" :key="hobby">{{hobby}}</li>
</ul>
<label v-for="hobby in originHobbies" :for="hobby">
<input type="checkbox" :value="hobby" v-model="hobbies" :id="hobby">{{hobby}}
</label>
<label for="lisence">
<input type="checkbox" value="agree" v-model="isAgree" id="lisence">同意協(xié)議
</label>
<button :disabled="!isAgree">下一步</button>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
hobbies:[],
isAgree:false,
originHobbies: ['抽煙','喝酒','燙頭','唱','跳','RAP','籃球']
}
});
</script>
5.v-model結(jié)合select類(lèi)型
<div id="app">
<label for="fruit">選擇您喜歡吃的水果吧
<select id="fruit" v-model="fruits" multiple size="2">
<option v-for="fruit in originFruits" :value="fruit" :key="fruit">{{fruit}}</option>
</select>
</label>
<ul>這些是您喜歡的水果
<li v-for="fruit in fruits" :key="fruit">{{fruit}}</li>
</ul>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
originFruits:['蘋(píng)果','香蕉','李子','桃子','檸檬'],
fruits:[]
}
});
</script>
十一、v-model修飾符的使用
和v-on的修飾符一樣使用,這些個(gè)修飾符用在radio,select,checkbox中沒(méi)什么意義,就是用在輸入框中的。
1.lazy修飾符
? 我們可能不希望每次用戶輸入都更新data中的數(shù)據(jù),這樣可能會(huì)浪費(fèi)性能。默認(rèn)情況下會(huì)根據(jù)用戶輸入實(shí)時(shí)刷新data中的數(shù)據(jù)。而使用了lazy修飾符就可以在輸入框失去焦點(diǎn)或者敲擊回車(chē)后更新data中的數(shù)據(jù)。
<div id="app">
<label for="message">
輸入Message
<input type="text" v-model.lazy="message" id="message">
</label>
<h2>{{message}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊,李銀河!'
}
});
</script>
2.number修飾符
? 在輸入框中輸入的數(shù)字綁定到data中的變量中時(shí)默認(rèn)都會(huì)變成String,若是想要輸入是數(shù)字number的話,要使用number修飾符
<div id="app">
<label for="message">
輸入Message
<input type="number" v-model.number="message" id="message">
</label>
<h2>{{typeof message}}-{{message}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: 0
}
});
</script>
使用了number修飾符后,若是輸入了不是數(shù)字的內(nèi)容,data中的數(shù)據(jù)是不會(huì)發(fā)生改變的。
3.trim修飾符
<div id="app">
<label for="message">
輸入Message
<input type="text" v-model.trim="message" id="message">
</label>
<h2>-------{{message}}-------</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '還有詩(shī)和遠(yuǎn)方的田野'
}
});
</script>
由于瀏覽器會(huì)自動(dòng)消去多余的空格,所以從瀏覽器中看不出來(lái),可以從控制臺(tái)中查看值。the 修飾符 is really useful.特別是在檢查用戶注冊(cè)的問(wèn)題的時(shí)候,以前是通過(guò)trim函數(shù)來(lái)實(shí)現(xiàn)的,現(xiàn)在直接加一個(gè)修飾符就可以了。