首頁 >web前端 >js教程 >vuejs中列表渲染的詳細介紹

vuejs中列表渲染的詳細介紹

不言
不言原創
2018-08-14 16:47:382820瀏覽

這篇文章帶給大家的內容是關於vuejs中清單渲染的詳細介紹,有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。

用v-for把一個陣列對應到一組元素

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

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

在v-for快中,我們擁有對父作用域屬性的完全存取權。 v-for也支援一個可選的第二個參數為目前項目的索引。

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

你也可以用of取代in當分隔符,因為他是最接近javascript迭代器的語法

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

一個物件的v-for

你也可以用v-for透過一個物件的屬性來迭代。

<ul id="v-for-object" class="demo">
<li v-for="value in object">
{{ value }}
</li>
</ul>
new Vue({
el: &#39;#v-for-object&#39;,
data: {
object: {
firstName: &#39;John&#39;,
lastName: &#39;Doe&#39;,
age: 30
}
}
})

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

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

第三個參數為索引:

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

在遍歷物件時,是按Object.key()的結果遍歷,但是不能保證他的結果在不同的javascript引擎下是一致的,

key

當vue.js用v-for正在更新已渲染過的元素清單時,他預設用「就地複用」策略。如果資料項的順序被改變。 vue將不會移動dom元素來匹配資料項的順序,而是簡單地複用此處每個元素,並確保他在特定索引下顯示被渲染過的每個元素。這個類似vue1.x的track-by="$index"。

這個預設的模式是高效率的,但只適用於不依賴子元件狀態或暫存dom狀態(例如:表單輸入值)的清單渲染輸出。

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

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

建議盡可能在使用v-for時提供key,除非遍歷輸出的dom內容非常簡單,或者是可以依賴預設行為以取得效能上的提升。

因為他是vue辨識節點的一個通用機制,key並不是與v-for特別關聯,key還具有其他用途,

陣列更新偵測

#編譯方法

vue包含一直觀察陣列的編譯方法,所以他們也會觸發視圖更新。

* push()———進數組

#* pop()————出數組

* shift()————

* unshift()

* splice()————分割陣列

* sort() ————對陣列排序

* reverse()————翻轉陣列

#取代陣列

變異方法,會改變這些方法呼叫的原始陣列。相比之下,也有非變異方法。例如:filter(), concat() 和 slice() 。

這些不會改變原始數組,但總是會傳回一個新數組 。當時用非變異方法時,可以用新數組替換就數組

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

你可能認為這將導致vue丟棄現有dom並重新渲染整個清單。幸運的是,事實並非如此,vue為了使得dom元素得到最大範圍的重用而實現了一些智能的、啟發式的方法,所以用一個含有相同元素的數組去替換原來的數組是非常高效的操作。

注意事項

由於javascript的限制,vue無法偵測以下變動的陣列

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

2、當你修改陣列的長度時,例如: vm.items.length = newLength

var vm = new Vue({
data: {
items: [&#39;a&#39;, &#39;b&#39;, &#39;c&#39;]
}
})
vm.items[1] = &#39;x&#39; // 不是响应性的
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)

splice()方法向/从数组添加/删除项目,然后返回被删除的项目

arrayObject.splice(index,howmany,item1,.....,itemX)

index

必需。整数,规定添加/删除项目的位置,使用负数可从数组结尾处规定位置。

howmany

必需。要删除的项目数量。如果设置为 0,则不会删除项目。

item1, ..., itemX

可选。向数组添加的新项目。

对象更改检测注意事项

还是由于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: &#39;Anika&#39;
}
}
})

你可以添加一个age属性到嵌套的userProfile对象:

Vue.set(vm.userProfile, &#39;age&#39;, 27)

你还可以使用vm.$set实例方法,他只是全局vue.set的别名

vm.$set(vm.userProfile, &#39;age&#39;, 27)

有事你可能需要为已有对象赋予多个新属性,比如使用 Object.assign() 或 _.extend()。在这种情况下,你应该用两个对象的属性创建一个新的对象。所以,如果你想添加新的响应式属性,不要像这样:

Object.assign(vm.userProfile, {
age: 27,
favoriteColor: &#39;Vue Green&#39;
})
你应该这样:
vm.userProfile = Object.assign({}, vm.userProfile, {
age: 27,
favoriteColor: &#39;Vue Green&#39;
})

显示过滤/排序结果

有事,我们想要显示一个数组的过滤或排序副本,而不实际改变 或重置原始数据。在这种情况下,可以创建返回过滤或排序 数组的计算属性。

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

在计算属性不使用的情况下,(例如,在嵌套v-for循环中)你可以使用method方法。

data: {
numbers: [ 1, 2, 3, 4, 5 ]
},
methods: {
even: function (numbers) {
return numbers.filter(function (number) {
return number % 2 === 0
})
}
}

一段取值范围的v-for

v-for也可以取整数。在这种情况下 ,它将重复多刺激模板。

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

v-for on a d477f9ce7bf77f53fbcf36bec1b69b7a

类似于v-if,你也可以利用带有v-for的d477f9ce7bf77f53fbcf36bec1b69b7a渲染多个元素。

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

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 置于外层元素 (或 d477f9ce7bf77f53fbcf36bec1b69b7a)上。如:

<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>

当在组件中使用 v-for 时,key 现在是必须的。

然而,任何数据都不会被自动传递到组件里,因为组件有自己独立的作用域。为了把迭代数据传递到组件里。

我们要用props:

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

不自动将item注入到组件里的原因是,这会使得组件与v-for的运作紧密耦合。明确组件数据的来源能够使组件在其他场合重复使用。

<p id="todo-list-example">
<form v-on:submit.prevent="addNewTodo">
<label for="new-todo">Add a todo</label>
<input
v-model="newTodoText"
id="new-todo"
placeholder="E.g. Feed the cat"
>
<button>Add</button>
</form>
<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>
</p>

注意这里的is="todo-item"属性。这种做法在使用dom模板时是十分必要的。因为在ff6d136ddc5fdfeffaf53ff6ee95f185元素内只有25edfb22a4f469ecb59f1190150159c6元素 会被看做有效内容。这样做实现的效果与c20b531f5b99ef8837ce29ced08ba7cd相同。但是可以避开一些潜在的浏览器解析错误。

<p id="todo-list-example">
  <form v-on:submit.prevent="addNewTodo">
    <label for="new-todo">Add a todo</label>
    <input
      v-model="newTodoText"
      id="new-todo"
      placeholder="E.g. Feed the cat"
    >
    <button>Add</button>
  </form>
  <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>
</p>

注意这里的 is="todo-item" 属性。这种做法在使用 DOM 模板时是十分必要的,因为在 ff6d136ddc5fdfeffaf53ff6ee95f185 元素内只有 25edfb22a4f469ecb59f1190150159c6 元素会被看作有效内容。这样做实现的效果与 c20b531f5b99ef8837ce29ced08ba7cd 相同,但是可以避开一些潜在的浏览器解析错误。查看 DOM 模板解析说明 来了解更多信息。

Vue.component(&#39;todo-item&#39;, {
  template: &#39;\
    <li>\
      {{ title }}\
      <button v-on:click="$emit(\&#39;remove\&#39;)">Remove</button>\
    </li>\
  &#39;,
  props: [&#39;title&#39;]
})
 
new Vue({
  el: &#39;#todo-list-example&#39;,
  data: {
    newTodoText: &#39;&#39;,
    todos: [
      {
        id: 1,
        title: &#39;Do the dishes&#39;,
      },
      {
        id: 2,
        title: &#39;Take out the trash&#39;,
      },
      {
        id: 3,
        title: &#39;Mow the lawn&#39;
      }
    ],
    nextTodoId: 4
  },
  methods: {
    addNewTodo: function () {
      this.todos.push({
        id: this.nextTodoId++,
        title: this.newTodoText
      })
      this.newTodoText = &#39;&#39;
    }
  }
})

相关推荐:

js实现页面间数据传递的代码

reac如何t实现更换皮肤颜色的功能

 jQuery中的方法有哪些?jQuery中常用的方法(附代码)

以上是vuejs中列表渲染的詳細介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn