• 技术文章 >web前端 >Vue.js

    详解Vue渲染列表指令:v-for

    青灯夜游青灯夜游2022-08-10 17:23:33转载412

    大前端零基础入门到就业:进入学习

    之前的文章中,我们学习了在Vue中如何通过v-ifv-show根据条件渲染所需要的DOM元素或者模板。在实际的项目中,我们很多时候会碰到将JSON数据中的数组或对象渲染出列表之类的元素。在Vue中,提供了一个v-for的指令,可以渲染列表。(学习视频分享:vue视频教程

    v-for 的作用


    v-for可以基于源数据多次渲染元素或模板块。这个指令必须用特定的语法alias in expression,为当前遍历的元素提供别名:

    <div v-for="alias in expression"> {{ alias }}</div>

    一般都是给数组或对象指定别名,除此之外还可以为索引值指定别名,对于对象还可以给value指定别名,常见的几种情形如下:

    <div v-for="item in items">{{ item }}</div>
    <div v-for="(item, index) in items">{{ item }} {{ index }}</div>
    <div v-for="val in object"></div>
    <div v-for="(val, key) in object"></div>
    <div v-for="(val, key, index) in object"></div>

    其中我们也可以把in换成of作为分隔符,因为它是最接近JavaScript迭代器的语法。

    v-for的默认行为试着不改变整体,而是替换元素。迫使其重新排序的元素,你需要提供一个key的特殊属性:

    <div v-for="itme in items" :key="item.id"> {{ item.text }}</div>

    接下来,我们看看v-for的一些使用场景。

    一个数组的 v-for


    使用v-for指令把数组的选项列表进行渲染。v-for指令需要使用item in items形式的特殊语法,items是源数据数组,item是数组元素迭代的别名。来看一个简单的示例:

    <!-- Template -->
    <ul>
        <li v-for="item in items">{{ item }}</li>
    </ul>
    
    // JavaScript
    var app = new Vue({
        el: '#app',
        data: {
            items: [1, 34, 89, 92, 45, 76, 33]
        }
    })

    这个时候,数组items的每个item渲染到对应的li中,在浏览器看到的效果如下:

    上面的例子是通过v-for把数组items的每个项迭代出来放到li中,除此之外,还可以把数组的每个index也遍历出来。在上面的代码的基础上,咱们修改一下模板:

    <ul>
        <li v-for="(item, index) in items">index-{{ index }}: {{ item }}</li>
    </ul>

    这个时候数组的索引号也遍历出来了:

    从上面的示列看出来了,你需要哪个元素(HTML的标签)循环,那么v-for就写在那个元素上。

    上面我们已经可以正常的使用v-for将定义的数组每一项输出来。为了加深学习,咱们在上面的示例基础上增加一项需求,就是对输出的数组进行排序。这个时候,咱们需要使用到Vue中的computed属性。

    在Vue中,我们不能污染源数据,如果我们直接对源数据items通过sort()方法进行排序,将会报错的:

    var app = new Vue({
        el: '#app',
        computed: {
            items: function() {
                return this.items.sort()
            }
        },
        data: {
            items: [1, 34, 89, 92, 45, 76, 33]
        }
    })

    为了不会污染Vue中的源数据,需要在computed里重新声明一个对象,比如声明一个sortItems对象:

    var app = new Vue({
        el: '#app',
        computed: {
            sortItems: function() {
                return this.items.sort()
            }
        },
        data: {
            items: [1, 34, 89, 92, 45, 76, 3, 12]
        }
    })

    这个时候,我们的模板也需要做对应的修改:

    <ul>
        <li v-for="item in sortItems">{{ item }}</li>
    </ul>

    如果不出意外的话,你看到的效果将是这样的:

    虽然有变化了,但不是我们想要的排序结果。虽然结果不是我们想要的,但这并不是Vue自身的问题,在JavaScript中也是这样。如果我们要想真正的实现一个排序效果,那么需要添加一个JavaScript的数组的排序函数的功能:

    function sortNumber(a, b) {
        return a - b
    }

    computed里的代码也做一个相应的修改:

    computed: {
        sortItems: function() {
            return this.items.sort(sortNumber)
        }
    }

    这相输出的效果才真正的是一个正确的排序效果:

    上面的例子,我们看到的是是一个简单的纯数字之类的数组,其其数组中的每个项也可以是对象,比如:

    data: {
        objItems: [
            {
                firstName: 'Jack',
                lastName: 'Li',
                age: 34
            },
            {
                firstName: 'Airen',
                lastName: 'Liao',
                age: 18
            }
        ]
    }

    我们把模板换成:

     <li v-for="objItem in objItems">{{ objItem.firstName }} {{objItem.lastName}} is {{ objItem.age}} years old!</li>

    这个时候看到的效果如下:

    在JavaScript中,我们有很多数组的方法,可以对数组进行操作,这些方法可以修改一个数组。其实,在Vue中同样包含一组观察数组变异方法,这些方法将会触发元素的重新更新(视图更新),这些方法也是JavaScript中数组中常看到的方法:push()pop()shift()unshift()splice()sort()reverse()。我们可以在控制台中简单的看一下前面的示例中items数组调用变异方法的效果:

    Vue不但提供了数组变异的方法,还提供了替换数组的方法。变异方法可以通过些方法的调用修改源数据中的数组;除此之外也有对应的非变异方法,比如filter()concat()slice()等。这些方法是不会改变源数据中的原始数组,但总是返回一个新数组。当使用这些方法时,可以用新数组替换旧数组。

    由于JavaScript的限制,Vue不能检测以下变动的数组:

    为了解决第一类问题,以下两种方式都可以实现和app.items[indexOfItem = newValue相同的效果,同时也将触发状态更新:

    Vue.set(app.items, indexOfItem, newValue)
    
    app.items.splice(indexOfItem, 1, newValue)

    为了解决第二类问题,你可以使用splice():

    app.items.splice(newLength)

    对象的 v-for


    v-for除了可以使用在数组上之外还可以应用在对象上。

    <!-- Template -->
    <ul>
        <li v-for="value in obj">{{ value }}</li>
    </ul>
    
    // JavaScript
    obj: {
        firstName: 'Airen',
        lastName: 'Liao',
        age: 30
    }

    使用v-for可以把obj的每个key对应的value值遍历出来,并且填到对应的li元素中。效果如下:

    你也可以给对象的key遍历出来:

    <ul>
        <li v-for="(value, key) in obj">{{ key }}: {{ value }}</li>
    </ul>

    效果如下:

    同样,也可以类似数组一样,可以把index索引做为第三个参数:

    <ul>
        <li v-for="(value, key, index) in obj">{{ index }}. {{ key }}: {{ value }}</li>
    </ul>

    前面提到过,数组可以变异,但对于对象而言,Vue不能检测对象属性的添加或删除。这主要也是由于JavaScript的限制。不过在Vue中,对于已经创建好的实例,可以使用Vue.set(object, key, value)方法向嵌套对象添加响应式属性。例如:

    var app = new Vue({
        data: {
            obj: {
                name: 'Airen'
            }
        }
    })

    可以使用类似下面的方式,给obj对象添加一个新的属性age

    Vue.set(app.obj, 'age', 27)

    回到我们的示例中给数据源中的obj添加一个'from'key,而且其对应的value值为'江西'

    除了Vue.set()之外,还可以使用app.$set实例方法,它其实就是Vue.set的别名:

    mounted(){
        this.$set(this.obj, '职位', '码农')
    }

    这里用到了Vue中的mounted(),和computed一样,也不知道他在Vue中的作用,同样放到后面来。我们总是会搞明白的。

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

    Object.assign(this.obj, {
        age: 27,
        favoriteColor: 'Vue Green'
    })

    应该这样做:

    this.obj = Object.assign({}, this.obj, {
        age: 27,
        favoriteColor: 'Vue Green'
    })

    一段取值范围的 v-for


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

    <ul>
        <li v-for="n in 10">{{ n }}</li>
    </ul>

    结果如下:

    v-for 和 一个 <template>


    类似于v-if,你也可以利用带有v-for<template>渲染多个元素,比如:

    <ul>
        <template v-for="(value, key) in obj">
            <li>
                <label :for="key">{{ key }}:</label>
                <input type="text" :placeholder="value" :id="key" />
            </li>
        </template>
    </ul>

    效果如下:

    注意了,v-for<template>一起使用的时候,需要把v-for写在<template>元素上。另外上面的示例中,咱们还使用了Vue的一些其他特性,但这些特性不是这节内容所要学习的。后面我们会有机会一一介绍的。

    一个组件的 v-for


    在自定义组件里,也可以像任何普通元素一样用v-for

    <my-component v-for="item in items" :key="item.id"></my-component>

    2.2.0+ 的版本里,当在组件中使用 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 的运作紧密耦合。在一些情况下,明确数据的来源可以使组件可重用。

    来看一个简单的Todo示例:

    <div id="todo">
        <input
            v-model="newTodoText"
            v-on:keyup.enter="addNewTodo"
            placeholder="Add a todo"
        />
    
        <ul>
            <li
                is="todoItem"
                v-for="(todo, index) in todos"
                v-bind:title="todo"
                v-on:remove="todos.splice(index, 1)"></li>
        </ul>
    </div>
    
    Vue.component('todoItem', {
        template:`
            <li>
                {{ title }}
                <button v-on:click="$emit('remove')">x</button>
            </li>
        `,
        props: ['title']
    })
    
    new Vue({
        el: '#todo',
        data: {
            newTodoText: '',
            todos: [
                'Do the dishes',
                'Take out the trash',
                'Mow the lawn'
            ]
        },
        methods: {
            addNewTodo: function() {
                this.todos.push(this.newTodoText)
                this.newTodoText = ''
            }
        }
    })

    1.gif

    总结


    这篇文章主要总结了Vue的v-for指令。通过这个指令,配合数据源中的数组或者对象,我们可以很方便的生成列表。这也常常称为列表渲染。当然配合一些模板,我们可以做出一些特有的功能和效果。比如文章中最后一个Todo 列表,使用v-for很易实现。

    (学习视频分享:web前端开发编程基础视频

    以上就是详解Vue渲染列表指令:v-for的详细内容,更多请关注php中文网其它相关文章!

    声明:本文转载于:博客园,如有侵犯,请联系admin@php.cn删除

    前端(VUE)零基础到就业课程:点击学习

    清晰的学习路线+老师随时辅导答疑

    快捷开发Web应用及小程序:点击使用

    支持亿级表,高并发,自动生成可视化后台。

    上一篇:vue引入Element-plus的全局引入与局部引入(附代码) 下一篇:自己动手写 PHP MVC 框架(40节精讲/巨细/新人进阶必看)

    相关文章推荐

    • ❤️‍🔥共22门课程,总价3725元,会员免费学• ❤️‍🔥接口自动化测试不想写代码?• Vue实例的生命周期详解之从创建到销毁全过程• 实例详解Vue中的事件修饰符• vue组件各个生命周期的职责一览!• 详解Vue条件渲染指令:v-if 和 v-show• 一文详解vue路由跳转-参数传递与接收• 超详细!总结vue实现路由跳转的3种方式!
    1/1

    PHP中文网