列表渲染
列表渲染
用 v-for 把一个数组对应为一组元素
我们可以用 v-for 指令基于一个数组来渲染一个列表。v-for 指令需要使用 item in items 形式的特殊语法,其中 items 是源数据数组,而 item 则是被迭代的数组元素的别名。
<ul id="example-1">
  <li v-for="item in items" :key="item.message">
    {{ item.message }}
  </li>
</ul>
var example1 = new Vue({
  el: '#example-1',
  data: {
    items: [
      { message: 'Foo' },
      { message: 'Bar' }
    ]
  }
})
结果:
- Foo
- bar
在 v-for 块中,我们可以访问所有父作用域的 property。v-for 还支持一个可选的第二个参数,即当前项的索引。
<ul id="example-2">
  <li v-for="(item, index) in items">
    {{ parentMessage }} - {{ index }} - {{ item.message }}
  </li>
</ul>
var example2 = new Vue({
  el: '#example-2',
  data: {
    parentMessage: 'Parent',
    items: [
      { message: 'Foo' },
      { message: 'Bar' }
    ]
  }
})
结果:
- Parent-0-Foo
- Parent-1-Bar
你也可以用 of 替代 in 作为分隔符,因为它更接近 JavaScript 迭代器的语法:
<div v-for="item of items"></div>
在 v-for 里使用对象
你也可以用 v-for 来遍历一个对象的 property。
<ul id="v-for-object" class="demo">
  <li v-for="value in object">
    {{ value }}
  </li>
</ul>
new Vue({
  el: '#v-for-object',
  data: {
    object: {
      title: 'How to do lists in Vue',
      author: 'Jane Doe',
      publishedAt: '2020-04-10'
    }
  }
})
结果:
- How to do lists in Vue
- Jane Doe
- 2020-04-10
你也可以提供第二个的参数为 property 名称 (也就是键名):
<div v-for="(value, name) in object">
  {{ name }}: {{ value }}
</div>
- title: How to do lists in Vue
- author: Jane Doe
- publishedAt: 2020-04-10
还可以用第三个参数作为索引:
<div v-for="(value, name, index) in object">
  {{ index }}. {{ name }}: {{ value }}
</div>
为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key attribute:
<div v-for="item in items" v-bind:key="item.id">
  <!-- 内容 -->
</div>
建议尽可能在使用 v-for 时提供 key attribute,除非遍历输出的 DOM 内容非常简单,或者是刻意依赖默认行为以获取性能上的提升。
因为它是 Vue 识别节点的一个通用机制,key 并不仅与 v-for 特别关联。后面我们将在指南中看到,它还具有其它用途。
数组更新检测
变更方法
Vue 将被侦听的数组的变更方法进行了包裹,所以它们也将会触发视图更新。这些被包裹过的方法包括:
- push()
- pop()
- shift()
- unshift()
- splice()
- sort()
- reverse()
替换数组
变更方法,顾名思义,会变更调用了这些方法的原始数组。相比之下,也有非变更方法,例如 filter()、concat() 和 slice()。它们不会变更原始数组,而总是返回一个新数组。当使用非变更方法时,可以用新数组替换旧数组:
example1.items = example1.items.filter(function (item) {
  return item.message.match(/Foo/)
})
显示过滤/排序后的结果
有时,我们想要显示一个数组经过过滤或排序后的版本,而不实际变更或重置原始数据。在这种情况下,可以创建一个计算属性,来返回过滤或排序后的数组。
例如:
<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 循环中) 你可以使用一个方法:
<ul v-for="set in sets">
  <li v-for="n in even(set)">{{ n }}</li>
</ul>
data: {
  sets: [[ 1, 2, 3, 4, 5 ], [6, 7, 8, 9, 10]]
},
methods: {
  even: function (numbers) {
    return numbers.filter(function (number) {
      return number % 2 === 0
    })
  }
}
v-for 与 v-if 一同使用
当它们处于同一节点,v-for 的优先级比 v-if 更高,这意味着 v-if 将分别重复运行于每个 v-for 循环中。当你只想为部分项渲染节点时,这种优先级的机制会十分有用,如下:
<li v-for="todo in todos" v-if="!todo.isComplete">
  {{ todo }}
</li>
案例--品牌列表
<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="../css/bootstrap.css">
    <link rel="stylesheet" href="../css/bootstrap3/css/bootstrap.css">
    <script src="../js/vue.js"></script>
</head>
<body>
    <div id="app" class="mx-3">
        <!-- 添加一条数据 -->
        <div class="panel panel-primary">
            <div class="panel-heading">
                <h3 class="panel-title">添加品牌</h3>
            </div>
            <div class="panel-body form-inline">
                <label>
                    <!-- Id: -->
                    <input class="form-control mx-2" type="text" v-model="addId" placeholder="添加的ID">
                </label>
                <label>
                    <!-- name: -->
                    <input class="form-control mx-2" type="text" v-model="addName" placeholder="添加的Name">
                </label>
                <button class="btn btn-info mx-2" @click="add">添加</button>
                <label>
                    <!-- 搜索名称或关键字: -->
                    <input type="text" class="form-control mx-2" placeholder="搜索名称或关键字:" v-model:value="keyWords" />
                </label>
            </div>
        </div>
        <table class="table table-bordered table-hover">
            <thead>
                <th>Id</th>
                <th>Name</th>
                <th>Ctime</th>
                <th>Operation</th>
            </thead>
            <tbody>
                <tr v-for="items in search(keyWords)" :key="items.id">
                    <td v-for="item in items">{{item}}</td>
                    <td>
                        <!-- 根据编号删除一条数据 -->
                        <button class="btn btn-danger" @click="del(items.id)">删除</button>
                    </td>
                </tr>
            </tbody>
        </table>
    </div>
</body>
<script>
    var vm = new Vue({
        el: "#app",
        data: {
            addId: '',
            addName: '',
            keyWords: "",
            list: [{
                    id: 1,
                    name: '奔驰',
                    ctime: new Date()
                },
                {
                    id: 2,
                    name: '宝马',
                    ctime: new Date()
                },
                {
                    id: 3,
                    name: '捷豹',
                    ctime: new Date()
                },
                {
                    id: 4,
                    name: '路虎',
                    ctime: new Date()
                }
            ]
        },
        methods: {
            add() {
                this.list.push({
                    id: this.addId,
                    name: this.addName,
                    ctime: new Date()
                });
                this.addId = this.addName = null;
            },
            del(id) {
                //在数组的some方法中如果return true就会终止循环
                this.list.some((item, i) => {
                    if (item.id == id) {
                        //从第i个位置移除1个元素。
                        this.list.splice(i, 1);
                        return true;
                    }
                })
            },
            search(keyWords) { //根据关键字进行数据的搜索
                var newList = [];
                this.list.forEach(item => {
                    if (item.name.indexOf(keyWords) != -1)
                        newList.push(item);
                })
                return newList;
            }
        }
    });
</script>
</html>
 
                    
                
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号