Vue的基礎(chǔ)語(yǔ)法(續(xù))

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è)修飾符就可以了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1. Vue 實(shí)例 1.1 創(chuàng)建一個(gè)Vue實(shí)例 一個(gè) Vue 應(yīng)用由一個(gè)通過(guò) new Vue 創(chuàng)建的根 Vue 實(shí)...
    王童孟閱讀 1,094評(píng)論 0 2
  • Vue 實(shí)例 屬性和方法 每個(gè) Vue 實(shí)例都會(huì)代理其 data 對(duì)象里所有的屬性:var data = { a:...
    云之外閱讀 2,373評(píng)論 0 6
  • 一、了解Vue.js 1.1.1 Vue.js是什么? 簡(jiǎn)單小巧、漸進(jìn)式、功能強(qiáng)大的技術(shù)棧 1.1.2 為什么學(xué)習(xí)...
    蔡華鵬閱讀 3,500評(píng)論 0 3
  • 一、vue是什么 vue是一套用于構(gòu)建用戶界面的漸進(jìn)式框架。與其它大型框架不同的是,vue被設(shè)計(jì)為可以自底向上逐層...
    勝過(guò)夜的美閱讀 6,626評(píng)論 0 3
  • vue學(xué)習(xí)筆記 安裝 Vue 提供一個(gè)官方命令行工具,可用于快速搭建大型單頁(yè)應(yīng)用。只需幾分鐘即可創(chuàng)建并啟動(dòng)一個(gè)帶熱...
    EL_PSY_CONGROO閱讀 1,148評(píng)論 0 5

友情鏈接更多精彩內(nèi)容