Vue.js學(xué)習(xí)手冊(2)

Vue常用特性

表單基本操作

  • 獲取單選框中的值

    • 通過v-model
      <!-- 
          1乘凸、 兩個單選框需要同時通過v-model 雙向綁定 一個值 
            2、 每一個單選框必須要有value屬性  且value 值不能一樣 
          3冀偶、 當(dāng)某一個單選框選中的時候 v-model  會將當(dāng)前的 value值 改變 data 中的 數(shù)據(jù)
    
          gender 的值就是選中的值进鸠,我們只需要實時監(jiān)控他的值就可以了
      -->
       <input type="radio" id="male" value="1" v-model='gender'>
       <label for="male">男</label>
    
       <input type="radio" id="female" value="2" v-model='gender'>
       <label for="female">女</label>
    
    <script>
        new Vue({
             data: {
                 // 默認(rèn)會讓當(dāng)前的 value 值為 2 的單選框選中
                    gender: 2,  
                },
        })
    
    </script>
    
  • 獲取復(fù)選框中的值

    • 通過v-model
    • 和獲取單選框中的值一樣
    • 復(fù)選框 checkbox 這種的組合時 data 中的 hobby 我們要定義成數(shù)組 否則無法實現(xiàn)多選
      <!-- 
          1霞幅、 復(fù)選框需要同時通過v-model 雙向綁定 一個值 
            2司恳、 每一個復(fù)選框必須要有value屬性  且value 值不能一樣 
          3、 當(dāng)某一個單選框選中的時候 v-model  會將當(dāng)前的 value值 改變 data 中的 數(shù)據(jù)
    
          hobby 的值就是選中的值猎塞,我們只需要實時監(jiān)控他的值就可以了
      -->
    
    <div>
       <span>愛好:</span>
       <input type="checkbox" id="ball" value="1" v-model='hobby'>
       <label for="ball">籃球</label>
       <input type="checkbox" id="sing" value="2" v-model='hobby'>
       <label for="sing">唱歌</label>
       <input type="checkbox" id="code" value="3" v-model='hobby'>
       <label for="code">寫代碼</label>
     </div>
    <script>
        new Vue({
             data: {
                    // 默認(rèn)會讓當(dāng)前的 value 值為 2 和 3 的復(fù)選框選中
                    hobby: ['2', '3'],
                },
        })
    </script>
    
  • 獲取下拉框和文本框中的值

    • 通過v-model
       <div>
          <span>職業(yè):</span>
           <!--
              1比藻、 需要給select  通過v-model 雙向綁定 一個值 
                2款违、 每一個option  必須要有value屬性  且value 值不能一樣 
              3、 當(dāng)某一個option選中的時候 v-model  會將當(dāng)前的 value值 改變 data 中的 數(shù)據(jù)
               occupation 的值就是選中的值请梢,我們只需要實時監(jiān)控他的值就可以了
          -->
           <!-- multiple  多選 -->
          <select v-model='occupation' multiple>
              <option value="0">請選擇職業(yè)...</option>
              <option value="1">教師</option>
              <option value="2">軟件工程師</option>
              <option value="3">律師</option>
          </select>
             <!-- textarea 是 一個雙標(biāo)簽   不需要綁定value 屬性的  -->
            <textarea v-model='desc'></textarea>
      </div>
    <script>
        new Vue({
             data: {
                    // 默認(rèn)會讓當(dāng)前的 value 值為 2 和 3 的下拉框選中
                     occupation: ['2', '3'],
                   desc: 'nihao'
                },
        })
    </script>
    

表單修飾符

  • .number 轉(zhuǎn)換為數(shù)值

    • 注意點:
    • 當(dāng)開始輸入非數(shù)字的字符串時当窗,因為Vue無法將字符串轉(zhuǎn)換成數(shù)值
    • 所以屬性值將實時更新成相同的字符串元咙。即使后面輸入數(shù)字,也將被視作字符串简识。
  • .trim 自動過濾用戶輸入的首尾空白字符

    • 只能去掉首尾的 不能去除中間的空格
  • .lazy 將input事件切換成change事件

    • .lazy 修飾符延遲了同步更新屬性值的時機(jī)陪白。即將原本綁定在 input 事件的同步邏輯轉(zhuǎn)變?yōu)榻壎ㄔ?change 事件上
  • 在失去焦點 或者 按下回車鍵時才更新

    <!-- 自動將用戶的輸入值轉(zhuǎn)為數(shù)值類型 -->
    <input v-model.number="age" type="number">
    
    <!--自動過濾用戶輸入的首尾空白字符   -->
    <input v-model.trim="msg">
    
    <!-- 在“change”時而非“input”時更新 -->
    <input v-model.lazy="msg" >
    

自定義指令

  • 內(nèi)置指令不能滿足我們特殊的需求
  • Vue允許我們自定義指令

Vue.directive 注冊全局指令

<!-- 
  使用自定義的指令拷泽,只需在對用的元素中,加上'v-'的前綴形成類似于內(nèi)部指令'v-if'脂矫,'v-text'的形式。 
-->
<input type="text" v-focus>
<script>
// 注意點: 
//   1拄轻、 在自定義指令中  如果以駝峰命名的方式定義 如  Vue.directive('focusA',function(){}) 
//   2、 在HTML中使用的時候 只能通過 v-focus-a 來使用 
    
// 注冊一個全局自定義指令 v-focus
Vue.directive('focus', {
    // 當(dāng)綁定元素插入到 DOM 中斧抱。 其中 el為dom元素
    inserted: function (el) {
            // 聚焦元素
            el.focus();
    }
});
new Vue({
  el:'#app'
});
</script>

Vue.directive 注冊全局指令 帶參數(shù)

  <input type="text" v-color='msg'>
 <script type="text/javascript">
    /*
      自定義指令-帶參數(shù)
      bind - 只調(diào)用一次,在指令第一次綁定到元素上時候調(diào)用

    */
    Vue.directive('color', {
      // bind聲明周期, 只調(diào)用一次,指令第一次綁定到元素時調(diào)用弛槐。在這里可以進(jìn)行一次性的初始化設(shè)置
      // el 為當(dāng)前自定義指令的DOM元素  
      // binding 為自定義的函數(shù)形參   通過自定義屬性傳遞過來的值 存在 binding.value 里面
      bind: function(el, binding){
        // 根據(jù)指令的參數(shù)設(shè)置背景色
        // console.log(binding.value.color)
        el.style.backgroundColor = binding.value.color;
      }
    });
    var vm = new Vue({
      el: '#app',
      data: {
        msg: {
          color: 'blue'
        }
      }
    });
  </script>

自定義指令局部指令

  • 局部指令慕蔚,需要定義在 directives 的選項 用法和全局用法一樣
  • 局部指令只能在當(dāng)前組件里面使用
  • 當(dāng)全局指令和局部指令同名時以局部指令為準(zhǔn)
<input type="text" v-color='msg'>
 <input type="text" v-focus>
 <script type="text/javascript">
    /*
      自定義指令-局部指令
    */
    var vm = new Vue({
      el: '#app',
      data: {
        msg: {
          color: 'red'
        }
      },
      //局部指令丐黄,需要定義在  directives 的選項
      directives: {
        color: {
          bind: function(el, binding){
            el.style.backgroundColor = binding.value.color;
          }
        },
        focus: {
          inserted: function(el) {
            el.focus();
          }
        }
      }
    });
  </script>

計算屬性 computed

  • 模板中放入太多的邏輯會讓模板過重且難以維護(hù) 使用計算屬性可以讓模板更加的簡潔
  • 計算屬性是基于它們的響應(yīng)式依賴進(jìn)行緩存的
  • computed比較適合對多個變量或者對象進(jìn)行處理后返回一個結(jié)果值,也就是數(shù)多個變量中的某一個值發(fā)生了變化則我們監(jiān)控的這個值也就會發(fā)生變化
 <div id="app">
     <!--  
        當(dāng)多次調(diào)用 reverseString  的時候 
        只要里面的 num 值不改變 他會把第一次計算的結(jié)果直接返回
        直到data 中的num值改變 計算屬性才會重新發(fā)生計算
     -->
    <div>{{reverseString}}</div>
    <div>{{reverseString}}</div>
     <!-- 調(diào)用methods中的方法的時候  他每次會重新調(diào)用 -->
    <div>{{reverseMessage()}}</div>
    <div>{{reverseMessage()}}</div>
  </div>
  <script type="text/javascript">
    /*
      計算屬性與方法的區(qū)別:計算屬性是基于依賴進(jìn)行緩存的孔飒,而方法不緩存
    */
    var vm = new Vue({
      el: '#app',
      data: {
        msg: 'Nihao',
        num: 100
      },
      methods: {
        reverseMessage: function(){
          console.log('methods')
          return this.msg.split('').reverse().join('');
        }
      },
      //computed  屬性 定義 和 data 已經(jīng) methods 平級 
      computed: {
        //  reverseString   這個是我們自己定義的名字 
        reverseString: function(){
          console.log('computed')
          var total = 0;
          //  當(dāng)data 中的 num 的值改變的時候  reverseString  會自動發(fā)生計算  
          for(var i=0;i<=this.num;i++){
            total += i;
          }
          // 這里一定要有return 否則 調(diào)用 reverseString 的 時候無法拿到結(jié)果    
          return total;
        }
      }
    });
  </script>

偵聽器 watch

  • 使用watch來響應(yīng)數(shù)據(jù)的變化
  • 一般用于異步或者開銷較大的操作
  • watch 中的屬性 一定是data 中 已經(jīng)存在的數(shù)據(jù)
  • 當(dāng)需要監(jiān)聽一個對象的改變時灌闺,普通的watch方法無法監(jiān)聽到對象內(nèi)部屬性的改變艰争,只有data中的數(shù)據(jù)才能夠監(jiān)聽到變化甩卓,此時就需要deep屬性對對象進(jìn)行深度監(jiān)聽
 <div id="app">
        <div>
            <span>名:</span>
            <span>
        <input type="text" v-model='firstName'>
      </span>
        </div>
        <div>
            <span>姓:</span>
            <span>
        <input type="text" v-model='lastName'>
      </span>
        </div>
        <div>{{fullName}}</div>
    </div>

  <script type="text/javascript">
        /*
              偵聽器
            */
        var vm = new Vue({
            el: '#app',
            data: {
                firstName: 'Jim',
                lastName: 'Green',
                // fullName: 'Jim Green'
            },
             //watch  屬性 定義 和 data 已經(jīng) methods 平級 
            watch: {
                //   注意:  這里firstName  對應(yīng)著data 中的 firstName 
                //   當(dāng) firstName 值 改變的時候  會自動觸發(fā) watch
                firstName: function(val) {
                    this.fullName = val + ' ' + this.lastName;
                },
                //   注意:  這里 lastName 對應(yīng)著data 中的 lastName 
                lastName: function(val) {
                    this.fullName = this.firstName + ' ' + val;
                }
            }
        });
    </script>

過濾器

  • Vue.js允許自定義過濾器弱匪,可被用于一些常見的文本格式化。
  • 過濾器可以用在兩個地方:雙花括號插值和v-bind表達(dá)式穷当。
  • 過濾器應(yīng)該被添加在JavaScript表達(dá)式的尾部毁习,由“管道”符號指示
  • 支持級聯(lián)操作
  • 過濾器不改變真正的data猜嘱,而只是改變渲染的結(jié)果益楼,并返回過濾后的版本
  • 全局注冊時是filter坠陈,沒有s的贮匕。而局部過濾器是filters,是有s的
  <div id="app">
    <input type="text" v-model='msg'>
      <!-- upper 被定義為接收單個參數(shù)的過濾器函數(shù)腥刹,表達(dá)式  msg  的值將作為參數(shù)傳入到函數(shù)中 -->
    <div>{{msg | upper}}</div>
    <!--  
      支持級聯(lián)操作
      upper  被定義為接收單個參數(shù)的過濾器函數(shù)葫男,表達(dá)式msg 的值將作為參數(shù)傳入到函數(shù)中。
      然后繼續(xù)調(diào)用同樣被定義為接收單個參數(shù)的過濾器 lower 丈积,將upper 的結(jié)果傳遞到lower中
    -->
    <div>{{msg | upper | lower}}</div>
    <div :abc='msg | upper'>測試數(shù)據(jù)</div>
  </div>

<script type="text/javascript">
   //  lower  為全局過濾器     
   Vue.filter('lower', function(val) {
      return val.charAt(0).toLowerCase() + val.slice(1);
    });
    var vm = new Vue({
      el: '#app',
      data: {
        msg: ''
      },
       //filters  屬性 定義 和 data 已經(jīng) methods 平級 
       //  定義filters 中的過濾器為局部過濾器 
      filters: {
        //   upper  自定義的過濾器名字 
        //    upper 被定義為接收單個參數(shù)的過濾器函數(shù)擒悬,表達(dá)式  msg  的值將作為參數(shù)傳入到函數(shù)中
        upper: function(val) {
         //  過濾器中一定要有返回值 這樣外界使用過濾器的時候才能拿到結(jié)果
          return val.charAt(0).toUpperCase() + val.slice(1);
        }
      }
    });
  </script>

過濾器中傳遞參數(shù)

    <div id="box">
        <!--
            filterA 被定義為接收三個參數(shù)的過濾器函數(shù)。
            其中 message 的值作為第一個參數(shù)溺忧,
            普通字符串 'arg1' 作為第二個參數(shù),表達(dá)式 arg2 的值作為第三個參數(shù)。
        -->
        {{ message | filterA('arg1', 'arg2') }}
    </div>
    <script>
        // 在過濾器中 第一個參數(shù) 對應(yīng)的是  管道符前面的數(shù)據(jù)   n  此時對應(yīng) message
        // 第2個參數(shù)  a 對應(yīng) 實參  arg1 字符串
        // 第3個參數(shù)  b 對應(yīng) 實參  arg2 字符串
        Vue.filter('filterA',function(n,a,b){
            if(n<10){
                return n+a;
            }else{
                return n+b;
            }
        });
        
        new Vue({
            el:"#box",
            data:{
                message: "哈哈哈"
            }
        })

    </script>

生命周期

  • 事物從出生到死亡的過程
  • Vue實例從創(chuàng)建 到銷毀的過程 ,這些過程中會伴隨著一些函數(shù)的自調(diào)用。我們稱這些函數(shù)為鉤子函數(shù)

常用的 鉤子函數(shù)

beforeCreate 在實例初始化之后展融,數(shù)據(jù)觀測和事件配置之前被調(diào)用 此時data 和 methods 以及頁面的DOM結(jié)構(gòu)都沒有初始化 什么都做不了
created 在實例創(chuàng)建完成后被立即調(diào)用此時data 和 methods已經(jīng)可以使用 但是頁面還沒有渲染出來
beforeMount 在掛載開始之前被調(diào)用 此時頁面上還看不到真實數(shù)據(jù) 只是一個模板頁面而已
mounted el被新創(chuàng)建的vm.$el替換,并掛載到實例上去之后調(diào)用該鉤子。 數(shù)據(jù)已經(jīng)真實渲染到頁面上 在這個鉤子函數(shù)里面我們可以使用一些第三方的插件
beforeUpdate 數(shù)據(jù)更新時調(diào)用,發(fā)生在虛擬DOM打補(bǔ)丁之前。 頁面上數(shù)據(jù)還是舊的
updated 由于數(shù)據(jù)更改導(dǎo)致的虛擬DOM重新渲染和打補(bǔ)丁,在這之后會調(diào)用該鉤子。 頁面上數(shù)據(jù)已經(jīng)替換成最新的
beforeDestroy 實例銷毀之前調(diào)用
destroyed 實例銷毀后調(diào)用

數(shù)組變異方法

  • 在 Vue 中,直接修改對象屬性的值無法觸發(fā)響應(yīng)式才避。當(dāng)你直接修改了對象屬性的值劈彪,你會發(fā)現(xiàn)屯曹,只有數(shù)據(jù)改了稿蹲,但是頁面內(nèi)容并沒有改變
  • 變異數(shù)組方法即保持?jǐn)?shù)組方法原有功能不變的前提下對其進(jìn)行功能拓展
push() 往數(shù)組最后面添加一個元素,成功返回當(dāng)前數(shù)組的長度
pop() 刪除數(shù)組的最后一個元素歇竟,成功返回刪除元素的值
shift() 刪除數(shù)組的第一個元素长窄,成功返回刪除元素的值
unshift() 往數(shù)組最前面添加一個元素滔吠,成功返回當(dāng)前數(shù)組的長度
splice() 有三個參數(shù),第一個是想要刪除的元素的下標(biāo)(必選)挠日,第二個是想要刪除的個數(shù)(必選)疮绷,第三個是刪除 后想要在原位置替換的值
sort() sort() 使數(shù)組按照字符編碼默認(rèn)從小到大排序,成功返回排序后的數(shù)組
reverse() reverse() 將數(shù)組倒序,成功返回倒序后的數(shù)組

替換數(shù)組

  • 不會改變原始數(shù)組肆资,但總是返回一個新數(shù)組
filter filter() 方法創(chuàng)建一個新的數(shù)組矗愧,新數(shù)組中的元素是通過檢查指定數(shù)組中符合條件的所有元素。
concat concat() 方法用于連接兩個或多個數(shù)組郑原。該方法不會改變現(xiàn)有的數(shù)組
slice slice() 方法可從已有的數(shù)組中返回選定的元素唉韭。該方法并不會修改數(shù)組,而是返回一個子數(shù)組

動態(tài)數(shù)組響應(yīng)式數(shù)據(jù)

  • Vue.set(a,b,c) 讓 觸發(fā)視圖重新更新一遍犯犁,數(shù)據(jù)動態(tài)起來
  • a是要更改的數(shù)據(jù) 属愤、 b是數(shù)據(jù)的第幾項、 c是更改后的數(shù)據(jù)

圖書列表案例

  • 靜態(tài)列表效果
  • 基于數(shù)據(jù)實現(xiàn)模板效果
  • 處理每行的操作按鈕

1酸役、 提供的靜態(tài)數(shù)據(jù)

  • 數(shù)據(jù)存放在vue 中 data 屬性中
 var vm = new Vue({
      el: '#app',
      data: {
        books: [{
          id: 1,
          name: '三國演義',
          date: ''
        },{
          id: 2,
          name: '水滸傳',
          date: ''
        },{
          id: 3,
          name: '紅樓夢',
          date: ''
        },{
          id: 4,
          name: '西游記',
          date: ''
        }]
      }
    }); var vm = new Vue({
      el: '#app',
      data: {
        books: [{
          id: 1,
          name: '三國演義',
          date: ''
        },{
          id: 2,
          name: '水滸傳',
          date: ''
        },{
          id: 3,
          name: '紅樓夢',
          date: ''
        },{
          id: 4,
          name: '西游記',
          date: ''
        }]
      }
    });

2住诸、 把提供好的數(shù)據(jù)渲染到頁面上

  • 利用 v-for循環(huán) 遍歷 books 將每一項數(shù)據(jù)渲染到對應(yīng)的數(shù)據(jù)中
 <tbody>
    <tr :key='item.id' v-for='item in books'>
       <!-- 對應(yīng)的id 渲染到頁面上 -->
       <td>{{item.id}}</td>
        <!-- 對應(yīng)的name 渲染到頁面上 -->
       <td>{{item.name}}</td>
       <td>{{item.date}}</td>
       <td>
         <!-- 阻止 a 標(biāo)簽的默認(rèn)跳轉(zhuǎn) -->
         <a href="" @click.prevent>修改</a>
         <span>|</span>
          <a href="" @click.prevent>刪除</a>
       </td>
     </tr>
</tbody>

3驾胆、 添加圖書

  • 通過雙向綁定獲取到輸入框中的輸入內(nèi)容
  • 給按鈕添加點擊事件
  • 把輸入框中的數(shù)據(jù)存儲到 data 中的 books 里面
<div>
  <h1>圖書管理</h1>
  <div class="book">
       <div>
         <label for="id">
           編號:
         </label>
          <!-- 3.1、通過雙向綁定獲取到輸入框中的輸入的 id  -->
         <input type="text" id="id" v-model='id'>
         <label for="name">
           名稱:
         </label>
           <!-- 3.2贱呐、通過雙向綁定獲取到輸入框中的輸入的 name  -->
         <input type="text" id="name" v-model='name'>
            <!-- 3.3丧诺、給按鈕添加點擊事件  -->
         <button @click='handle'>提交</button>
       </div>
  </div>
</div>
  <script type="text/javascript">
    /*
      圖書管理-添加圖書
    */
    var vm = new Vue({
      el: '#app',
      data: {
        id: '',
        name: '',
        books: [{
          id: 1,
          name: '三國演義',
          date: ''
        },{
          id: 2,
          name: '水滸傳',
          date: ''
        },{
          id: 3,
          name: '紅樓夢',
          date: ''
        },{
          id: 4,
          name: '西游記',
          date: ''
        }]
      },
      methods: {
        handle: function(){
          // 3.4 定義一個新的對象book 存儲 獲取到輸入框中 書 的id和名字 
          var book = {};
          book.id = this.id;
          book.name = this.name;
          book.date = '';
         // 3.5 把book  通過數(shù)組的變異方法 push 放到    books 里面
          this.books.push(book);
          //3.6 清空輸入框
          this.id = '';
          this.name = '';
        }
      }
    });
  </script>

4 修改圖書-上

  • 點擊修改按鈕的時候 獲取到要修改的書籍名單
    • 4.1 給修改按鈕添加點擊事件, 需要把當(dāng)前的圖書的id 傳遞過去 這樣才知道需要修改的是哪一本書籍
  • 把需要修改的書籍名單填充到表單里面
    • 4.2 根據(jù)傳遞過來的id 查出books 中 對應(yīng)書籍的詳細(xì)信息
    • 4.3 把獲取到的信息填充到表單
 <div id="app">
    <div class="grid">
      <div>
        <h1>圖書管理</h1>
        <div class="book">
          <div>
            <label for="id">
              編號:
            </label>
            <input type="text" id="id" v-model='id' :disabled="flag">
            <label for="name">
              名稱:
            </label>
            <input type="text" id="name" v-model='name'>
            <button @click='handle'>提交</button>
          </div>
        </div>
      </div>
      <table>
        <thead>
          <tr>
            <th>編號</th>
            <th>名稱</th>
            <th>時間</th>
            <th>操作</th>
          </tr>
        </thead>
        <tbody>
          <tr :key='item.id' v-for='item in books'>
            <td>{{item.id}}</td>
            <td>{{item.name}}</td>
            <td>{{item.date}}</td>
            <td>
              <!--- 
                4.1  給修改按鈕添加點擊事件奄薇,  需要把當(dāng)前的圖書的id 傳遞過去 
                這樣才知道需要修改的是哪一本書籍
                --->  
              <a href="" @click.prevent='toEdit(item.id)'>修改</a>
              <span>|</span>
              <a href="" @click.prevent>刪除</a>
            </td>
          </tr>
        </tbody>
      </table>
    </div>
  </div>
 <script type="text/javascript">
    /*
      圖書管理-添加圖書
    */
    var vm = new Vue({
      el: '#app',
      data: {
        flag: false,
        id: '',
        name: '',
        books: [{
          id: 1,
          name: '三國演義',
          date: ''
        },{
          id: 2,
          name: '水滸傳',
          date: ''
        },{
          id: 3,
          name: '紅樓夢',
          date: ''
        },{
          id: 4,
          name: '西游記',
          date: ''
        }]
      },
      methods: {
        handle: function(){
          // 3.4 定義一個新的對象book 存儲 獲取到輸入框中 書 的id和名字 
          var book = {};
          book.id = this.id;
          book.name = this.name;
          book.date = '';
         // 3.5 把book  通過數(shù)組的變異方法 push 放到    books 里面
          this.books.push(book);
          //3.6 清空輸入框
          this.id = '';
          this.name = '';
        },
        toEdit: function(id){
          console.log(id)
          //4.2  根據(jù)傳遞過來的id 查出books 中 對應(yīng)書籍的詳細(xì)信息
          var book = this.books.filter(function(item){
            return item.id == id;
          });
          console.log(book)
          //4.3 把獲取到的信息填充到表單
          // this.id   和  this.name 通過雙向綁定 綁定到了表單中  一旦數(shù)據(jù)改變視圖自動更新
          this.id = book[0].id;
          this.name = book[0].name;
        }
      }
    });
  </script>

5 修改圖書-下

  • 5.1 定義一個標(biāo)識符驳阎, 主要是控制 編輯狀態(tài)下當(dāng)前編輯書籍的id 不能被修改 即 處于編輯狀態(tài)下 當(dāng)前控制書籍編號的輸入框禁用
  • 5.2 通過屬性綁定給書籍編號的 綁定 disabled 的屬性 flag 為 true 即為禁用
  • 5.3 flag 默認(rèn)值為false 處于編輯狀態(tài) 要把 flag 改為true 即當(dāng)前表單為禁用
  • 5.4 復(fù)用添加方法 用戶點擊提交的時候依然執(zhí)行 handle 中的邏輯如果 flag為true 即 表單處于不可輸入狀態(tài) 此時執(zhí)行的用戶編輯數(shù)據(jù)數(shù)據(jù)
<div id="app">
    <div class="grid">
      <div>
        <h1>圖書管理</h1>
        <div class="book">
          <div>
            <label for="id">
              編號:
            </label>
              <!-- 5.2 通過屬性綁定 綁定 disabled 的屬性  flag 為 true 即為禁用      -->
            <input type="text" id="id" v-model='id' :disabled="flag">
            <label for="name">
              名稱:
            </label>
            <input type="text" id="name" v-model='name'>
            <button @click='handle'>提交</button>
          </div>
        </div>
      </div>
      <table>
        <thead>
          <tr>
            <th>編號</th>
            <th>名稱</th>
            <th>時間</th>
            <th>操作</th>
          </tr>
        </thead>
        <tbody>
          <tr :key='item.id' v-for='item in books'>
            <td>{{item.id}}</td>
            <td>{{item.name}}</td>
            <td>{{item.date}}</td>
            <td>
              <a href="" @click.prevent='toEdit(item.id)'>修改</a>
              <span>|</span>
              <a href="" @click.prevent>刪除</a>
            </td>
          </tr>
        </tbody>
      </table>
    </div>
  </div>   
<script type="text/javascript">
        /*圖書管理-添加圖書*/
        var vm = new Vue({
            el: '#app',
            data: {
                // 5.1  定義一個標(biāo)識符, 主要是控制 編輯狀態(tài)下當(dāng)前編輯書籍的id 不能被修改 
                // 即 處于編輯狀態(tài)下 當(dāng)前控制書籍編號的輸入框禁用 
                flag: false,
                id: '',
                name: '',
              
            },
            methods: {
                handle: function() {
                   /*
                     5.4  復(fù)用添加方法   用戶點擊提交的時候依然執(zhí)行 handle 中的邏輯
                         如果 flag為true 即 表單處于不可輸入狀態(tài) 此時執(zhí)行的用戶編輯數(shù)據(jù)數(shù)據(jù)    
                   */ 
                    if (this.flag) {
                        // 編輯圖書
                        // 5.5  根據(jù)當(dāng)前的ID去更新數(shù)組中對應(yīng)的數(shù)據(jù)  
                        this.books.some((item) => {
                            if (item.id == this.id) {
                                // 箭頭函數(shù)中 this 指向父級作用域的this 
                                item.name = this.name;
                                // 完成更新操作之后馁蒂,需要終止循環(huán)
                                return true;
                            }
                        });
                        // 5.6 編輯完數(shù)據(jù)后表單要處以可以輸入的狀態(tài)
                        this.flag = false;
                    //  5.7  如果 flag為false  表單處于輸入狀態(tài) 此時執(zhí)行的用戶添加數(shù)據(jù)    
                    } else { 
                        var book = {};
                        book.id = this.id;
                        book.name = this.name;
                        book.date = '';
                        this.books.push(book);
                        // 清空表單
                        this.id = '';
                        this.name = '';
                    }
                    // 清空表單
                    this.id = '';
                    this.name = '';
                },
                toEdit: function(id) {
                     /*
                     5.3  flag 默認(rèn)值為false   處于編輯狀態(tài) 要把 flag 改為true 即當(dāng)前表單為禁                      用 
                     */ 
                    this.flag = true;
                    console.log(id)
                    var book = this.books.filter(function(item) {
                        return item.id == id;
                    });
                    console.log(book)
                    this.id = book[0].id;
                    this.name = book[0].name;
                }
            }
        });
    </script>

6 刪除圖書

  • 6.1 給刪除按鈕添加事件 把當(dāng)前需要刪除的書籍id 傳遞過來
  • 6.2 根據(jù)id從數(shù)組中查找元素的索引
  • 6.3 根據(jù)索引刪除數(shù)組元素
  <tbody>
          <tr :key='item.id' v-for='item in books'>
            <td>{{item.id}}</td>
            <td>{{item.name}}</td>
            <td>{{item.date}}</td>
            <td>
              <a href="" @click.prevent='toEdit(item.id)'>修改</a>
              <span>|</span>
               <!--  6.1 給刪除按鈕添加事件 把當(dāng)前需要刪除的書籍id 傳遞過來  --> 
              <a href="" @click.prevent='deleteBook(item.id)'>刪除</a>
            </td>
          </tr>
</tbody>
  <script type="text/javascript">
    /*
      圖書管理-添加圖書
    */
    var vm = new Vue({
      methods: {
        deleteBook: function(id){
          // 刪除圖書
          #// 6.2 根據(jù)id從數(shù)組中查找元素的索引
          // var index = this.books.findIndex(function(item){
          //   return item.id == id;
          // });
          #// 6.3 根據(jù)索引刪除數(shù)組元素
          // this.books.splice(index, 1);
          // -------------------------
         #// 方法二:通過filter方法進(jìn)行刪除
        
          # 6.4  根據(jù)filter 方法 過濾出來id 不是要刪除書籍的id 
          # 因為 filter 是替換數(shù)組不會修改原始數(shù)據(jù) 所以需要 把 不是要刪除書籍的id  賦值給 books 
          this.books = this.books.filter(function(item){
            return item.id != id;
          });
        }
      }
    });
  </script>

常用特性應(yīng)用場景

1 過濾器

  • Vue.filter 定義一個全局過濾器
 <tr :key='item.id' v-for='item in books'>
            <td>{{item.id}}</td>
            <td>{{item.name}}</td>
            <!-- 1.3  調(diào)用過濾器 -->
            <td>{{item.date | format('yyyy-MM-dd hh:mm:ss')}}</td>
            <td>
              <a href="" @click.prevent='toEdit(item.id)'>修改</a>
              <span>|</span>
              <a href="" @click.prevent='deleteBook(item.id)'>刪除</a>
            </td>
</tr>

<script>
        #1.1  Vue.filter  定義一個全局過濾器
        Vue.filter('format', function(value, arg) {
              function dateFormat(date, format) {
                if (typeof date === "string") {
                  var mts = date.match(/(\/Date\((\d+)\)\/)/);
                  if (mts && mts.length >= 3) {
                    date = parseInt(mts[2]);
                  }
                }
                date = new Date(date);
                if (!date || date.toUTCString() == "Invalid Date") {
                  return "";
                }
                var map = {
                  "M": date.getMonth() + 1, //月份 
                  "d": date.getDate(), //日 
                  "h": date.getHours(), //小時 
                  "m": date.getMinutes(), //分 
                  "s": date.getSeconds(), //秒 
                  "q": Math.floor((date.getMonth() + 3) / 3), //季度 
                  "S": date.getMilliseconds() //毫秒 
                };
                format = format.replace(/([yMdhmsqS])+/g, function(all, t) {
                  var v = map[t];
                  if (v !== undefined) {
                    if (all.length > 1) {
                      v = '0' + v;
                      v = v.substr(v.length - 2);
                    }
                    return v;
                  } else if (t === 'y') {
                    return (date.getFullYear() + '').substr(4 - all.length);
                  }
                  return all;
                });
                return format;
              }
              return dateFormat(value, arg);
            })
#1.2  提供的數(shù)據(jù) 包含一個時間戳   為毫秒數(shù)
   [{
          id: 1,
          name: '三國演義',
          date: 2525609975000
        },{
          id: 2,
          name: '水滸傳',
          date: 2525609975000
        },{
          id: 3,
          name: '紅樓夢',
          date: 2525609975000
        },{
          id: 4,
          name: '西游記',
          date: 2525609975000
        }];
</script>

2 自定義指令

  • 讓表單自動獲取焦點
  • 通過Vue.directive 自定義指定
<!-- 2.2  通過v-自定義屬性名 調(diào)用自定義指令 -->
<input type="text" id="id" v-model='id' :disabled="flag" v-focus>

<script>
    # 2.1   通過Vue.directive 自定義指定
    Vue.directive('focus', {
      inserted: function (el) {
        el.focus();
      }
    });

</script>

3 計算屬性

  • 通過計算屬性計算圖書的總數(shù)
    • 圖書的總數(shù)就是計算數(shù)組的長度
 <div class="total">
        <span>圖書總數(shù):</span>
        <!-- 3.2 在頁面上 展示出來 -->
        <span>{{total}}</span>
</div>

  <script type="text/javascript">
    /*
      計算屬性與方法的區(qū)別:計算屬性是基于依賴進(jìn)行緩存的呵晚,而方法不緩存
    */
    var vm = new Vue({
      data: {
        flag: false,
        submitFlag: false,
        id: '',
        name: '',
        books: []
      },
      computed: {
        total: function(){
          // 3.1  計算圖書的總數(shù)
          return this.books.length;
        }
      },
    });
  </script>

生命周期

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市沫屡,隨后出現(xiàn)的幾起案子饵隙,更是在濱河造成了極大的恐慌,老刑警劉巖沮脖,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件金矛,死亡現(xiàn)場離奇詭異,居然都是意外死亡倘潜,警方通過查閱死者的電腦和手機(jī)绷柒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來涮因,“玉大人废睦,你說我怎么就攤上這事⊙荩” “怎么了嗜湃?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長澜掩。 經(jīng)常有香客問我购披,道長,這世上最難降的妖魔是什么肩榕? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任刚陡,我火速辦了婚禮,結(jié)果婚禮上株汉,老公的妹妹穿的比我還像新娘筐乳。我一直安慰自己,他們只是感情好乔妈,可當(dāng)我...
    茶點故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布蝙云。 她就那樣靜靜地躺著,像睡著了一般路召。 火紅的嫁衣襯著肌膚如雪勃刨。 梳的紋絲不亂的頭發(fā)上波材,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天,我揣著相機(jī)與錄音身隐,去河邊找鬼廷区。 笑死,一個胖子當(dāng)著我的面吹牛抡医,可吹牛的內(nèi)容都是我干的躲因。 我是一名探鬼主播,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼忌傻,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了搞监?” 一聲冷哼從身側(cè)響起水孩,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎琐驴,沒想到半個月后俘种,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡绝淡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年宙刘,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片牢酵。...
    茶點故事閱讀 39,722評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡悬包,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出馍乙,到底是詐尸還是另有隱情布近,我是刑警寧澤,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布丝格,位于F島的核電站撑瞧,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏显蝌。R本人自食惡果不足惜预伺,卻給世界環(huán)境...
    茶點故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望曼尊。 院中可真熱鬧酬诀,春花似錦、人聲如沸涩禀。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽艾船。三九已至葵腹,卻和暖如春高每,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背践宴。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工鲸匿, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人阻肩。 一個月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓带欢,卻偏偏與公主長得像,于是被迫代替她去往敵國和親烤惊。 傳聞我的和親對象是個殘疾皇子乔煞,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,614評論 2 353

推薦閱讀更多精彩內(nèi)容

  • Vue 實例 屬性和方法 每個 Vue 實例都會代理其 data 對象里所有的屬性:var data = { a:...
    云之外閱讀 2,207評論 0 6
  • 一、了解Vue.js 1.1.1 Vue.js是什么柒室? 簡單小巧渡贾、漸進(jìn)式、功能強(qiáng)大的技術(shù)棧 1.1.2 為什么學(xué)習(xí)...
    蔡華鵬閱讀 3,319評論 0 3
  • 主要還是自己看的雄右,所有內(nèi)容來自官方文檔空骚。 介紹 Vue.js 是什么 Vue (讀音 /vju?/,類似于 vie...
    Leonzai閱讀 3,348評論 0 25
  • 組件 組件 (Component) 是 Vue.js 最強(qiáng)大的功能之一 組件可以擴(kuò)展 HTML 元素擂仍,封裝可重用的...
    __method__閱讀 226評論 0 0
  • 第一章 Vue概述 what? Vue是實現(xiàn)UI層的漸進(jìn)式j(luò)s框架囤屹,核心庫關(guān)注視圖層,簡單的ui構(gòu)建逢渔,復(fù)雜的路由控...
    fastwe閱讀 715評論 0 0