文档章节

Vue.js-列表渲染

tianyawhl
 tianyawhl
发布于 2017/08/25 09:54
字数 1606
阅读 27
收藏 0

我们用v-for指令根据一组数组的选项列表进行渲染,v-for指令需要以item in items形式的特殊语法,items是源数据数组并且item是数组元素迭代的别名
基本用法

<body class="">
    <div id="app-7">
        <ul>
            <li v-for="item in items">{{item.message}}</li>
        </ul>
    </div>
    <script src="js/vue.js"></script>
    <script>
    var app = new Vue({
        el: "#app-7",
        data: {
            items: [
                { message: "foo" },
                { message: "bar" }
            ]
        }
    })
    </script>
</body>

 

在v-for块中,我们拥有对父作用域属性的完全访问权限,v-for还支持一个可选的第二个参数作为当前项的索引

<body class="">
    <div id="app-7">
        <ul>
            <li v-for="(item,index) in items">{{parentMessage}}-{{index}}-{{item.message}}</li>
        </ul>
    </div>
    <script src="js/vue.js"></script>
    <script>
    var app = new Vue({
        el: "#app-7",
        data: {
        	parentMessage:"parent",
            items: [
                { message: "foo" },
                { message: "bar" }
            ]
        }
    })
    </script>
</body>

你也可以用of代替in作为分隔符     <div v-for="item of items"></div>

 

如同v-if模板,你也可以用带有v-for的<template>标签来渲染多个元素块,最后渲染的不含template元素

<body class="">
    <div id="app-7">
       <ul>
       	<template v-for="item in items">
       		<li>firstline</li>
       		<li>line</li>
       	</template>
       </ul>
    </div>
    <script src="js/vue.js"></script>
    <script>
    var app = new Vue({
        el: "#app-7",
        data: {
            items: [
                { message: "foo" },
                { message: "bar" }
            ]
        }
    })
    </script>
</body>

 

对象迭代v-for
你也可以用v-for通过一个对象的属性来迭代,value为foo 与 bar

<body class="">
    <div id="app-7">
        <ul>
            <li v-for="value in object">{{value}}</li>
        </ul>
    </div>
    <script src="js/vue.js"></script>
    <script>
    var app = new Vue({
        el: "#app-7",
        data: {
            object: { firstname: "foo", lastname: "bar" },
        }
    })
    </script>
</body>

你也可以提供第二个参数为键名,第三个参数为索引

<body class="">
    <div id="app-7">
        <ul>
            <li v-for="(value,key,index) in object">{{key}}:{{value}}-{{index}}</li>
        </ul>
    </div>
    <script src="js/vue.js"></script>
    <script>
    var app = new Vue({
        el: "#app-7",
        data: {
            object: { firstname: "foo", lastname: "bar" },
        }
    })
    </script>
</body>

 

整数迭代v-for  结果显示12345678910

<body class="">
    <div id="app-7">
       <span v-for="n in 10">{{n}}</span>
    </div>
    <script src="js/vue.js"></script>
    <script>
    var app = new Vue({
        el: "#app-7",
    })
    </script>
</body>

 

官网例子todo改成不用组件的写法

<body class="">
    <div id="app-7">
        <input type="text" placeholder="please enter new text" v-model="newtext" v-on:keyup.enter="addlist">
        <ul>
            <template v-for="(todo,index) in todos">
                <li style="margin-bottom:20px;">{{todo.title}}
                    <button v-on:click="remove(index)">删除</button>
                </li>
            </template>
        </ul>
    </div>
    <script src="js/vue.js"></script>
    <script>
    var app = new Vue({
        el: "#app-7",
        data: {
            newtext: "",
            todos: [
                { id: 1, title: "firsttile" },
                { id: 2, title: "secondtile" },
                { id: 3, title: "thirdtitle" }
            ],
            nexttodoid: 4
        },
        methods: {
            addlist: function() {
                this.todos.push({ id: this.nexttodoid++, title: this.newtext })
                this.newtext = ""
            },
            remove:function(index){
            	this.todos.splice(index,1)
            }

        }
    })
    //this.todos.push({ id: this.nexttodoid++, }) 不能改成id: ++this.nexttodoid,++在前面是
    //先自加再赋值,
    </script>
</body>

官网例子todo用组件的写法

<body class="">
    <div id="todo-list-example">
        <input placeholder="please endter the new text" 
           v-model="newTodoText" v-on:keyup.enter="addNewTodo">
       <ul>
         <item-compoent v-for="(todo,index) in todos" v-bind:title="todo.title" 
           v-on:remove="todos.splice(index,1)">

         </item-compoent>
       </ul> 
    </div>
    <script src="js/vue.js"></script>
    <script>
   Vue.component("item-compoent",{
    props:["title"],
    template:`
    <li>{{title}}<button v-on:click="$emit('remove')">删除</button></li>
    `
   })
    var app7 = new Vue({
        el: '#todo-list-example',
        data: {
            newTodoText:'',
            todos: [
             {id:1,title:"do the dishes"} ,
             {id:2,title:"take out the trash"} ,
             {id:3,title:"mow the lawn"},
            ],
            nextid:4
        },
        methods:{
            addNewTodo:function(){
                this.todos.push({id:this.nextid++,title:this.newTodoText});
                this.newTodoText =""
            }
        }
    })
   
    </script>
</body>

 //1、当在input中输入数据后,按回车下面的列表增加一项,原理是在input中写上v-model的属性,用于与data里面的newTodoText双向绑定,同时v-on:keyup.enter 是按enter键后执行addNewTodo方法,实例的方法是在todos新增一项,并且把input清空
    //2、父模板数据不能直接传递到子组件模板,需要在子组件中定义props属性像props:["title"],父模板绑定title并赋值,因为例子中的li含有按钮,点击按钮抛出子组件remove,父组件接收remove并执行todos.splice(index,1)意思是从下标index开始删除1项

 

v-for与v-if
v-for的优先级比v-if高,意味着v-if将分别重复运行于每个v-for循环中
<li v-for="todo in todos" v-if="todo.isComplete">{{ todo }}</li>
上面的代码只传递了未complete的todos
而如果你的目的是有条件的跳过循环的执行,那么将v-if置于包装元素(或<template>上)

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

 

key
为了给vue一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供唯一的key属性
<div v-for="item in items" v-bind:key="item.id"> </div>
建议尽量使用v-for来提供key

 

数组更新检测
变异方法
Vue包含一组观察数组的变异方法,所以它们也将会触发视图更新,这些方法如下:
push()
pop()
shift()
unshift()
splice()
sort()
reverse()

push的用法例子

<body class="">
    <div id="todo-list-example">
        <ul>
            <li v-for="item in items">
                {{ item.message }}
            </li>
        </ul>
        <input v-model="newtext">
        <button v-on:click="addlist">追加</button>
    </div>
    <script src="js/vue.js"></script>
    <script>
    var example1 = new Vue({
        el: '#todo-list-example',
        data: {
            newtext:"",
            items: [
                { message: 'Foo' },
                { message: 'Bar' }
            ]
        },
      methods:{
        addlist:function(){
          this.items.push({message:this.newtext});
          this.newtext=""
        }
      }
    })
    </script>
</body>

重塑数组
变异方法顾名思义,会改变被这些方法调用的原始数组,相比之下也有非变异方法
filter(),concat()和slice(),这3个不会改变原始数组,总是返回一个新数组,当使用非变异方法时,可以用新的数组代替旧数组,性能依然很高效
example1.items = example1.items.filter(function (item) {
  return item.message.match(/Foo/)
})
filter用法

<body class="">
    <div id="todo-list-example">
        <ul>
            <li v-for="item in items">
                {{ item.message }}
            </li>
        </ul>
        <button v-on:click="addlist">过滤</button>
    </div>
    <script src="js/vue.js"></script>
    <script>
    var example1 = new Vue({
        el: '#todo-list-example',
        data: {
            newtext: "",
            items: [
                { message: 'Foo' },
                { message: 'Bar' }
            ]
        },
        methods: {
            addlist: function() {
                this.items = this.items.filter(function(item) {
                    return item.message.match(/Foo/);
                })
            }
        }
    })
    </script>
</body>

注意事项
由于JavaScript的限制,Vue不能检测以下变动的数组
1、当你利用索引值直接设置一个项时例如vm.items[indexOfItem]=newValue
2、当你修改数组的长度时例如:vm.items.length = newLength
为了解决第一类问题,以下2种方法都可以实现
Vue.set(example.items,indexOfItem,newValue)
example.items.splice(indexOfItem,1,newValue)

解决第二个问题可以用splice
example1.items.splice(newLength)
 

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

<body class="">
<div id="example-1">
    <span v-for="n in evennumber" >{{n}}</span>
</div>
    <script src="js/vue.js"></script>
    <script>
    
    var app7 = new Vue({
        el: '#example-1',
        data: {
            numbers:[1,2,3,4,5,6,7,8]
        },
        computed:{
            evennumber:function(){
                return this.numbers.filter(function(number){
                    return number%2===0
                })
            }
        }
    })
    </script>
</body>

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

<body class="">
<div id="example-1">
    <span v-for="n in evennumber(numbers)" >{{n}}</span>
</div>
    <script src="js/vue.js"></script>
    <script>
    
    var app7 = new Vue({
        el: '#example-1',
        data: {
            numbers:[1,2,3,4,5,6,7,8]
        },
        methods:{
            evennumber:function(numbers){
                return numbers.filter(function(number){
                    return number%3===0
                })
            }
        }
    })
    </script>
</body>
或者
<body class="">
<div id="example-1">
    <span v-for="n in evennumber()" >{{n}}</span>
</div>
    <script src="js/vue.js"></script>
    <script>
    
    var app7 = new Vue({
        el: '#example-1',
        data: {
            numbers:[1,2,3,4,5,6,7,8]
        },
        methods:{
            evennumber:function(){
                return this.numbers.filter(function(number){
                    return number%2===0
                })
            }
        }
    })
    </script>
</body>

 

© 著作权归作者所有

上一篇: Vue.js-事件处理器
下一篇: Vue.js-条件渲染
tianyawhl
粉丝 7
博文 247
码字总数 129966
作品 0
常州
前端工程师
私信 提问
mpvue: vuejs和小程序碰撞出来的火花

微信自推出小程序以来,热度一直居高不下,各大公司开始专门开发小程序,但是小程序自定义的wxml和wxss和自己定义的语法,让被三大框架统治的前端江湖头疼不易,因为需要专门为小程序开发一...

蜗牛老湿
2018/05/18
0
0
React与Vue模板使用比较(一、vue模板与React JSX比较)

前言 本人原为React开发者,现在转战Vue。在这些天接触Vue的日子里,说说自己的感觉:同样的登山活动,React就像父亲,给你必要的登山工具就让你出发了;Vue就像母亲,在你登山之前为你准备好...

barretem
03/05
0
0
设计模式在vue中的应用(四)

前言 目录整理: 设计模式在vue中的应用(一) 设计模式在vue中的应用(二) 设计模式在vue中的应用(三) 设计模式在vue中的应用(四) 为什么要写这些文章呢。正如设计模式(Design Patter...

hailx
02/13
0
0
Vue2.5 零基础开发去哪儿网实战(三) - Vue 基础精讲

0 联系我 1. Java开发技术交流Q群 2.完整博客链接 3.个人知乎 4.gayhub 1 Vue实例 基本规范编写 绑定事件 这里的 v-on 其实等价于下面的简易写法 没错,直接@即可! 3-2 Vue实例生命周期 3-3 ...

JavaEdge
02/15
0
0
为什么v-for循环时要写上key

当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用“就地复用”策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序, 而是简单复用此处每个元素,并且确保...

南蓝NL
03/20
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Android双向绑定原理简述

Android双向绑定原理简述 双向绑定涉及两个部分,即将业务状态的变化传递给UI,以及将用户输入信息传递给业务模型。 首先我们来看业务状态是如何传递给UI的。开启dataBinding后,编译器为布局...

tommwq
今天
3
0
Spring系列教程八: Spring实现事务的两种方式

一、 Spring事务概念: 事务是一系列的动作,它们综合在一起才是一个完整的工作单元,这些动作必须全部完成,如果有一个失败的话,那么事务就会回滚到最开始的状态,仿佛什么都没发生过一样。...

我叫小糖主
今天
7
0
CentOS 的基本使用

1. 使用 sudo 命令, 可以以 root 身份执行命令, 必须要在 /etc/sudoers 中定义普通用户 2. 设置 阿里云 yum 镜像, 参考 https://opsx.alibaba.com/mirror # 备份mv /etc/yum.repos.d/CentO...

北漂的我
昨天
3
0
Proxmox VE技巧 移除PVE “没有有效订阅” 的弹窗提示

登陆的时候提示没有有效的订阅You do not have a valid subscription for this server. Please visit www.proxmox.com to get a list of available options. 用的是免费版的,所以每次都提示......

以谁为师
昨天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部