Vue 指令大全(超詳細)

Ozzie發表於2019-12-17

本文詳細介紹了 Vue 各種指令的用法,以及部分指令之間的對比

本文綱領: 本文會詳細介紹 vue 以下指令 及其 語法、用法,以及 指令之間的詳細對比,涉及指令有:
v-text,v-html,v-if,v-else,v-else-if,v-show,v-for,v-on,v-bind、v-model,v-pre,v-cloak,v-once


插值表示式(以此引出指令)

  1. 資料繫結最常見的形式就是“Mustache”語法 (雙大括號) 的文字插值,Mustache 標籤將會被對應資料物件上屬性的值替代。只要繫結的資料物件上屬性發生了改變,插值處的內容都會更新。
  2. 用過 vue 的盆友都清楚,message 是將資料解析成純文字的,也就是說,就算message 中含有了 html 標籤,它也是隻看做純文字的,不能輸出真正的 html。
  3. 例如:
     <div id="app">
         <p>{{message}}</p>
     </div>
     <script type="text/javascript">
        var app = new Vue({
            el: '#app',
            data: {
                message: '<h1>asc</h1>'
            }
        })
    </script>
    <!--頁面顯示為: <h1>asc</h1>-->

v-text

  1. v-text 簡介:
    • v-text與插值表示式相同的地方是,它也是將資料解析成純文字(解釋html標籤可能導致xss攻擊
    • 但它與花括號的區別是: 使用v-text在頁面載入時不會顯示'message',解決了插值表示式閃爍問題,因為他是屬性而不是插值表示式
  2. 例如:
     <div id="app">
         <p v-text="msg">這裡的內容會被替換</p>
     </div>
     <script>
        var vm = new Vue({
            el: "#app",
            data: {
                msg: "Hello! <h1>v-text</h1>",
            }
        })
     </script>
     <!--頁面顯示為: Hello! <h1>v-text</h1>-->
  3. 注: "頁面閃爍" 指的是在載入插值表示式時,會先直接在頁面顯示'message',然後再編譯對應的資料

v-html

  1. 簡介: 為了輸出真正的HTML,可以用v-html指令。它等同於JS的innerHtml屬性,會將資料解析成html形式。
  2. 例如:
     <div id="app">
         <p v-text="msg">這裡的內容會被替換</p>
     </div>
     <script>
        var vm = new Vue({
            el: "#app",
            data: {
                msg: "Hello! <h1>v-html</h1>",
            }
        })
     </script>
     <!--頁面顯示為: Hello! v-html -->

v-if

  1. 簡介: v-if 指令用於條件性地渲染一塊內容。這塊內容只會在指令的表示式返回 truthy 值的時候被渲染。
  2. 例如:
     <div id="app">
         <p v-if="true"> v-if 為 true 時顯示</p>
         <p v-if="false"> v-if 為 false 時顯示</p>
     </div>
     <script>
        var vm = new Vue({
            el: "#app",
            data: {
                true: true,
                false: false,
            }
        })
     </script>
  3. v-if 是“真正”的條件渲染,因為它會確保在切換過程中 條件塊內的事件監聽器子元件 適當地被銷燬和重建。
  4. v-if 是惰性的,如果初始渲染時條件為 ,那麼就什麼也不用做,直到第一次條件變為 ,才開始渲染條件塊。
  5. v-if 通常用於以下兩種情況:
    • 多個元素之間,通過條件判斷,來 展示 或者 隱藏 某個或多個元素。
    • 進行兩個檢視的切換。
    • 例如下面的程式碼分別實現了: ①type不同值時元素的展示情況;②點選按鈕切換檢視
      <div id="app">
      <div style="color:red">v-if的簡單實用</div>
      <template>
          <div v-if="type == 'A'">A</div>
          <div v-else-if="type=='B'">B</div>
          <div v-else>C</div>
      </template>
      <div>
          <p>v-if的彈框切換</p>
      </div>
      <template v-if="loginType === 'username'">
          <label>使用者名稱: </label>
          <input placeholder="Enter your username" key="username-input">
      </template>
      <template v-else>
          <label>密碼: </label>
          <input placeholder="Enter your email address" key="email-input">
      </template>
      <button @click="changeloginType">切換狀態</button>
      </div>
      <script>
      var app = new Vue({
          el: '#app',
          data: {
              type: 'C',
              loginType: 'username'
          },
          methods: {
              changeloginType() {
                  let self = this;
                  if (self.loginType == 'username') {
                      self.loginType = ''
                  } else {
                      self.loginType = 'username'
                  }
              }
          }
      })
      </script>
  6. 擴充瞭解 — 官方文件: 條件渲染 — Vue.js

v-else

  1. 簡介: 個人感覺 v-else 並不像一個單獨功能的指令,而是偏輔助功能的,而且 v-else 必須和 v-if 連用,否則會報錯。
  2. 例如:
     <div id="app">
        <p v-if="msg1">The msg1 is true</p>
        <p v-else>The msg1 is false</p>
        <input type="button" @click="button" value="Button"/>
     </div>
     <script type="text/javascript">
        var app = new Vue({
            el: '#app',
            data: {
                msg1: true,
            },
            methods: {
                button: function(){
                    this.msg1 = !this.msg1;
                }
            }
        })
     </script>
    • 上述過程即為 v-ifv-else 連用,若去掉 v-if 部分,則報錯為: 編譯模板時出錯

v-else-if

  1. 簡介: 與v-else相同,v-else-if也必須和v-if連用,其實道理很簡單,類比 C語言ifelseelse if,這裡的v-else-if也是用在v-ifv-else中間,實現多次判斷
  2. 例如:
     <div id="app">
        <p v-if="10>20">v-if 贏了</p>
        <p v-else-if="10>5">v-else-if 贏了</p>
        <p v-else>好吧,v-else 贏了</p>
     </div>
     <script type="text/javascript">
        var app = new Vue({
            el: '#app',
        })
     </script>
    • 如果沒有v-if,那麼也會和上面的v-else一樣報錯: 編譯模板時出錯

v-show

  1. 簡介: v-show也是用來 控制元素是否顯示 的,其功能與v-if指令相似。
  2. 例如:
    <div id="app">
    <p v-show="msg">顯示成功</p>
    <input type="button" @click="show" value="Do you want to hide it?" />
    </div>
    <script type="text/javascript">
    var app = new Vue({
        el: '#app',
        data: {
            msg: true,
        },
        methods: {
            show: function(){
                this.msg = !this.msg;
            }
        }
    })
    </script>
  3. 那麼,v-showv-if有什麼 聯絡 呢?
    • v-showv-if都是通過 動態地操作DOM 來實現顯示與隱藏的
  4. v-showv-if區別 是什麼呢?
    • 手段的不同: v-if是動態地向DOM樹內動態地新增或刪除DOM元素,如果v-if的值是false就會在DOM中刪除,相當於visibility:hidden;,如果是true把元素克隆到相應的DOM樹上去,支援加在<template>標籤上;而v-show是動態地設定DOM元素的display屬性,而不會刪除DOM元素,是display:none;,不支援加在<template>標籤上。
    • 編譯過程的不同: v-if在切換時會有一個區域性編譯/解除安裝的過程,在切換時適當地銷燬和重建內部的事件監聽 和 子元件,因為v-if可能是資料繫結或者子元件;而v-show只是簡單地進行 CSS 屬性的切換。
    • 編譯條件的不同: v-if是真真正正的條件渲染,但它是惰性的,如果初始條件為假,則什麼也不用做,只有在第一次條件變為真時才開始區域性編譯,編譯會被快取,之後等到再切換時再進行區域性解除安裝;而v-show不管其值是否為真,都進行編譯,然後編譯被快取,而且DOM元素也保留。
    • 效能消耗不同: v-if有著更高的切換消耗,v-show有著更高的初識渲染消耗
      由此,就引發出了使用問題:
      • 當元件的某塊內容切換很少,那麼切換消耗也就很少,此時用v-if來渲染更加合適
      • 如果頻繁地切換著條件,那麼就用v-show更加合適,實現一次渲染,多次切換
      • 為什麼這麼說呢,因為頻繁操作DOM會很影響效能,如果頻繁切換,就意味著頻繁地建立、刪除DOM,為減少消耗就更該用v-show;如果是要麼顯示要麼隱藏的情況下,那麼v-if更加合理,因為藉助v-if的惰性,如果一開始它的值即為false,那麼甚至都不需要建立DOM,如果其值為true,則效果與v-show完全一樣。
    • 補充: display:nonevisibility:hidden的區別:
      • display:none是徹底消失,不在文件流中佔位,瀏覽器也不會解析該元素;
      • visibility:hidden可以理解為透明度為0的效果,它只是視覺上的消失,在文件流中是佔位的,瀏覽器也會解析該元素。
      • 使用visibility:hidden要比display:none效能更好,用display切換時,頁面會產生 迴流 (當頁面中的一部分元素需要改變規模尺寸、佈局、顯示隱藏等,頁面需要 重新構建,即為迴流。所有頁面第一次載入時需要產生一次迴流),而用visibility切換時不會產生迴流。
    • 補充: 若一個元素在CSS中已設定display:none,則無法通過設定v-if或者v-show來讓元素顯示,因為切換時只會修改元素 element.style 的“display”屬性為“none”或者“block”,並不會覆蓋或者修改已經存在的CSS屬性

v-for

  1. v-for迴圈普通陣列:
    <div id="app">
     <p v-for="value in list">{{value}}</p>
     <p v-for="(value,i) in list">索引: {{i}} => 值: {{value}}</p>
    <!-- 注意: 值與索引的順序為 : (value,i) -->
    </div>
    <script type="text/javascript">
    var vm = new Vue({
        el: "#app",
        data: {
            list: [1,2,3,4,5]
        }
    })
    </script>
  2. v-for迴圈物件陣列:
    <div id="app">
    <p v-for="(value,i) in list">
        索引: {{i}} —— Id: {{value.id}} —— Name: {{value.name}}
    </p>
    </div>
    <script type="text/javascript">
    var vm = new Vue({
        el: "#app",
        data: {
            list: [
                { id: 1, name: 'first' },
                { id: 2, name: 'second' },
                { id: 3, name: 'third' },
            ]
        }
    })
    </script>
  3. v-for迴圈物件:
    <div id="app">
    <p v-for="(value,key,i) in student">
        索引: {{i}} —— 鍵: {{key}} —— 值: {{value}}
    </p>
    </div>
    <script type="text/javascript">
    var app = new Vue({
        el: '#app',
        data: {
            student: {
                id: 0,
                name: 'Tom',
                gender: '男'
            }
        }
    })
    </script>
  4. v-for迭代數字:
    <div id="app">
    <p v-for="count in 10">這是第{{count}}次迴圈</p>
    </div>
    <script type="text/javascript">
    var app = new Vue({
        el: '#app',
    })
    </script>
  5. v-for中的key屬性的使用:
    <div id="app">
    <div>
        <label>Id:
            <input type="text" v-model="id" />
        </label>
        <label>Name:
            <input type="text" v-model="name" />
        </label>
        <input type="button" @click="add" value="新增" />
    </div>
    <p v-for="item in list" :key='item.id'>
        <input type="checkbox" />{{item.id}} --- {{item.name}}
    </p>
    </div>
    <script type="text/javascript">
    var app = new Vue({
        el: '#app',
        data: {
            id: '',
            name: '',
            list: [
                { id: 1, name: '李斯' },
                { id: 2, name: '嬴政' },
                { id: 3, name: '趙高' },
            ]
        },
        methods: {
            add(){
                this.list.unshift({ id: this.id, name: this.name });
            }
        }
    })
    </script>

v-on

  1. 簡介: 它是來 繫結事件監聽器 的,這樣我們就可以進行一下互動。
  2. 例如:
    <div id="app">
    <input type="button" v-on:click="click" value="點此彈出語句"/>
    </div>
    <script type="text/javascript">
    var app = new Vue({
        el: '#app',
        methods: {
            click(){
                alert('Hello Vue!');
            }
        }
    })
    </script>
    • v-on可簡寫為@

v-bind

  1. 簡介: v-bind指令主要用於 繫結屬性,可以動態地繫結一個或多個屬性,比如 class屬性、style屬性、value屬性、href屬性,只要是屬性,就可以用v-bind進行繫結。它的語法是: v-bind:屬性名 = "變數名",規定v-bind可以縮寫為:,如語法可以縮寫為:屬性名 = "變數名"
  2. 繫結 HTML Class:
    • 物件語法: 我們可以傳給v-bind:class一個物件,以動態地切換 class屬性,如:
      <div v-bind:class="{ active: isActive }"></div>
      <script>
      var vm = new Vue({
          el: '#app',
          data: {
              isActive: true  //此時可以展示active
          }
      })
      </script>
    • 上述表示 active 是否被展現取決於 isActive 是否為真。
    • 此外,可以在物件中傳入多個屬性來動態地切換 class,例如下面的模板:
       <div class="static" v-bind:class="{ A:isA, 'B': isB }"></div>
       <script>
          var vm = new Vue({
              el: '#app',
              data: {
                  isA: true,
                  isB: false,
              }
          })
       //結果渲染為: <div class="static isA"></div>
       </script>
    • 當然,繫結的物件也不必內聯定義在模板裡,而是用一個物件名代替:
       <div v-bind:class="classObject"></div>
       <script>
          var vm = new Vue({
              el: '#app',
              data: {
                  classObject{
                      isA: true,
                      isB: false,
                  }
              }
          })
       </script>
    • 我們也可以繫結一個返回物件的計算屬性,這是一個強大而且常用的模式:
       <div v-bind:class="classObject"></div>
       <script>
          var vm = new Vue({
              el: '#app',
              data: {
                  isA: true,
                  isB: false,
              },
              computed: {
                  classObject: function () {
                      return {
                          active: this.isA && !this.isB,
                          statiq: this.isB && this.isB.type === 'fatal'
                      }
                  }
              }
          })
       </script>
    • 陣列語法: 我們可以把一個陣列傳給 v-bind:class,以應用一個 class列表:
       <div id="app">
          <div v-bind:class="[activeClass, errorClass]"></div>
       </div>
       <script>
          var vm = new Vue({
              el: '#app',
              data: {
                  activeClass: 'active',
                  errorClass: 'text-danger'
              }
          })
       //渲染為  <div class="active text-danger"></div>
       </script>
  3. 注: 關於v-bind指令詳解請參考: 詳解v-bind指令 以及 vue.js中的v-bind語法的使用詳解

v-model

  1. 簡介: 這個指令用於 在表單上建立雙向資料繫結v-model會忽略所有表單元素的 value、checked、selected特性的初始值,因為v-model選擇Vue例項資料來作為具體的值。
  2. 例如:
    <div id="app">
        <input v-model="somebody">
        <p>hello {{somebody}}</p>
    </div>
    <script>
    var app = new Vue({
        el: '#app',
        data: {
            somebody: '小明'
        }
    })
    </script>

v-pre

  1. 簡介: v-pre按原樣輸出,標籤中的內容是什麼就輸出什麼,主要用來跳過這個元素以及它的子元素的編譯過程,可以用來顯示原始的Mustache標籤。
  2. 例如:
    <div id="app">
        <p v-pre>{{msg}}</p>
        <p>{{msg}}</p>
    </div>
    <script>
    var app = new Vue({
        el: '#app',
        data: {
            msg:"'v-pre'是不會管我的..."
        }
    })
    </script>

v-cloak

  1. 簡介: 還記得上文中提到的 頁面閃爍 嗎,我們也可以用v-cloak來解決這一問題。
    這個指令用來保持在元素上直到關聯例項結束時進行編譯。
  2. 例如:
    <div id="app" v-cloak> {{context}} </div>
    <script>
    var app = new Vue({
        el: '#app',
        data: {
            context:'Hello Vue!'
        }
    });
    //用'v-cloak'則不會出現閃爍
    </script>

v-once

  1. v-once關聯的例項 只會渲染一次,執行 一次性地插值,當資料改變時,插值處的內容不會更新,v-once所定義的元素或元件只會渲染一次,首次渲染後,不再隨著資料的改變而重新渲染。若之後牽涉到重新渲染,那麼 它關聯的例項及其所有子節點 會被視為 靜態內容 而被跳過,這可以用來優化更新效能。
  2. 例如:
    <div id="app">
        <p v-once>{{msg}}</p>
        <p>{{msg}}</p>
        <p> <input type="text" v-model="msg" name=""> </p>
    </div>
    <script type="text/javascript">
    var vm = new Vue({
        el: '#app',
        data: {
            msg: "hello"
        }
    });
    </script>

相關文章