天天看點

全棧工程師開發實戰之從入門到技術實戰之02--vue指令

第二章:vue指令和事件處理

回顧:

vue:

vue ?

發展曆史,産生背景

優勢:

核心:資料決定視圖,雙向資料綁定

MVC:

三層架構:

全棧工程師開發實戰之從入門到技術實戰之02--vue指令

MVVM: Model View ViewModel vue的執行個體對象

本章目标

  • 了解什麼是 Vue.js 指令
  • 了解 Vue.js 指令的用途
  • 掌握 Vue.js 指令的書寫規範
  • 能夠使用 Vue.js 指令完成部分頁面互動效果

一、vue指令

1.1 相關插件安裝

高亮代碼括号的插件

全棧工程師開發實戰之從入門到技術實戰之02--vue指令

vue的代碼提示插件

全棧工程師開發實戰之從入門到技術實戰之02--vue指令

[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-6kqd13Tt-1654938578648)(assets/image-20220202161926801.png)]

标簽重命名插件

全棧工程師開發實戰之從入門到技術實戰之02--vue指令

1.2 什麼是 Vue指令

指令 (Directives) 是帶有 ​

​v-​

​ 字首的特殊 attribute。指令 attribute 的值預期是單個 JavaScript 表達式。指令的職責是,當表達式的值改變時,将其産生的連帶影響,響應式地作用于 DOM。解析模闆/标簽(标簽屬性,标簽體内容,綁定事件等)

例如:

//點選toggle按鈕,會顯示紅色方塊,再次點選,紅色方塊消失,這裡就是通過控制屬性的真假,通過指令作用到紅色方塊上來控制方塊的顯示隐藏
<button v-on:click="isaaa = !isaaa">toggle</button>
<div class="block" v-show="isaaa"></div>      
全棧工程師開發實戰之從入門到技術實戰之02--vue指令

1.3 Vue.js 指令的書寫規範

//書寫位置:任意 HTML 元素的開始标簽内
<p v-if="seen">現在你看到我了</p>

//注意:一個開始标簽内可寫入多個指令,多個指令間使用空格分隔
<a href="javascript:;" :class="{active:timeflag}" @click="queryAll('time')">全部</a>      

1.4 常用指令

  • ​v-text​

    文法格式:​

    ​v-text='表達式'​

    ​作用相當于之前學習的DOM操作中的innerText屬性,會直接覆寫元素中原本的文本内容,實際開發中使用不多
<p v-text="name+'法撒旦'"></p>
<script>
let app = new Vue({
      el:'p',
      data:{
        stat:true,
        name:'張三'
      }
    })
</script>      
  • ​v-html​

    文法格式:​

    ​v-html='表達式'​

    ​作用相當于DOM操作中的innerHTML屬性,可以識别字元串中的标簽。
全棧工程師開發實戰之從入門到技術實戰之02--vue指令
<p v-html="msg"></p>
<script>
let app = new Vue({
      el:'p',
      data:{
        msg:'<h1>你好哈哈哈</h1>'
      }
    })
</script>      
  • **​

    ​v-if ​

    ​​

    ​v-else-if​

    ​​

    ​v-else​

    ​ **

    作用等同于js代碼中的 if else if elseif else 幫助我們按照需求去控制DOM元素的顯示與隐藏。

    文法格式:​

    ​v-if='表達式'​

    ​​

    ​v-else-if='表達式'​

    ​​

    ​v-else='表達式'​

    ​注意: v-if 和後續的v-else-if v-else都要連續使用,如果中間有間隔,效果是可以正常顯示的,但是,控制台會報錯。這個特性針對操作同級元素的時候來說。
<body>
    <div id="max">
        <ul v-if='num>10'>
            <li>你好哈哈1</li>
            <li>你好哈哈2</li>
            <li>你好哈哈3</li>
        </ul>
        <ul v-else="num>5">
            <li>你好嘿嘿1</li>
            <li>你好嘿嘿2</li>
            <li>你好嘿嘿3</li>
        </ul>
    </div>
</body>
<script>
    let app = new Vue({
        el: '#max',
        data: {
            num: 9
        }
    })
</script>      
  • ​v-show​

    控制元素是否顯示,作用等同于css樣式的display:none 或非none

    文法格式:​

    ​v-show='true/false'​

    ​; true為顯示,false為不顯示
<div id="max">
      <p v-show='stat'>你好哈哈哈</p>
      <button v-on:click='tiggleShow()'>點我</button>
    </div>
<script type="text/javascript">
    let app = new Vue({
      el:'#max',
      data:{
        stat:true,
      },
      methods:{
        tiggleShow(){
          this.stat = !this.stat;
        }
      }
    })
  
  </script>      
v-if與v-show差別:
  v-show指令的元素始終會被渲染到HTML
  它隻是簡單地為元素設定CSS的style屬性。當不滿足條件的元素被設定style="display:none"樣式
  v-if指令滿足條件是,會渲染到html中,不滿足條件時,是不會渲染到html中的

v-if 指令有更高的切換消耗
v-if當條件成立的時候會将元素加上,不成立的時候,就會移除dom,并且内部的指令不會執行
v-show 指令有更高的初始渲染消耗
v-show隻是簡單的隐藏和顯示
如果需要頻繁切換使用 v‐show 較好,如果在運作時條件不大可能改變 使用v‐if 較好      
  • ​v-for​

    ​ 循環周遊 #*

    v-for的作用等同于js代碼中的for循環,用于循環生成DOM結構,想循環哪個DOM結構,就在哪個DOM結構上添加v-for。

    但凡使用到v-for的地方 必須添加第二個屬性 :key=‘id’

<body>
    <div id="box">
        <!-- 周遊數組
        文法 v-for="(item,index) in arr"
            item 就表示數組中的每一個資料
            index表示下标
    -->
        <ul>
            <li v-for="(item,index) in arr">{{item}}</li>
        </ul>
        <!-- 周遊普通對象
            文法 v-for="(val,key,i) in arr"
            val 就表示對象中的每一個值
            key 就表示對象中的每一個鍵值
            i就是下标
        -->
        <ul>
            <li v-for="(val,key,i) in user">{{key}}--{{val}}--{{i}}</li>
        </ul>
        <!-- 周遊字元串 -->
        <ul>
            <li v-for="(item,i) in str">{{item}}</li>
        </ul>
    </div>
    <script>
        let app = new Vue({
            el: '#box',
            data: {
                arr: ['a', 'b', 'c'],
                user: { "name": '張三', "age": 18, "address": '鄭州' },
                str:'abcdefg'
            }
        })
    </script>
</body>      
  • ​v-on​

    ​ 綁定事件和事件處理

    vue的綁定事件的方式,隻需要把原生事件名字的on去掉就可以了

    例如: onclick === > @click/v-on:click onblur ===> @blur/v-on:blur

  • 普通用法
為 HTML 元素綁定事件監聽
  v-on:事件名稱 =‘函數名稱()’
    表達式可以是一個方法的名字或一個内聯語句
  簡寫文法:@事件名稱 =‘函數名稱()’
  注意:函數定義在 methods 配置項中

<button v-on:click='fn()'>toggle</button>
v-on: 可以簡寫成 @
<button @click='fn()'>toggle</button>      
  • ​v-bind​

    作用:為元素的屬性 動态的綁定值

v-bind可以在其名稱後面帶一個參數,參數通常是HTML元素的屬性(attribute),v-bind是動态綁定指令,預設情況下自帶屬性的值是固定的,為了能夠動态的給這些屬性添加/修改值可以使用v-bind指令
v-bind:屬性名 = ‘表達式’
簡寫形式:v-bind可以省略,直接書寫為 :屬性名 = ‘表達式’
<img v-bind:src="imageSrc"> 等價于  <img :src="imageSrc">   //綁定一個屬性      

v-bind:綁定class

//對象文法
我們可以傳給 v-bind:class 一個對象,以動态地切換 class:
格式:<div v-bind:class="{ 類名: 布爾值 }"></div>
//isActive是boolean屬性的參數,為true就給div添加類名active,為false就不添加
<div v-bind:class="{ active: isActive }"></div>
可以同時綁定多個類名,也可以和靜态類名同時存在
<div class="static" v-bind:class="{ active: isActive, 'text-danger': hasError }"></div>

//數組文法
我們可以把一個數組傳給 v-bind:class,以應用一個 class 清單:
<div v-bind:class="[activeClass, errorClass]"></div>
 data: {
  activeClass: 'active',
  errorClass: 'text-danger'
}

<div v-bind:class="[isActive ? activeClass : '', errorClass]"></div>
//綁定多個屬性
<div v-bind:class="{'textColor':isColor, 'textSize':isSize}">多個樣式的綁定</div>

 <div id="box">
        <a :href="url" v-bind:class='classname'>點我</a>
    </div>
    <script>
        new Vue({
            el:'#box',
            data:{
                url:'http://www.baidu.com',
                classname:['aaa','bbb','ccc']
            }
        })
    </script>      

v-bind:綁定内聯樣式

#對象文法
//v-bind:style 的對象文法十分直覺——看着非常像 CSS,但其實是一個 JavaScript 對象。CSS property 名可以用駝峰式 (camelCase) 或短橫線分隔 (kebab-case,記得用引号括起來) 來命名:
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
data: {
  activeColor: 'red',
  fontSize: 30
}
//直接綁定到一個樣式對象通常更好,這會讓模闆更清晰:
<div v-bind:style="styleObject"></div>
data: {
  styleObject: {
    color: 'red',
    fontSize: '13px'
  }
}

#數組文法
//v-bind:style 的數組文法可以将多個樣式對象應用到同一個元素上:
<div v-bind:style="[styleObject,baseStyles, overridingStyles]"></div>      
  • ​v-model​

    你可以用​​

    ​v-model​

    ​​ 指令在表單​

    ​<input>​

    ​​、​

    ​<textarea>​

    ​​ 及​

    ​<select>​

    ​ 元素上建立雙向資料綁定。它會根據控件類型自動選取正确的方法來更新元素。盡管有些神奇,但​

    ​v-model​

    ​​ 本質上不過是文法糖。它負責監聽使用者的輸入事件以更新資料,并對一些極端場景進行一些特殊處理。

    ​​

    ​v-model​

    ​​ 會忽略所有表單元素的​

    ​value​

    ​​、​

    ​checked​

    ​​、​

    ​selected​

    ​​ attribute 的初始值而總是将 Vue 執行個體的資料作為資料來源。你應該通過 JavaScript 在元件的​

    ​data​

    ​​ 選項中聲明初始值。

    v-model說白了就像監聽器一樣,會自動的将vue執行個體的值同步更新到表單中,同樣的也會把表達中的值同步到vue執行個體中。

    這就是雙向資料綁定。

    **注意:**隻有表單元素使用v-model使用才有意義,因為隻有表單元素才可以跟使用者互動。别的元素使用隻能顯示資料,沒有别的意義。

    對input框,操作的是value屬性的值:

<body>
    <div class="box">
        <input type="text" value="你好嘿嘿嘿" v-model='msg'>
        <br>
        {{msg}}
    </div>
    <script>
        new Vue({
            el:'.box',
            data:{
                msg:'你好哈哈哈'
            }
        })
    </script>      

```

對單個複選框操作的是 checked屬性的值:

<body>
    <div class="box">
        <input type="checkbox" v-model='b'>
        <br>
        {{b}}
    </div>
    <script>
        new Vue({
            el:'.box',
            data:{
                b:''
            }
        })
    </script>
</body>
此時vue執行個體中b的值會就跟複選框綁定到了一起。      

對多個複選框操作如果在vue執行個體中是用一個數組接收,接收到是一個數組,裡邊包含的是被選中的複選框的vlaue值

<body>
    <div class="box">
        <input type="checkbox" value="1" v-model='b'>
        <input type="checkbox" value="2" v-model='b'>
        <input type="checkbox" value="3" v-model='b'>
        <br>
        {{b}}
    </div>
    <script>
        new Vue({
            el:'.box',
            data:{
                b:[]
            }
        })
    </script>
  想讓哪個框預設選中,就直接把這個框的值寫入到vue的執行個體中去。      

對于單選框來說,拿到的是被選中的那個單選框的value屬性的值:

<body>
    <div class="box">
        <input type="radio" value="男" name="sex" v-model="s">男
        <input type="radio" value="女" name="sex" v-model="s">女
        <br>
        {{s}}
    </div>
    <script>
        new Vue({
            el:'.box',
            data:{
                s:""
            }
        })
    </script>
</body>      

對于下拉框來說,拿到的是被選中的那個選項的值

<body>
    <div class="box">
        <select name="" id="" v-model="selected" multiple>
            <option value="a">a</option>
            <option value="b">b</option>
            <option value="c">c</option>
            <option value="d">d</option>
        </select>
        <br>
        {{selected}}
    </div>
    <script>
        new Vue({
            el:'.box',
            data:{
                selected:''
            }
        })
    </script>
</body>
此時selected拿到的就是被選中的項的value值,如果是多選的下拉框,此時的selected值就是選中的多個框的value值。      
  • v-model的專用修飾符
.lazy - 取代 input 監聽 change 事件
    原本的資料綁定相當于對input框進行oninput事件監聽,使用v-model.lazy之後相當于把oninput事件換成了onchange事件
.number - 輸入字元串轉為有效的數字  自動轉換為數字
    <div id="app">
            <input type="text" v-model.number='num1'>+<input type="text" v-model.number='num2'>=<span>{{num1+num2}}</span>
        </div>
        <script>
            new Vue({
                el:'#app',
                data:{
                    num1:1,
                    num2:2
                }
            })
        </script>
.trim - 輸入首尾空格過濾      

1.5 事件處理

  • vue中的event事件對象:

    如果調用函數時不傳遞參數,那麼在函數中可以直接使用e來表示事件對象,但是如果進行參數的傳遞,在函數内部就無法再使用e了,此時 vue中給我們提供了一個 $event 來表示時間對象,隻需要調用函數時傳入即可。

擷取事件對象
    <div id="max">
        <button @click='fn($event)'>點我擷取事件對象</button>
    </div>
    <script>
        new Vue({
            el: '#max',
            methods: {
                fn(e){
                    console.log(e);
                }
            }
        })
    </script>      
  • 事件修飾符
v-on後面可以增加修飾符
<div @click.stop='fn()'>點我</div>
事件修飾符:
    常用:
        .stop:調用event.stopPropagation() 阻止事件冒泡
        .prevent : 調用event.preventDefault()阻止預設行為
    不常用:
        .self : 隻當事件是從偵聽器綁定的元素本身觸發時才觸發回調
            例如:如果不想添加冒泡事件,可以給父子級的元素都添加.self修飾符這樣就不會觸發冒泡事件,隻有在點選元素自身的時候才會觸發。
        .once:點選事件将隻會觸發一次
            事件隻會被觸發一次,觸發後,底層就會解綁事件 類似于jquery中one()事件綁定
        .capture:添加事件監聽器時使用事件捕獲模式
        .passive:滾動事件的預設行為 (即滾動行為) 将會立即觸發      
  • 按鍵修飾符

    在監聽鍵盤事件時,我們經常需要檢查詳細的按鍵。Vue 允許為​​

    ​v-on​

    ​ 在監聽鍵盤事件時添加按鍵修飾符:
<!-- 隻有在 `key` 是 `Enter` 時調用 `vm.submit()` -->
<input v-on:keyup.enter="submit">      

注意:​

​keyCode​

​​ 的事件用法​​已經被廢棄了​​并可能不會被最新的浏覽器支援。

使用 ​

​keyCode​

​ attribute 也是允許的:

<input v-on:keyup.13="fn1">enter鍵觸發
<input v-on:keyup.65="fn2">a鍵觸發      

為了在必要的情況下支援舊浏覽器,Vue 提供了絕大多數常用的按鍵碼的别名:

  • ​.enter​

  • ​.tab​

  • ​.delete​

    ​ (捕獲“删除”和“倒退”鍵)
  • ​.esc​

  • ​.space​

  • ​.up​

  • ​.down​

  • ​.left​

  • ​.right​

有一些按鍵 (​

​.esc​

​​ 以及所有的方向鍵) 在 IE9 中有不同的 ​

​key​

​ 值, 如果你想支援 IE9,這些内置的别名應該是首選。

你還可以通過全局 ​

​config.keyCodes​

​​ 對象​​自定義按鍵修飾符别名​​:

// 可以使用 `v-on:keyup.f1`

<div id="max">
        <input type="text" @keydown.aaa='fn4'>

    </div>
    <script>
        //單個定義
        Vue.config.keyCodes.f1 = 112
        //當以多個
        Vue.config.keyCodes = {
            aaa:65,
            bbb:66
        }
        new Vue({
            el: '#max',
            methods: {
                fn4(){
                    alert('a鍵被按下了');
                }

            }
        })
    </script>      
  • 系統修飾鍵
系統修飾鍵
    .ctrl
    .alt
    .shift
    .meta
注意:在 Mac 系統鍵盤上,meta 對應 command 鍵 (⌘)。在 Windows 系統鍵盤 meta 對應 Windows 徽标鍵 (⊞)。在 Sun 作業系統鍵盤上,meta 對應實心寶石鍵 (◆)。在其他特定鍵盤上,尤其在 MIT 和 Lisp 機器的鍵盤、以及其後繼産品,比如 Knight 鍵盤、space-cadet 鍵盤,meta 被标記為“META”。在 Symbolics 鍵盤上,meta 被标記為“META”或者“Meta”。

<!-- Alt + C -->同時按下alt鍵和c鍵
<input v-on:keyup.alt.67="handler">

#請注意: 修飾鍵與正常按鍵不同,在和 keyup 事件一起用時,事件觸發時修飾鍵必須處于按下狀态。換句話說,隻有在按住 ctrl 的情況下釋放其它按鍵,才能觸發 keyup.ctrl。而單單釋放 ctrl 也不會觸發事件。如果你想要這樣的行為,請為 ctrl 換用 keyCode:keyup.17。      
  • ​.exact​

    ​ 修飾符
2.5.0 新增
  • ​.exact​

    ​ 修飾符允許你控制由精确的系統修飾符組合觸發的事件。
<!-- 隻要按下的鍵中有ctrl鍵 事件就可以被觸發 -->
<button v-on:click.ctrl="onClick">A</button>

<!-- 有且隻有 Ctrl 被按下的時候才觸發 -->
<button v-on:click.ctrl.exact="onCtrlClick">A</button>

<!-- 沒有任何系統修飾符被按下的時候才觸發 -->
<button v-on:click.exact="onClick">A</button>      
  • 滑鼠按鈕修飾符
2.2.0 新增
  • ​.left​

  • ​.right​

  • ​.middle​

這些修飾符會限制處理函數僅響應特定的滑鼠按鈕。

當點選滑鼠右鍵時才會觸發事件
<button @click.right='fn()'>滑鼠修飾符</button>      

二、案例作業

案例1—注冊頁面

需求說明

使用常見表單元素布局注冊頁面

使用v-model指令完成對應資料的綁定

填寫的表單内容可以顯示在表單下方

全棧工程師開發實戰之從入門到技術實戰之02--vue指令

案例2—點選重新編輯

需求說明

點選“Edit Me”,下方出現文本框,可以自行修改文本

輸入框中的文字和頁面中的文字保持一緻

使用 v-show、v-on、v-model 指令

案例3—仿京東左側菜單

需求說明

完成京東左側菜單的頁面布局

使用 v-for 指令周遊子分類名稱,進而顯示子分類的清單

全棧工程師開發實戰之從入門到技術實戰之02--vue指令

案例4—導航切換

需求說明:

點選導覽列中的導航項目,目前被點選的項目内容會顯示在下方綠色方塊中,并且目前被點選項目的背景會變成紅色

使用 v-for 指令周遊顯示導航項目,使用v-on添加添加事件,使用v-bind指令動态綁定class和key屬性

全棧工程師開發實戰之從入門到技術實戰之02--vue指令

案例5—商品的增加,删除,上下架

全棧工程師開發實戰之從入門到技術實戰之02--vue指令
全棧工程師開發實戰之從入門到技術實戰之02--vue指令

需求:

  • 點選新增,添加商品,如果輸入框為空字元串則彈出提示框
  • 點選删除,删除對應的行
  • 點選操作欄中的上下架,改變對應的狀态
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="./lib/vue.js"></script>
    <style>
        td{
            height: 30px;
            text-align: center;
        }
    </style>
</head>
<body>
    <div id="app">
        <div>
            名稱: <input type="text" v-model.trim="gName">
            數量: <input type="text" v-model.number="gNum">
            是否上架: <select v-model="gState">
                <option value="true">上架</option>
                <option value="false">下架</option>
            </select>
            <button @click="addGoods">新增商品</button>
        </div>
        <table border="1" width="800px">
            <thead>
                <th><input type="checkbox" @change="checkAll" v-model="allState"></th>
                <th>編号</th>
                <th>名稱</th>
                <th>狀态</th>
                <th>數量</th>
                <th>操作</th>
            </thead>
            <tbody>
                <tr v-for="(item,index) in goods">
                    <td><input type="checkbox" v-model="item.isChecked" @change="reverseChk"></td>
                    <td>{{item.id}}</td>
                    <td>{{item.name}}</td>
                    <td>
                        <span v-if="item.state">上架狀态</span>
                        <span v-else>下架狀态</span>
                    </td>
                    <td><button @click="add(item.id)">+</button><span>{{item.num}}</span><button @click="sub(item.id,index)">-</button></td>
                    <td>
                        <button @click="del($event,item.id)">删除</button>
                        <button v-if="item.state" @click="item.state=!item.state">點選下架</button>
                        <button v-else  @click="item.state=!item.state">點選上架</button>
                    </td>
                </tr>
            </tbody>
        </table>
        <span>選中的商品的總數量:{{count}}</span>
    </div>

    <!-- <button οnclick="alert()">點我</button> -->
</body>
<script>
    /*
        ① 根據data資料渲染DOM結構
        ② 新增商品
        ③ 删除功能  根據id删除
        ④ 上下架功能  根據id修改上下架
        ⑤ 首先把資料中新增一個屬性 isChecked
            在把這個屬性跟頁面中的input框做雙向資料綁定
            全選:給全選框綁定事件
            反選:給所有的複選框綁定事件
    */
    new Vue({
        el:'#app',
        data:{
            goods:[
                {id:1,name:'蘋果',state:true,num:5,isChecked:false},
                {id:2,name:'香蕉',state:false,num:5,isChecked:false},
                {id:3,name:'橘子',state:true,num:5,isChecked:true},
                {id:4,name:'甘蔗',state:true,num:5,isChecked:false},
                {id:5,name:'荔枝',state:true,num:5,isChecked:false}
            ],
            //定義商品名稱
            gName:'',
            //商品的數量
            gNum:0,
            //上下架的狀态
            gState:true,
            //商品id
            ids:5,
            //全選狀态
            allState:false,
            //記錄選中的商品的總數量
            //count:0
        },
        methods: {
            //定義新增商品的方法/函數
            addGoods(){
                //1.先建立一個商品對象
                let obj = {
                    id:++this.ids,
                    name:this.gName,
                    num:this.gNum,
                    state:this.gState
                }
                //2.把資料整體追加到 data中goods中
                this.goods.push(obj);
            },
            //定義删除按鈕
            del(e,i){
                //方式一:DOM方式  不推薦使用
                //e.target.parentElement.parentElement.remove()
                //e.target.parentNode.parentNode.remove()

                //方式二:從資料的角度來删除
                /* this.goods.forEach((item,index) => {
                    if(item.id==i){
                        //index表示删除的下标  1 表示删除的個數
                        this.goods.splice(index,1)
                    }
                }); */
                //使用數組的filter方法做過濾操作 拿到符合條件的所有結果
                this.goods = this.goods.filter(item=>item.id!=i)
            },
            //定義修改狀态的函數
            /* changeState(i){
                this.goods.forEach((item) => {
                    if(item.id==i){
                        //index表示删除的下标  1 表示删除的個數
                        item.state = !item.state
                    }
                });
            } */
            //定義全選事件
            checkAll(){
                //全選:要把購物車中所有的選項的isChecked屬性值都變成跟全選框一緻
                this.goods.forEach((item) => {
                    item.isChecked = this.allState
                });
            },
            //定義反選事件
            reverseChk(){
                //點選每一個複選框時,都要對所有複選框做周遊,看裡邊是否存在isChecked為false的選項
                //隻要有false  那麼allState也等于false 
                this.allState = this.goods.every(item=>item.isChecked==true)
            },
            //定義數量的增加方法
            add(i){
                this.goods.forEach((item) => {
                    if(item.id==i){
                        item.num+=1
                    }
                });
            },
            //定義數量的減少方法
            sub(i,a){
                //如果數量為1的  就直接return  
                if(this.goods[a].num==1) return ;
                
                this.goods.forEach((item) => {
                    if(item.id==i){
                        item.num-=1
                    }
                });
            }
        },
        computed: {
            //計算選中結算的商品總數量
            count(){
                //先 篩選 出被選中的商品 再 計算中總數量指派給count 
                return this.goods.filter(item=>item.isChecked==true).reduce((total,item)=>total+=item.num,0)
            }
        }
    })
</script>
</html>      

三、作業:

作業1:學生資訊錄入系統

作業2:任務清單案例

需求:觀察視訊中各項特效變化,完成效果。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../js/vue.js"></script>
    <style>
        .active{
            text-decoration: line-through;
            color: gray;
        }
    </style>
</head>
<body>
    <div id="app">
        <h1>任務清單</h1>
        <h4>任務總數{{sum()}}; 未完成{{daiban()}};已完成{{sum()-daiban()}}</h4>
        <ol>
            <li v-for='(item,index) in lists'>
                <input :id="item.id" v-model='item.isChecked' type="checkbox">
                <span :class="{active:item.isChecked}"  @dblclick='showInp1(index)' v-show='item.isEdit'>{{item.content}}</span>
                <input type="text" @blur='item.isEdit=true' v-model='item.content'  v-show='!item.isEdit'>
            </li>
        </ol>
        <input type="text" v-model.trim='msg'><button @click='add'>添加</button>
        <button @click='del'>删除已完成任務</button>
    </div>
    <script>
        let vm = new Vue({
            el:'#app',
            data:{
                lists:[
                    {isChecked:false,content:'學習java',isEdit:true},
                    {isChecked:false,content:'學習html',isEdit:true},
                    {isChecked:false,content:'學習vue',isEdit:true},
                    {isChecked:false,content:'學習css',isEdit:true}
                ],
                msg:'',
                id:0
            },
            methods:{
                //添加任務
                add(){
                    let obj = {
                        id:++this.id,
                        isChecked:false,
                        content:this.msg,
                        isEdit:true
                    }
                    this.lists.push(obj);
                },
                //定義輕按兩下任務時顯示input輸入框
                showInp1(i){
                    //如果任務是已完成狀态此時無法再次編輯
                    if(this.lists[i].isChecked) return;
                    //改變目前編輯的資料的isedit的值
                    this.lists[i].isEdit = false;
                },
                //任務總數
                sum(){
                    return this.lists.length;
                },
                //未完成的任務
                daiban(){
                    let aaa = 0;
                    this.lists.forEach(obj => {
                        if(!obj.isChecked){
                            aaa++;
                        }
                    });
                    return aaa;
                },
                //删除已完成任務
                del(){
                    //通過原生js的數組的fillter方法篩選出未完成的任務
                    this.lists = this.lists.filter((obj)=>{
                        return obj.isChecked!=true;
                    })
                }
            }
        })
    </script>
</body>
</html>      

繼續閱讀