VueJs(3)---V-指令(1)
一、語法
v- 指令是帶有v-的特殊屬性
- v-if 條件渲染
- v-show
- v-else (必須在v-if/v-else-if/v-show指令后)
- v-else-if (v-if/v-else-if后)
- v-for (遍歷)
- v-html (綁定HTML屬性中的值) (本篇先講這6個)
- v-bind (響應更新HTML特性,綁定自定義屬性,如綁定某個class元素或style)
- v-on (監聽指定元素的dom事件)
- v-model (內置的雙向數據綁定,用在表單控件,綁定的value通常是靜態字符串)
- v-cloak 關於vuejs頁面閃爍{{message}}
- v-once 只渲染元素和組件一次,隨后的重新渲染,元素/組件及其所有的子節點將被視為靜態內容並跳過
v-text和v-html
v-test
<span v-text="msg"></span> <!-- 和下面的一樣 --> <span>{{msg}}</span>
v-html :如果你的數據是“<h1>標題文字<h1>"那么它會解析成下面的,v-test永遠是按文本輸出。
v-show、v-if、v-else、v-else-if
v-show
根據表達式之真假值,切換元素的 display
CSS 屬性。
<h1 v-show="ok">Hello!</h1>
不同的是帶有 v-show
的元素始終會被渲染並保留在 DOM 中。v-show
只是簡單地切換元素的 CSS 屬性 display
注意,v-show
不支持 <template>
元素,也不支持 v-else
v-if
根據表達式的值的真假條件渲染元素。在切換時元素及它的數據綁定 / 組件被銷毀並重建。如果元素是 <template>
,將提出它的內容作為條件塊。
<h1 v-if="ok">Yes</h1> <!--也可以和v-else一起用--> <h1 v-if="ok">Yes</h1> <h1 v-else>No</h1>
在 <template>
元素上使用 v-if
條件渲染分組
因為 v-if
是一個指令,所以必須將它添加到一個元素上。但是如果想切換多個元素呢?此時可以把一個 <template>
元素當做不可見的包裹元素,並在上面使用 v-if
。最終的渲染結果將不包含 <template>
元素。
<template v-if="ok"> <h1>Title</h1> <p>Paragraph 1</p> <p>Paragraph 2</p> </template>
v-else
你可以使用 v-else
指令來表示 v-if
的“else 塊
<div v-if="Math.random() > 0.5"> Now you see me </div> <div v-else> Now you don't </div>
注意:v-else
元素必須緊跟在帶 v-if
或者 v-else-if
的元素的后面,否則它將不會被識別。
v-else-if
v-else-if
,顧名思義,充當 v-if
的“else-if 塊”,可以連續使用
<div v-if="type === 'A'"> A </div> <div v-else-if="type === 'B'"> B </div> <div v-else> Not A/B/C </div>
v-if
vs v-show
v-if
是“真正”的條件渲染,因為它會確保在切換過程中條件塊內的事件監聽器和子組件適當地被銷毀和重建。
v-if
也是惰性的:如果在初始渲染時條件為假,則什么也不做——直到條件第一次變為真時,才會開始渲染條件塊。
相比之下,v-show
就簡單得多——不管初始條件是什么,元素總是會被渲染,並且只是簡單地基於 CSS 進行切換。
一般來說,v-if
有更高的切換開銷,而 v-show
有更高的初始渲染開銷。因此,如果需要非常頻繁地切換,則使用 v-show
較好;如果在運行時條件很少改變,則使用 v-if
較好。
v-for
v-for需要用特定語法:alias in expression 為當前遍歷的元素提供別名
<!--常見的四種用法--> <div v-for="item in items"> {{ item.text }}</div> <div v-for="(item, index) in items"></div> <div v-for="(val, key) in object"></div> <div v-for="(val, key, index) in object"></div>
v-for
默認行為試着不改變整體,而是替換元素。迫使其重新排序的元素,你需要提供一個 key
的特殊屬性
<div v-for="item in items" :key="item.id"> {{ item.text }} </div>
案例官網:v-for列表渲染
key
當 Vue.js 用 v-for
正在更新已渲染過的元素列表時,它默認用“就地復用”策略。如果數據項的順序被改變,Vue 將不會移動 DOM 元素來匹配數據項的順序, 而是簡單復用此處每個元素,並且確保它在特定索引下顯示已被渲染過的每個元素。這個類似 Vue 1.x 的 track-by="$index"
為了給 Vue 一個提示,以便它能跟蹤每個節點的身份,從而重用和重新排序現有元素,你需要為每項提供一個唯一 key
屬性。理想的 key
值是每項都有的且唯一的 id。這個特殊的屬性相當於 Vue 1.x 的 track-by
,但它的工作方式類似於一個屬性,所以你需要用 v-bind
來綁定動態值 (在這里使用簡寫)
<div v-for="item in items" :key="item.id"> <!-- 內容 --> </div>
注意事項
由於 JavaScript 的限制,Vue 不能檢測以下變動的數組:
- 當你利用索引直接設置一個項時,例如:
vm.items[indexOfItem] = newValue
- 當你修改數組的長度時,例如:
vm.items.length = newLength
舉個例子:
var vm = new Vue({ data: { items: ['a', 'b', 'c'] } }) vm.items[1] = 'x' <!--不是響應性的--> vm.items.length = 2 <!-- 不是響應性的-->
為了解決第一類問題,以下兩種方式都可以實現和 vm.items[indexOfItem] = newValue
相同的效果,同時也將觸發狀態更新:
<!-- Vue.set--> Vue.set(vm.items, indexOfItem, newValue) <!-- Array.prototype.splice--> vm.items.splice(indexOfItem, 1, newValue)
你也可以使用 vm.$set
實例方法,該方法是全局方法 Vue.set
的一個別名
vm.$set(vm.items, indexOfItem, newValue)
為了解決第二類問題,你可以使用 splice
:
vm.items.splice(newLength)
對象更改檢測注意事項
還是由於 JavaScript 的限制,Vue 不能檢測對象屬性的添加或刪除
var vm = new Vue({ data: { a: 1 } }) <!-- `vm.a` 現在是響應式的--> vm.b = 2 <!--vm.b` 不是響應式的-->
對於已經創建的實例,Vue 不能動態添加根級別的響應式屬性。但是,可以使用 Vue.set(object, key, value)
方法向嵌套對象添加響應式屬性。例如,對於:
var vm = new Vue({ data: { userProfile: { name: 'Anika' }}}) <!--你可以添加一個新的 age 屬性到嵌套的 userProfile 對象--> Vue.set(vm.userProfile, 'age', 27)
你還可以使用 vm.$set
實例方法,它只是全局 Vue.set
的別名
vm.$set(vm.userProfile, 'age', 27)
顯示過濾/排序結果
v-for
with v-if
當它們處於同一節點,v-for
的優先級比 v-if
更高,這意味着 v-if
將分別重復運行於每個 v-for
循環中。當你想為僅有的_一些_項渲染節點時,這種優先級的機制會十分有用,如下
<li v-for="todo in todos" v-if="!todo.isComplete"> {{ todo }} </li> <!--上面的代碼只傳遞了未完成的 todos。-->
而如果你的目的是有條件地跳過循環的執行,那么可以將 v-if
置於外層元素 (或 <template>
)上。如
<ul v-if="todos.length"> <li v-for="todo in todos"> {{ todo }} </li> </ul> <p v-else>No todos left!</p>
一個組件的 v-for
在自定義組件里,你可以像任何普通元素一樣用 v-for
<my-component v-for="item in items" :key="item.id"></my-component>
2.2.0+ 的版本里,當在組件中使用 v-for
時,key
現在是必須的。
然而,任何數據都不會被自動傳遞到組件里,因為組件有自己獨立的作用域。為了把迭代數據傳遞到組件里,我們要用 props
完整例子
<div id="todo-list-example"> <input v-model="newTodoText" v-on:keyup.enter="addNewTodo" placeholder="Add a todo" > <ul> <li is="todo-item" v-for="(todo, index) in todos" v-bind:key="todo.id" v-bind:title="todo.title" v-on:remove="todos.splice(index, 1)" <!--刪除一個元素--> ></li> </ul> </div>
組件
Vue.component('todo-item', { template: '\ <li>\ {{ title }}\ <!--z這里有兩個地方不太明白1:"/"是什么意思。 2:這里的remove是什么意思,是調用上面的remove嗎?求解。--> <button v-on:click="$emit(\'remove\')">X</button>\ </li>\ ', props: ['title'] }) new Vue({ el: '#todo-list-example', data: { newTodoText: '', todos: [ { id: 1, title: 'Do the dishes', }, { id: 2, title: 'Take out the trash', }, { id: 3, title: 'Mow the lawn' } ], nextTodoId: 4 }, methods: { addNewTodo: function () { this.todos.push({ <!--push代表末尾添加--> id: this.nextTodoId++, title: this.newTodoText }) this.newTodoText = '' } } })
注意這里的 is="todo-item"
屬性。這種做法在使用 DOM 模板時是十分必要的,因為在 <ul>
元素內只有 <li>
元素會被看作有效內容。
動態效果看官網:一個組件的v-for
想的太多,做的太少,中間的落差就是煩惱,要么去做,要么別想 中尉【13】