閱讀660 返回首頁    go 阿裏雲 go 技術社區[雲棲]


vue.js列表渲染

v-for

我們用 v-for 指令根據一組數組的選項列表進行渲染。 v-for 指令需要以 item in items 形式的特殊語法, items 是源數據數組並且 item 是數組元素迭代的別名

基本用法

<ul >
    <li v-for="item in items">{{ item.message }}</li>
</ul>
<script>
var example1 = new Vue({
    el: '#example-1',
    data: {
        items: [
            {message: 'Foo' },
            {message: 'Bar' }
        ]
    }
})
</script>

在 v-for 塊中,我們擁有對父作用域屬性的完全訪問權限。 v-for 還支持一個可選的第二個參數為當前項的索引

<ul >
    <li v-for="(item, index) in items">
        {{ parentMessage }} - {{ index }} - {{ item.message }}
    </li>
</ul>
<script>
var example2 = new Vue({
    el: '#example-2',
    data: {
        parentMessage: 'Parent',
        items: [
            { message: 'Foo' },
            { message: 'Bar' }
        ]
    }
})
</script>

你也可以用 of 替代 in 作為分隔符,因為它是最接近 JavaScript 迭代器的語法:

<div v-for="item of items"></div>

Template v-for

如同 v-if 模板,你也可以用帶有 v-for 的 標簽來渲染多個元素塊。例如:

<ul>
    <template v-for="item in items">
        <li>{{ item.msg }}</li>
        <li ></li>
    </template>
</ul>

對象迭代 v-for

你也可以用 v-for 通過一個對象的屬性來迭代

<ul  >
    <li v-for="value in object">{{ value }}</li>
</ul>
<script>
new Vue({
    el: '#repeat-object',
    data: {
        object: {
            FirstName: 'John',
            LastName: 'Doe',
            Age: 30
        }
    })
</script>

也可以提供第二個的參數為鍵名:

<div v-for="(value, key) in object">
    {{ key }} : {{ value }}
</div>

第三個參數為索引:

<div v-for="(value, key, index) in object">
  {{ index }}. {{ key }} : {{ value }}
</div>

在遍曆對象時,是按 Object.keys() 的結果遍曆,但是不能保證它的結果在不同的 JavaScript 引擎下是一致的

整數迭代 v-for

v-for 也可以取整數。在這種情況下,它將重複多次模板

<div>
    <span v-for="n in 10">{{ n }}</span>
</div>  

組件和v-for

在自定義組件裏,你可以像任何普通元素一樣用 v-for

<my-component v-for="item in items"></my-component>

然而他不能自動傳遞數據到組件裏,因為組件有自己獨立的作用域。為了傳遞迭代數據到組件裏,我們要用 props :

<my-component v-for="(item, index) in items" v-bind:item="item" v-bind:index="index"></my-component>

不自動注入 item 到組件裏的原因是,因為這使得組件會緊密耦合到 v-for 如何運作。在一些情況下,明確數據的來源可以使組件可重用

下麵是一個簡單的 todo list 完整的例子:

<div >
    <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:title="todo" v-on:remove="todos.splice(index, 1)"></li>
    </ul>
</div>
<script>
Vue.component('todo-item', {
    template: '<li>{{ title }}<button v-on:click="$emit(\'remove\')">X</button></li>',
    props: ['title']
})
new Vue({
    el: '#todo-list-example',
    data: {
        newTodoText: '',
        todos: [
            'Do the dishes',
            'Take out the trash',
            'Mow the lawn'
        ]
    },
    methods: {
        addNewTodo: function () {
            this.todos.push(this.newTodoText)
            this.newTodoText = ''
        }
    }
})
</script>

v-for with v-if

當它們處於同一節點, v-for 的優先級比 v-if 更高,這意味著 v-if 將分別重複運行於每個 v-if 循環中。當你想為僅有的 一些 項渲染節點時,這種優先級的機製會十分有用:

<li v-for="todo in todos" v-if="!todo.isComplete">{{ todo }}</li>

上麵的代碼隻傳遞了未complete的todos。而如果你的目的是有條件地跳過循環的執行,那麼將 v-if 置於包裝元素 (或 )上。如:

<ul v-if="shouldRenderTodos">
    <li v-for="todo in todos">{{ todo }}</li>
</ul>

key

當 Vue.js 用 v-for 正在更新已渲染過的元素列表時,它默認用 “就地複用” 策略。如果數據項的順序被改變,Vue將不是移動 DOM 元素來匹配數據項的順序, 而是簡單複用此處每個元素,並且確保它在特定索引下顯示已被渲染過的每個元素。這個類似 Vue 1.x 的 track-by="$index"

這個默認的模式是有效的,但是隻適用於不依賴子組件狀態或臨時 DOM 狀態(例如:表單輸入值)的列表渲染輸出

為了給 Vue 一個提示,以便它能跟蹤每個節點的身份,從而重用和重新排序現有元素,你需要為每項提供一個唯一 key 屬性。理想的 key 值是每項都有唯一 id。這個特殊的屬性相當於 Vue 1.x 的 track-by ,但它的工作方式類似於一個屬性,所以你需要用 v-bind 來綁定動態值(在這裏使用簡寫):

<div v-for="item in items" :key="item.id">
    <!-- 內容 -->
</div>

建議盡可能使用 v-for 來提供 key ,除非迭代 DOM 內容足夠簡單,或者你是故意要依賴於默認行為來獲得性能提升。
因為它是 Vue 識別節點的一個通用機製, key 並不特別與 v-for 關聯,key 還具有其他用途

數組更新檢測

變異方法

Vue 包含一組觀察數組的變異方法,所以它們也將會觸發視圖更新。這些方法如下:

push() pop() shift() unshift() splice() sort() reverse()

重塑數組

變異方法(mutation method),顧名思義,會改變被這些方法調用的原始數組。相比之下,也有非變異(non-mutating method)方法,例如: filter(), concat(), slice() 。這些不會改變原始數組,但總是返回一個新數組。當使用非變異方法時,可以用新數組替換舊數組:

example1.items = example1.items.filter(function (item) {
    return item.message.match(/Foo/)
})

你可能認為這將導致 Vue 丟棄現有 DOM 並重新渲染整個列表。幸運的是,事實並非如此。 Vue 實現了一些智能啟發式方法來最大化 DOM 元素重用,所以用一個含有相同元素的數組去替換原來的數組是非常高效的操作

注意事項

由於 JavaScript 的限製, Vue 不能檢測以下變動的數組:

當你利用索引直接設置一個項時,例如: vm.items[indexOfItem] = newValue

當你修改數組的長度時,例如: vm.items.length = newLength

為了解決第一類問題,以下兩種方式都可以實現和 vm.items[indexOfItem] = newValue 相同的效果, 同時也將觸發狀態更新:

Vue.set(example1.items, indexOfItem, newValue)  // Vue.set

example1.items.splice(indexOfItem, 1, newValue)// Array.prototype.splice`

為了解決第二類問題,你也同樣可以使用 splice:

example1.items.splice(newLength)

顯示過濾/排序結果

有時,我們想要顯示一個數組的過濾或排序副本,而不實際改變或重置原始數據。在這種情況下,可以創建返回過濾或排序數組的計算屬性

<li v-for="n in evenNumbers">{{ n }}</li>
<script>
data: {
    numbers: [ 1, 2, 3, 4, 5 ]
},
computed: {
    evenNumbers: function () {
        return this.numbers.filter(function (number) {
            return number % 2 === 0
        })
    }
}
</script>

或者,你也可以在計算屬性不適用的情況下 (例如,在嵌套 v-for 循環中) 使用 method 方法:

<li v-for="n in even(numbers)">{{ n }}</li>
<script>
data: {
    numbers: [ 1, 2, 3, 4, 5 ]
},
methods: {
    even: function (numbers) {
        return numbers.filter(function (number) {
            return number % 2 === 0
        })
    }
}
</script>

最後更新:2017-08-13 22:24:27

  上一篇:go  android,java知識點總結
  下一篇:go  互聯網醫療的發展將給予更好的服務