文章出處

前面的話

  如果只使用Vue最基礎的聲明式渲染的功能,則完全可以把Vue當做一個模板引擎來使用。本文將詳細介紹Vue模板內容

 

概述

  Vue.js使用了基于HTML的模板語法,允許聲明式地將DOM綁定至底層Vue實例的數據。所有Vue.js的模板都是合法的HTML ,所以能被遵循規范的瀏覽器和HTML解析器解析

  在底層的實現上, Vue將模板編譯成虛擬DOM渲染函數。結合響應系統,在應用狀態改變時, Vue能夠智能地計算出重新渲染組件的最小代價并應用到DOM操作上

  一般地,模板內容包括文本內容和元素特性

 

文本渲染

【文本插值】

  文本渲染最常見的形式是使用雙大括號語法來進行文本插值,下面的message相當于一個變量或占位符,最終會表示為真正的文本內容 

<div id="app">
  {{ message }}
</div>
<script>
new Vue({
  el: '#app',
  data:{
      'message': '<span>測試內容</span>'
  }
})
</script>

【表達式插值】

{{ number + 1 }}
{{ ok ? 'YES' : 'NO' }}
{{ message.split('').reverse().join('') }}

  上面這些表達式會在所屬Vue實例的數據作用域下作為JS被解析。有個限制就是,每個綁定都只能包含單個表達式,所以下面的例子都不會生效

  模板表達式都被放在沙盒中,只能訪問全局變量的一個白名單,如MathDate。不應該在模板表達式中試圖訪問用戶定義的全局變量

<!-- 這是語句,不是表達式 -->
{{ var a = 1 }}
<!-- 流控制也不會生效,請使用三元表達式 -->
{{ if (ok) { return message } }}

  [注意]關于表達式與語句的區別移步至此

<div id="app">
  {{ num + 1 }}
</div>
<script>
new Vue({
  el: '#app',
  data:{
      'num': -1
  }
})
</script>

【v-text】

  實現插值類似效果的另一種寫法是使用v-text指令,該指令用于更新元素的innerText。如果要更新部分的innerText,需要使用模板插值

  [注意]v-text優先級高于模板插值的優先級

<div id="app" v-text="message">
</div>
<script>
new Vue({
  el: '#app',
  data:{
       message:"This is a <i>simple</i> document"
  }
})
</script>

【v-html】 

  如果要輸出真正的 HTML ,需要使用 v-html 指令,該指令用于更新元素的 innerHTML

  [注意]在網站上動態渲染任意 HTML 是非常危險的,因為容易導致 XSS 攻擊。只在可信內容上使用 v-html,而不用在用戶提交的內容上

<div id="app" v-html="message">
</div>
<script>
new Vue({
  el: '#app',
  data:{
       message:"This is a <i>simple</i> document"
  }
})
</script>

 

靜態插值

  上面介紹了模板插值,一般地,模板插值是動態插值。即無論何時,綁定的數據對象上的占位符內容發生了改變,插值處的內容都會更新

<div id="app">  {{ message }}</div>
<script>
var vm = new Vue({
  el: '#app',
  data:{
      'message': '測試內容'
  }
})
</script>

  結果如下圖所示,vm.message的內容發生了改變,DOM結構中的元素內容也相應地更新

【v-once】

   如果要實現靜態插值,即執行一次性插值,數據改變時,插值處內容不會更新,這時需要用到v-once指令

<div id="app" v-once>{{ message }}</div>
<script>
var vm = new Vue({
  el: '#app',
  data:{
      'message': '測試內容'
  }
})
</script>

  由下圖所示,vm.message改變為123時,DOM結構中元素內容仍然是“測試內容”

 

不渲染

【v-pre】

  如果要跳過這個元素和它的子元素的編譯過程,只用來顯示原始大括號及標識符,則可以使用v-pre指令。這樣,可以減少編譯時間

<div id="example" v-pre>{{message}}</div>
<script>
var vm = new Vue({
  el: '#example',
  data:{
    //如果使用v-pre指令,則不會被表示為match
    message:'match'
  },
})
</script>

 

隱藏未編譯

  一般地,使用模板差值時,頁面上會顯示大括號及占位符。編譯完成后,再轉換為真正的值。如果在網絡條件不好的情況下,這種現象更加明顯

<div id="example">{{message}}</div>
<script src="https://unpkg.com/vue"></script>
<script>
var vm = new Vue({
  el: '#example',
  data:{
    message:'match'
  },
})
</script>

【v-cloak】

  這個指令保持在元素上直到關聯實例結束編譯。和 CSS 規則如 [v-cloak] { display: none } 一起用時,這個指令可以隱藏未編譯的 Mustache 標簽直到實例準備完畢

<style>
[v-cloak]{display:none;} 
</style>
<div id="example" v-cloak>{{message}}</div>
<script src="https://unpkg.com/vue"></script>
<script>
var vm = new Vue({
  el: '#example',
  data:{
    message:'match'
  },
})
</script>

  

特性渲染

  HTML共有16個全局屬性(或稱為特性),Vue.js支持對特性的內容進行動態渲染

  [注意]對象屬性(property)和元素特性(attribute)的區別移步至此

  特性渲染時不能使用雙大括號語法

<div id="app" title={{my-title}}></div>
<script>
var vm = new Vue({
  el: '#app',
  data:{
      'my-title': '測試內容'
  }
})
</script>

  使用上面代碼時,控制臺會顯示如下錯誤

【v-bind】

  上面的錯誤提示中提到,應該使用v-bind指令,通過v-bind指令可以動態地綁定一個或多個特性

  在這里title是參數,告知v-bind指令將該元素的title屬性與表達式message的值綁定

<div id="app" v-bind:title="message"></div>

  由于v-bind指令非常常用,可縮寫如下

<div id="app" :title="message"></div>
<script>
new Vue({
  el: '#app',
  data:{
       message:"我是小火柴"
  }
})
</script>

  對布爾值的屬性也有效——如果條件被求值為false,該屬性會被移除

<button id="app" :disabled="isButtonDisabled">按鈕</button>
<script>
var vm = new Vue({
  el: '#app',
  data:{
      'isButtonDisabled': true
  }
})
</script>

 

class綁定

  數據綁定一個常見需求是操作元素的class列表和它的內聯樣式。因為它們都是屬性 ,可以用v-bind處理它們:只需要計算出表達式最終的字符串。不過,字符串拼接麻煩又易錯。因此,在v-bind用于classstyle時, Vue.js 專門增強了它。表達式的結果類型除了字符串之外,還可以是對象或數組

  綁定class包括對象語法、數組語法和組件綁定

【對象語法】

  可以傳給 v-bind:class 一個對象,以動態地切換 class 

<div v-bind:class="{ active: isActive }"></div>

  上面的語法表示 class active 的更新將取決于數據屬性 isActive 是否為真值 

  可以在對象中傳入更多屬性來動態切換多個class。v-bind:class指令可以與普通的class屬性共存

<div id="app" class="static"
     v-bind:class="{ active: isActive, 'text-danger': hasError }">
</div>
<script>
var app = new Vue({
  el: '#app',
  data:{
       isActive:true,
       hasError:false
  }
})
</script>

  當 isActive 或者 hasError 變化時,class 列表將相應地更新。例如,如果 hasError的值為 true , class列表將變為 "static active text-danger"

  也可以直接綁定數據里的一個對象

<div id="app" :class="classObject"></div>
<script>
var app = new Vue({
  el: '#app',
  data:{
    classObject: {
      active: true,
      'text-danger': false
    }
  }
})
</script>

  也可以在這里綁定返回對象的計算屬性。這是一個常用且強大的模式

<div id="app" :class="classObject"></div>
<script>
var app = new Vue({
  el: '#app',
  data: {
    isActive: true,
    error: null
  },
  computed: {
    classObject: function () {
      return {
        active: this.isActive && !this.error,
        'text-danger': this.error && this.error.type === 'fatal',
      }
    }
  }
})
</script>

【數組語法】

  可以把一個數組傳給 v-bind:class ,以應用一個 class 列表

<div id="app" :class="[activeClass, errorClass]"></div>
<script>
var app = new Vue({
  el: '#app',
  data: {
    activeClass: 'active',
    errorClass: 'text-danger'
  }
})
</script>

  如果要根據條件切換列表中的 class ,可以用三元表達式

<div id="app" :class="[isActive ? activeClass : '', errorClass]"></div>

  此例始終添加 errorClass ,但是只有在 isActive 是 true 時添加 activeClass

  不過,當有多個條件 class 時這樣寫有些繁瑣。可以在數組語法中使用對象語法

<div id="app" :class="[{ active: isActive }, errorClass]"></div>

【組件綁定】

  在一個定制組件上用到class屬性時,這些類將被添加到根元素上面,這個元素上已經存在的類不會被覆蓋

<div id="app" class="test">
  <my-component class="baz boo"></my-component>
</div>
<script>
Vue.component('my-component', {
  template: '<p class="foo bar">Hi</p>'
})
var app = new Vue({
  el: '#app'
})
</script>

  HTML 最終將被渲染為如下所示

  同樣的適用于綁定 HTML class

<div id="app" class="test">
  <my-component :class="{ active: isActive }"></my-component>
</div>
<script>
Vue.component('my-component', {
  template: '<p class="foo bar">Hi</p>'
})
var app = new Vue({
  el: '#app',
  data:{
    isActive:true
  }
})
</script>

 

style綁定

【對象語法】

  v-bind:style的對象語法十分直觀——看著非常像 CSS ,其實它是一個JS對象。 CSS屬性名可以用駝峰式 (camelCase)或(配合引號的)短橫分隔命名 (kebab-case)

<div id="app" :style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
<script>
var app = new Vue({
  el: '#app',
  data: {
    activeColor: 'red',
    fontSize: 30
  }
})
</script>

  直接綁定到一個樣式對象通常更好,讓模板更清晰

<div id="app" :style="styleObject"></div>
<script>
var app = new Vue({
  el: '#app',
  data: {
    styleObject: {
      color: 'red',
      fontSize: '13px'
    }
  }
})
</script>

【數組語法】

  v-bind:style 的數組語法可以將多個樣式對象應用到一個元素上

<div id="app" :style="[baseStyles, overridingStyles]"></div>
<script>
var app = new Vue({
  el: '#app',
  data: {
    baseStyles: {
      color: 'red',
      fontSize: '13px'
    },
    overridingStyles:{
      height:'100px',
      width:'100px'
    }
  }
})
</script>

【前綴】

  當v-bind:style使用需要特定前綴的CSS屬性時,如transform,Vue.js會自動偵測并添加相應的前綴

  可以為 style 綁定中的屬性提供一個包含多個值的數組,常用于提供多個帶前綴的值

<div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }">

  這會渲染數組中最后一個被瀏覽器支持的值。在這個例子中,如果瀏覽器支持不帶瀏覽器前綴的 flexbox,那么渲染結果會是 display: flex

 

過濾器

  Vue.js允許自定義過濾器,可被用作一些常見的文本格式化。過濾器可以用在兩個地方:模板插值和v-bind表達式。過濾器應該被添加在JS表達式的尾部,由“管道”符指示

{{ message | capitalize }}
<div v-bind:id="rawId | formatId"></div>

  過濾器設計目的是用于文本轉換。為了在其他指令中實現更復雜的數據變換,應該使用計算屬性

  過濾器有兩種注冊形式

  1、一種是使用Vue.filter()方法

// 注冊
Vue.filter('my-filter', function (value) {
  // 返回處理后的值
})
// getter,返回已注冊的過濾器
var myFilter = Vue.filter('my-filter')

  2、另一種是在Vue構造函數或組件中使用filters參數

var app = new Vue({
  el: '#app',
  filters: {
    'my-filter': function (value) {
      //
    }
  }
})

  過濾器函數總接受表達式的值 (之前的操作鏈的結果) 作為第一個參數。在這個例子中,capitalize 過濾器函數將會收到 message 的值作為第一個參數

<div id="app">
  {{ message}} 
  {{ message | capitalize }}  
</div>
<script>
var app = new Vue({
  el: '#app',
  data:{
    message: '小火柴'
  },
  filters: {
    capitalize: function (value) {
      if (!value) return ''
      value = value.toString()
      return value.split('').reverse().join('')
    }
  }
})
</script>

  過濾器可以串聯

{{ message | filterA | filterB }}

  在這個例子中,filterA 擁有單個參數,它會接收 message 的值,然后調用 filterB,且 filterA 的處理結果將會作為 filterB 的單個參數傳遞進來

<div id="app">
  {{ message}} 
  {{ message | filterA | filterB }} 
</div>
<script>
var app = new Vue({
  el: '#app',
  data:{
    message: '小火柴'
  },
  filters: {
    filterA: function (value) {
      return value.split('').reverse().join('')
    },
    filterB: function(value){
      return value.length
    }
  }
})
</script>

  過濾器是JS函數,因此可以接受參數

{{ message | filterA('arg1', arg2) }}

  這里,filterA 是個擁有三個參數的函數。message 的值將會作為第一個參數傳入。字符串 'arg1' 將作為第二個參數傳給 filterA,表達式 arg2 的值將作為第三個參數

<div id="app">
  {{ message}} 
  {{ message | filterA('arg1', arg) }}
</div>
<script>
var app = new Vue({
  el: '#app',
  data:{
    message: '小火柴',
    arg: 'abc'
  },
  filters: {
    filterA: function (value,arg1,arg2) {
      return value + arg1 + arg2
    }
  }
})
</script>

  下面是過濾器在v-bind表達式中使用的一個例子

<div id="app" :class="raw | format"></div>
<script>
var app = new Vue({
  el: '#app',
  data:{
    raw: 'active'
  },
  filters: {
    format: function (value) {
      return value.split('').reverse().join('')
    }
  }
})
</script>

 


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()