7.列表渲染

7.1用 v-for 把一个数组对应为一组元素

<!-- 我们可以用 v-for 指令基于一个数组来渲染一个列表。v-for 指令需要
                使用 item in items 形式的特殊语法,其中 items 是源数据数组,而 
                item 则是被迭代的数组元素的别名。 -->
    <ul id="app1">
        <li v-for="item in items">{{item.message}}</li>
    </ul>
    <script>
        var vm1 = new Vue({
            el: '#app1',
            data: {
                items: [
                    { message: 'Foo' },
                    { message: 'Bar' }
                ]
            }
        })
    </script>
<!-- 在 v-for 块中,我们可以访问所有父作用域的 property。v-for 还支
            持一个可选的第二个参数index,即当前项的索引。 -->
    <ul id="app2">
        <li v-for="(item , index) in items">{{parentMsg}} -- {{index}} -- {{item.message}}</li>
    </ul>
    <script>
        var vm1 = new Vue({
            el: '#app2',
            data: {
                parentMsg: 'Parent',
                items: [
                    { message: 'Foo' },
                    { message: 'Bar' }
                ]
            }
        })
    </script>
<!-- 你也可以用 of 替代 in 作为分隔符,因为它更接近 JavaScript 迭代器的语法: -->
    <div v-for="item of items"></div>

7.2在 v-for 里使用对象

<!-- 你也可以用 v-for 来遍历一个对象的 property。操作遍历涉及3个参数:value name index -->
    <!-- value:对象属性值 name:对象属性名 index:对象索引 -->
    <ul id="app3">
        <li v-for="(value ,name ,index) in objs">
            {{index + 1}}.{{name}} :{{value}}
        </li>
    </ul>
    <script>
        var vm = new Vue({
            el: '#app3',
            data: {
                objs: {
                    title: 'HarryPotter', //title对应对象属性名,'HarryPotter'对应对象属性值
                    author: 'JK.Rowling',
                    type: 'novel',
                    nation: 'The Britain'
                }
            }
        })
    </script>

7.3维护状态
*不太理解
建议尽可能在使用 v-for 时提供 key attribute,除非遍历输出的 DOM 内容非常简单,或者是刻意依赖默认行为以获取性能上的提升。
因为它是 Vue 识别节点的一个通用机制,key 并不仅与 v-for 特别关联。后面我们将在指南中看到,它还具有其它用途。
不要使用对象或数组之类的非基本类型值作为 v-for 的 key。请用字符串或数值类型的值。

7.4数组更新检测
7.4.1变更方法

Vue 将被侦听的数组的变更方法进行了包裹,所以它们也将会触发视图更新。这些被包裹过的方法包括:
        push()
        pop()
        shift()
        unshift()
        splice()
        sort()
        reverse()
你可以打开控制台,然后对前面例子的 items 数组尝试调用变更方法。比如 example1.items.push({ message: 'Baz' })

7.4.2替换数组
变更方法,顾名思义,会变更调用了这些方法的原始数组。

7.4.3注意事项
注意事项
由于 JavaScript 的限制,Vue 不能检测数组和对象的变化。

7.5 显示过滤/排序后的结果
显示一个数组经过过滤或排序后的版本,而不实际变更或重置原始数据。
在这种情况下,可以创建一个计算属性,来返回过滤或排序后的数组。

<!-- 示例1:通过计算属性过滤 -->
    <ul id="app4">
        <li v-for="n in evenNumbers">{{n}}</li>
    </ul>
    <script>
        var vm4 = new Vue({
            el: '#app4',
            data: {
                numbers: [1, 2, 3, 4, 5, 6]
            },
            computed: {
                evenNumbers: function () {
                    // .filter过滤器函数,过滤掉奇数数字
                    return this.numbers.filter(function (number) {
                        return number % 2 === 0; //筛选出偶数数字
                    })
                }
            }
        })
        //console.log(vm4.evenNumbers);
    </script>
<!-- 示例2:在计算属性不适用的情况下,通过methods过滤 -->
    <div id="app5">
        <ul v-for="set in sets">
            <li v-for="n in even(set)">{{n}}</li>
        </ul>
    </div>
    <script>
        var vm5 = new Vue({
            el: '#app5',
            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
                    })
                }
            }
        })
        //console.log(vm5.sets);
    </script>

7.6 在 v-for 里使用值范围

<!-- v-for 也可以接受整数。在这种情况下,它会把模板重复对应次数。 -->
    <div id="app6">
        <!-- {{n}}重复10,打印内容为1 2 3 4 5 6 7 8 9 10 -->
        <span v-for="n in 10">{{ n }}&nbsp;</span>
    </div>
    <script>
        var vm5 = new Vue({
            el: '#app6'
        })
    </script>

7.7 在 上使用 v-for

<!-- 类似于 v-if,你也可以利用带有 v-for<template> 来循环渲染一段包含多个元素的内容。比如: -->
    <div id="app7">
        <template v-for="item in items">
            <li>{{item.msg}}</li>
        </template>
    </div>
    <script>
        var vm7 = new Vue({
            el: '#app7',
            data: {
                items: [
                    { msg: 'Donald' },
                    { msg: 'Trump' },
                    { msg: 'is' },
                    { msg: 'over' }
                ]
            }
        })
    </script>

7.8 v-for 与 v-if 一同使用
7.8.1使用在同一元素上
注意:不推荐在同一元素上使用 v-if 和 v-for。
当它们处于同一节点,v-for 的优先级比 v-if 更高,这意味着 v-if 将分别重复运行于每个 v-for 循环中。当你只想为部分项渲染节点时,这种优先级的机制会十分有用,如下:

<div id="app8">
        <!-- 运行于每个todo循环中, 只渲染存在todo.isComplete的部分节点,即已完成的todo事项 -->
        <li v-for="todo in todos" v-if="todo.isComplete">
            {{todo}}
        </li>
    </div>
    <script>
        var vm8 = new Vue({
            el: '#app8',
            data: {
                todos: [
                    {
                        work: 'Math',
                        isComplete: ''
                    },
                    {
                        work: 'English',
                        isComplete: 'finish'
                    },
                    {
                        work: 'Chinese',
                        isComplete: 'finish'
                    }
                ]
            }
        })
    </script>

7.8.2使用在不同元素上
而如果你的目的是有条件地跳过循环的执行,那么可以将 v-if 置于外层元素 (或 ) 上。如:

<div id="app9">
        <!-- v-if在外层元素判断数据是否存在 -->
        <ul v-if="lists.length">
            <!-- 数据存在,调用v-for循环渲染 -->
            <li v-for="list in lists">{{list.name}}</li>
        </ul>
        <!-- 数据不存在显示提示语 -->
        <p v-else>there is no list</p>
    </div>
    <script>
        var vm9 = new Vue({
            el: '#app9',
            data: {
                lists: [
                    {
                        name: 'Bush'
                    },
                    {
                        name: 'Obama'
                    },
                    {
                        name: 'Trump'
                    }
                ]
            }
        })
    </script>

7.9 在组件上使用 v-for

<div id="app10">
        <my-component v-for="item in items" v-bind:key="item.id" v-bind:item="item"></my-component>
    </div>
    <script>
        // 然而,任何数据都不会被自动传递到组件里,因为组件有自己独立的作用域。
        // 为了把迭代数据传递到组件里,我们要使用 prop:
        Vue.component('my-component', {
            props: ['item'],
            template: `<li>{{item.id}}--{{item.name}}--{{item.price}}</li>`
        })
        var vm10 = new Vue({
            el: '#app10',
            data: {
                items: [
                    {
                        id: 1,
                        name: 'meat',
                        price: '¥11'
                    },
                    {
                        id: 2,
                        name: 'fruit',
                        price: '¥3'
                    },
                    {
                        id: 3,
                        name: 'vegetables',
                        price: '¥1'
                    }
                ]
            }
        })
    </script>
<!-- 案例:todo-list -->
    <div id="todo-list">
        <!-- 1)将提交表单和添加事项按钮合并
        2)prevent修饰符防止触发默认行为,例如提交表单 -->
        <form v-on:submit.prevent="addBtn">
            <label for="addTodo">Add a todo item</label>
            <input type="text" v-model="textVal" id="new-todo" placeholder="please enter a item">
            <button>Add</button>
        </form>
        <ul v-for="(list , index) in lists">
            <li 
            is="my-component" 
            :key="list.id" 
            :content="list.content" 
            @remove="lists.splice(index, 1)"></li>
        </ul>
    </div>
    <script>
        Vue.component('my-component', {
            props: ['content'],
            template: `\
                <li>\
                {{ content }}\
                <button v-on:click="$emit(\'remove\')">Remove</button>\
                </li>\
                `
        })

        var todoList = new Vue({
            el: '#todo-list',
            data: {
                textVal: ' ',
                lists: [
                ],
                nextId: 0
            },
            methods: {
                addBtn: function () {
                    this.lists.push({
                        id: this.nextId++,
                        content: this.textVal
                    });
                    this.textVal = '';
                    console.log(this.nextId);
                }

            }
        })
    </script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值