16列表渲染

列表渲染

一、v-for + 三种运用情况

    v-for指令:
        1.用于展示列表数据
        2.语法:v-for=" (item,index) in xxx" : key="yyy"
        3.可遍历:数组、对象、字符串(用的很少)、指定次数(用的很少)

实例

<body>
    <div id="root">
        <h2>人员列表</h2>
        <!-- v-for(遍历列表) -->
        <div>
            <ul>
                <li v-for="(item,index) in persons" :key="index">
                    {{item.name}}-{{item.age}}
                </li>
            </ul>
        </div>
        <!-- v-for(遍历对象) -->
        <div>
            <ul>
                <li v-for="(val,key) in car" :key="key">
                    {{val}}-{{key}}
                </li>
            </ul>
        </div>
        <!-- v-for(遍历字符串) (少)-->
        <div>
            <ul>
                <li v-for="(val,index) in str" :key="index">
                    {{val}}-{{index}}
                </li>
            </ul>
        </div>
        <!-- v-for(遍历次数) (少)-->
        <div>
            <ul>
                <li v-for="(number,index) in 5" :key="index">
                    {{number}}-{{index}}
                </li>
            </ul>
        </div>
    </div>
    <script>
        Vue.config.productionTip = false;
        new Vue({
            el:'#root',
            data:{
                persons:[
                    {id:'001',name:'John',age:'20'},
                    {id:'002',name:'alex',age:'19'},
                    {id:'003',name:'zrie',age:'18'},
                ],
                car:{
                    name:'奥迪AE86',
                    color:'black',
                    price:'120w'
                },
                str:'hello',
            }
        });
    </script>
</body>

二、key的作用及原理

1.写key的原理与不写可以的原理

  • 写key使用key值做diff算法比较
  • 不写key,默认使用index值做diff算法比较

2.写key这key用什么值比较好

  • 遍历的索引值
    • 使用场景:不会对原始的数据产生顺序破坏时。(例:只是用于做展示)
    • :key="index"
  • 传递的唯一标识
    • 使用场景:操作原始数据,可能会产生顺序上的变化时。(例:逆序添加,逆序删除等)
    • :key="item.id"
面试题:react、vue中的key有什么作用? (key的内部原理)
    1。虚拟DOM中key的作用:
        key是虚拟DOM对象的标识,当数据发生变化时,Vue会根据【新数据】生成【新的虚拟DOM】,
        随后Vue进行【新虚拟DOM】与【旧虚拟DOM】的差异比较,比较规则如下:
        
    2.对比规则:
        (1).旧虚拟DOM中找到了与新虚拟DOM相同的key:
            1.若虚拟DOM中内容没变,直接使用之前的真实DOM !
            2.若虚拟DOM中内容变了,则生成新的真实DOM,随后替换掉页面中之前的真实DOM。
        (2).旧虚拟DOM中未找到与新虚拟DOM相同的key
            创建新的真实DOM,随后渲染到到页面。

	3.用index作为key可能会引发的问题:
        1。若对数据进行:逆序添加、逆序删除等破坏顺序操作:
        	会产生没有必要的真实DOM更新==>界面效果没问题,但效率低。
        2.如果结构中还包含输入类的DOM:
            会产生错误DOM更新==>界面有问题。
        4.开发中如何选择key?:
    		1.最好使用每条数据的唯一标识作为key,比如id、手机号、身份证号、学号等唯一值,
    		2.如果不存在对数据的逆序添加、逆序删除等破坏顺序操作,仅用于渲染列表用于展示,
    			使用index作为key是没有问题的。

实例

<div id="root">
    <button @click.once="add">点我添加老李</button>
    <ul v-for="(p,index) in persons" :key="index">
        <li>{{p.name}}-{{p.age}}<input type="text"></li>
    </ul>
    <ul v-for="(p,index) in persons" :key="p.id">
        <li>{{p.name}}-{{p.age}}<input type="text"></li>
    </ul>
</div>
<script>
    Vue.config.productionTip = false;
    const vm = new Vue({
        el:'#root',
        data:{
            persons:[
                {id:'001',name:'张三',age:'18'},
                {id:'002',name:'李四',age:'19'},
                {id:'003',name:'王五',age:'20'},
            ],
        },
        methods: {
            add(){
                let p = {id:'004',name:'',age:'30'}
                this.persons.unshift(p);
            }
        },
    })
</script>

遍历列表时key的作用(index是key)

image-20220828124544934

遍历列表时key的作用(唯一标识是key)

image-20220828124814004

三、列表过滤

列表过滤一般标准选择的数计算属性,当然有的人可能会想到监听属性,也是可以的。

监听属性实现

watch

<div id="root">
    <h2>人员列表</h2>
    <div>
        <input type="text" placeholder="请输入姓名..." v-model="keyworld">
        <ul>
            <li v-for="(item,index) in filPersons" :key="item.id">
                {{item.name}}-{{item.age}}-{{item.sex}}
            </li>
        </ul>
    </div>
</div>
<script>
    Vue.config.productionTip=false;
    //#region 
    //#endregion
    new Vue({
        el:'#root',
        data:{
            keyworld:'',
            persons:[
                {id:'001',name:'马冬梅',age:'20',sex:'女'},
                {id:'002',name:'周冬雨',age:'19',sex:'女'},
                {id:'003',name:'周杰伦',age:'18',sex:'男'},
                {id:'004',name:'温盖伦',age:'18',sex:'男'},
            ],
            filPersons:[],
        },
        watch:{
            keyworld:{
                immediate:true,  // 解决刚开始读取数据
                handler(val){
                    this.filPersons = this.persons.filter((p)=>{
                        return p.name.indexOf(val) !== -1
                    })
                }
            }
        }
    });
</script>   

计算属性实现

computed

<div id="root">
    <h2>人员列表</h2>
    <div>
        <input type="text" placeholder="请输入姓名..." v-model="keyworld">
        <ul>
            <li v-for="(item,index) in filPersons" :key="item.id">
                {{item.name}}-{{item.age}}-{{item.sex}}
            </li>
        </ul>
    </div>
</div>
<script>
    new Vue({
        el:'#root',
        data:{
            keyworld:'',
            persons:[
                {id:'001',name:'马冬梅',age:'20',sex:'女'},
                {id:'002',name:'周冬雨',age:'19',sex:'女'},
                {id:'003',name:'周杰伦',age:'18',sex:'男'},
                {id:'004',name:'温盖伦',age:'18',sex:'男'},
            ],
        },
        computed:{
            filPersons(){
                return this.persons.filter((p)=>{
                    return p.name.indexOf(this.keyworld) !== -1
                })
            }
        }
    });
</script>

推荐使用的是计算属性。先从简单的入手。

四、列表排序

列表排序,一般最好通过computed属性实现。

列表排序

function(){
    let arr = [1,3,2,4,6,5]
    arr.sort((after, before)=>{
        return after - before    // 升序;  > 0
    })
    return arr
}

实现

<div id="root">
    <h2>人员列表</h2>
    <div>
        <input type="text" placeholder="请输入姓名..." v-model="keyworld">
        <button @click="sortType = 2">升序</button>
        <button @click="sortType = 1">降序</button>
        <button @click="sortType = 0">原序</button>
        <ul>
            <li v-for="(item,index) in filPersons" :key="item.id">
                {{item.name}}-{{item.age}}-{{item.sex}}
            </li>
        </ul>
    </div>
</div>
<script>
    new Vue({
        el:'#root',
        data:{
            keyworld:'',
            sortType:0,
            persons:[
                {id:'001',name:'马冬梅',age:'20',sex:'女'},
                {id:'002',name:'周冬雨',age:'19',sex:'女'},
                {id:'003',name:'周杰伦',age:'18',sex:'男'},
                {id:'004',name:'温盖伦',age:'30',sex:'男'},
            ],
        },
        computed:{
            filPersons(){
                let arr = this.persons.filter((p)=>{
                    return p.name.indexOf(this.keyworld) !== -1
                })
                // 判断是否排序
                if(this.sortType){
                    arr.sort((p1,p2)=>{
                        return this.sortType === 1 ? p2.age - p1.age : p1.age - p2.age
                    })
                }
                return arr
            }
        }
    });
</script>
posted @ 2022-09-06 16:17  Redskaber  阅读(33)  评论(0)    收藏  举报