专栏首页前端之攻略Vue.js-列表渲染 原

Vue.js-列表渲染 原

我们用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>

(adsbygoogle = window.adsbygoogle || []).push({});

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Vue案例引发的「嵌套组件」通信的简单方式

    我们都知道 Vue 是采用组件化开发的模式,组件化的优势在于相对独立,易于维护,可复用。你可以把项目看成许多组件的组合而成。

    六小登登
  • 基于CMS的组件复用实践

    目前前端项目大多基于Vue、React、Angular等框架来实现,这一类框架都有一个明显的特点:基于模块化以及组件化思维。所以,开发者在使用上述框架时,实际上...

    个推君
  • navigateTo:fail page "pages/goodsDetails/javascript:void(0);" is not found

    在vue.js项目转化到mpvue的小程序项目的过程中,执行事件时,报了如下图所示的错误:

    honey缘木鱼
  • 个推前端微服务化:突破传统SPA瓶颈

    目前的前端领域,单页面应用(SPA)大行其道。而随着时间的推移以及应用功能的丰富,这些应用变得越来越庞大也越来越难以维护。于是“微前端”这一概念应运而生。

    个推君
  • 解读mpvue官方文档的Class 与 Style 绑定及不支持语法

    在vue.js项目转化为小程序时,把原来页面的代码直接拷贝过去,发现布局改变很多,很多已经设置的标签的css样式并没有显示出来,查看官方文档,得知原来vue.j...

    honey缘木鱼
  • 在WordPress中添加简书风格的连载目录和文章导航

    自从机缘巧合的开始翻译Gensis的系列教程,越来越沉迷于研究这款WordPress主题框架了,一边翻译一边学习一边也在自己的丘壑博客上实验。

    丘壑
  • 记一次vue长列表的内存性能分析和优化

    这个长列表页面,其实是一个实时日志上报的页面,随着页面打开时间的增加,日志数量也会增多,常规的页面布局和渲染免不了会遇到性能问题。

    书童小二
  • mpvue页面跳转及传值

    vue中 使用 vue-router 来进行路由跳转的。mpvue中只能通过以下几种方式跳转: (1).a 标签

    honey缘木鱼
  • vue与react哪种好?

    vue与react,到目前为止两个我都用来写了好多项目,vue用的脚手架是vue-cli,react用的是dva,两者都对其进行了很好的封装,只需要简单的几步就...

    杭州前端工程师
  • webpack带来的安全风险

    最近在资产收集过程中,发现越来越多的vue应用,大部分会使用webpack进行打包,如果没有正确配置,就会导致vue源码泄露。

    ChaMd5安全团队

扫码关注云+社区

领取腾讯云代金券