• 12_列表渲染


    1.基本列表

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8" />
            <title>基本列表</title>
            <script type="text/javascript" src="../js/vue.js"></script>
        </head>
        <body>
            <!-- 
                    v-for指令:
                            1.用于展示列表数据
                            2.语法:v-for="(item, index) in xxx" :key="yyy"
                            3.可遍历:数组、对象、字符串(用的很少)、指定次数(用的很少)
            -->
            <!-- 准备好一个容器-->
            <div id="root">
                <!-- 遍历数组 -->
                <h2>人员列表(遍历数组)</h2>
                <ul>
                    <li v-for="(p,index) of persons" :key="index">
                        {{p.name}}-{{p.age}}
                    </li>
                </ul>
    
                <!-- 遍历对象 -->
                <h2>汽车信息(遍历对象)</h2>
                <ul>
                    <li v-for="(value,k) of car" :key="k">
                        {{k}}-{{value}}
                    </li>
                </ul>
    
                <!-- 遍历字符串 -->
                <h2>测试遍历字符串(用得少)</h2>
                <ul>
                    <li v-for="(char,index) of str" :key="index">
                        {{char}}-{{index}}
                    </li>
                </ul>
                
                <!-- 遍历指定次数 -->
                <h2>测试遍历指定次数(用得少)</h2>
                <ul>
                    <li v-for="(number,index) of 5" :key="index">
                        {{index}}-{{number}}
                    </li>
                </ul>
            </div>
    
            <script type="text/javascript">
                Vue.config.productionTip = false
                
                new Vue({
                    el:'#root',
                    data:{
                        persons:[
                            {id:'001',name:'张三',age:18},
                            {id:'002',name:'李四',age:19},
                            {id:'003',name:'王五',age:20}
                        ],
                        car:{
                            name:'奥迪A8',
                            price:'70万',
                            color:'黑色'
                        },
                        str:'hello'
                    }
                })
            </script>
    </html>

    2.key的原理

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8" />
            <title>key的原理</title>
            <script type="text/javascript" src="../js/vue.js"></script>
        </head>
        <body>
            <!-- 
                    面试题:react、vue中的key有什么作用?(key的内部原理)
                            
                            1. 虚拟DOM中key的作用:
                                            key是虚拟DOM对象的标识,当数据发生变化时,Vue会根据【新数据】生成【新的虚拟DOM】, 
                                            随后Vue进行【新虚拟DOM】与【旧虚拟DOM】的差异比较,比较规则如下:
                                            
                            2.对比规则:
                                        (1).旧虚拟DOM中找到了与新虚拟DOM相同的key:
                                                    ①.若虚拟DOM中内容没变, 直接使用之前的真实DOM!
                                                    ②.若虚拟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">
                <!-- 遍历数组 -->
                <h2>人员列表(遍历数组)</h2>
                <button @click.once="add">添加一个老刘</button>
                <ul>
                    <li v-for="(p,index) of persons" :key="index">
                        {{p.name}}-{{p.age}}
                        <input type="text">
                    </li>
                </ul>
            </div>
    
            <script type="text/javascript">
                Vue.config.productionTip = false
                
                new Vue({
                    el:'#root',
                    data:{
                        persons:[
                            {id:'001',name:'张三',age:18},
                            {id:'002',name:'李四',age:19},
                            {id:'003',name:'王五',age:20}
                        ]
                    },
                    methods: {
                        add(){
                            const p = {id:'004',name:'老刘',age:40}
                            this.persons.unshift(p)
                        }
                    },
                })
            </script>
    </html>

    3.列表过滤

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8" />
            <title>列表过滤</title>
            <script type="text/javascript" src="../js/vue.js"></script>
        </head>
        <body>
            <!-- 准备好一个容器-->
            <div id="root">
                <h2>人员列表</h2>
                <input type="text" placeholder="请输入名字" v-model="keyWord">
                <ul>
                    <li v-for="(p,index) of filPerons" :key="index">
                        {{p.name}}-{{p.age}}-{{p.sex}}
                    </li>
                </ul>
            </div>
    
            <script type="text/javascript">
                Vue.config.productionTip = false
                
                //用watch实现
                //#region 
                /* new Vue({
                    el:'#root',
                    data:{
                        keyWord:'',
                        persons:[
                            {id:'001',name:'马冬梅',age:19,sex:'女'},
                            {id:'002',name:'周冬雨',age:20,sex:'女'},
                            {id:'003',name:'周杰伦',age:21,sex:'男'},
                            {id:'004',name:'温兆伦',age:22,sex:'男'}
                        ],
                        filPerons:[]
                    },
                    watch:{
                        keyWord:{
                            immediate:true,
                            handler(val){
                                this.filPerons = this.persons.filter((p)=>{
                                    return p.name.indexOf(val) !== -1
                                })
                            }
                        }
                    }
                }) */
                //#endregion
                
                //用computed实现
                new Vue({
                    el:'#root',
                    data:{
                        keyWord:'',
                        persons:[
                            {id:'001',name:'马冬梅',age:19,sex:''},
                            {id:'002',name:'周冬雨',age:20,sex:''},
                            {id:'003',name:'周杰伦',age:21,sex:''},
                            {id:'004',name:'温兆伦',age:22,sex:''}
                        ]
                    },
                    computed:{
                        filPerons(){
                            return this.persons.filter((p)=>{
                                return p.name.indexOf(this.keyWord) !== -1
                            })
                        }
                    }
                }) 
            </script>
    </html>

    4.列表排序

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8" />
            <title>列表排序</title>
            <script type="text/javascript" src="../js/vue.js"></script>
        </head>
        <body>
            <!-- 准备好一个容器-->
            <div id="root">
                <h2>人员列表</h2>
                <input type="text" placeholder="请输入名字" v-model="keyWord">
                <button @click="sortType = 2">年龄升序</button>
                <button @click="sortType = 1">年龄降序</button>
                <button @click="sortType = 0">原顺序</button>
                <ul>
                    <li v-for="(p,index) of filPerons" :key="p.id">
                        {{p.name}}-{{p.age}}-{{p.sex}}
                        <input type="text">
                    </li>
                </ul>
            </div>
    
            <script type="text/javascript">
                Vue.config.productionTip = false
                
                new Vue({
                    el:'#root',
                    data:{
                        keyWord:'',
                        sortType:0, //0原顺序 1降序 2升序
                        persons:[
                            {id:'001',name:'马冬梅',age:30,sex:''},
                            {id:'002',name:'周冬雨',age:31,sex:''},
                            {id:'003',name:'周杰伦',age:18,sex:''},
                            {id:'004',name:'温兆伦',age:19,sex:''}
                        ]
                    },
                    computed:{
                        filPerons(){
                            const arr = this.persons.filter((p)=>{
                                return p.name.indexOf(this.keyWord) !== -1
                            })
                            //判断一下是否需要排序
                            if(this.sortType){
                                arr.sort((p1,p2)=>{
                                    return this.sortType === 1 ? p2.age-p1.age : p1.age-p2.age
                                })
                            }
                            return arr
                        }
                    }
                }) 
    
            </script>
    </html>

    5.更新时的一个问题

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8" />
            <title>更新时的一个问题</title>
            <script type="text/javascript" src="../js/vue.js"></script>
        </head>
        <body>
            <!-- 准备好一个容器-->
            <div id="root">
                <h2>人员列表</h2>
                <button @click="updateMei">更新马冬梅的信息</button>
                <ul>
                    <li v-for="(p,index) of persons" :key="p.id">
                        {{p.name}}-{{p.age}}-{{p.sex}}
                    </li>
                </ul>
            </div>
    
            <script type="text/javascript">
                Vue.config.productionTip = false
                
                const vm = new Vue({
                    el:'#root',
                    data:{
                        persons:[
                            {id:'001',name:'马冬梅',age:30,sex:''},
                            {id:'002',name:'周冬雨',age:31,sex:''},
                            {id:'003',name:'周杰伦',age:18,sex:''},
                            {id:'004',name:'温兆伦',age:19,sex:''}
                        ]
                    },
                    methods: {
                        updateMei(){
                            // this.persons[0].name = '马老师' //奏效
                            // this.persons[0].age = 50 //奏效
                            // this.persons[0].sex = '男' //奏效
                            // this.persons[0] = {id:'001',name:'马老师',age:50,sex:'男'} //不奏效
                            this.persons.splice(0,1,{id:'001',name:'马老师',age:50,sex:''})
                        }
                    }
                }) 
    
            </script>
    </html>

    6.Vue监测数据改变的原理_对象

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8" />
            <title>Vue监测数据改变的原理</title>
            <!-- 引入Vue -->
            <script type="text/javascript" src="../js/vue.js"></script>
        </head>
        <body>
            <!-- 准备好一个容器-->
            <div id="root">
                <h2>学校名称:{{name}}</h2>
                <h2>学校地址:{{address}}</h2>
            </div>
        </body>
    
        <script type="text/javascript">
            Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
    
            const vm = new Vue({
                el:'#root',
                data:{
                    name:'尚硅谷',
                    address:'北京',
                    student:{
                        name:'tom',
                        age:{
                            rAge:40,
                            sAge:29,
                        },
                        friends:[
                            {name:'jerry',age:35}
                        ]
                    }
                }
            })
        </script>
    </html>

    7.模拟一个数据监测

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8" />
            <title>Document</title>
        </head>
        <body>
            <script type="text/javascript" >
    
                let data = {
                    name:'尚硅谷',
                    address:'北京',
                }
    
                //创建一个监视的实例对象,用于监视data中属性的变化
                const obs = new Observer(data)        
                console.log(obs)    
    
                //准备一个vm实例对象
                let vm = {}
                vm._data = data = obs
    
                function Observer(obj){
                    //汇总对象中所有的属性形成一个数组
                    const keys = Object.keys(obj)
                    //遍历
                    keys.forEach((k)=>{
                        Object.defineProperty(this,k,{
                            get(){
                                return obj[k]
                            },
                            set(val){
                                console.log(`${k}被改了,我要去解析模板,生成虚拟DOM.....我要开始忙了`)
                                obj[k] = val
                            }
                        })
                    })
                }
                
                
    
    
            </script>
        </body>
    </html>

    8.Vue.set的使用

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8" />
            <title>Vue监测数据改变的原理</title>
            <!-- 引入Vue -->
            <script type="text/javascript" src="../js/vue.js"></script>
        </head>
        <body>
            <!-- 准备好一个容器-->
            <div id="root">
                <h1>学校信息</h1>
                <h2>学校名称:{{school.name}}</h2>
                <h2>学校地址:{{school.address}}</h2>
                <h2>校长是:{{school.leader}}</h2>
                <hr/>
                <h1>学生信息</h1>
                <button @click="addSex">添加一个性别属性,默认值是男</button>
                <h2>姓名:{{student.name}}</h2>
                <h2 v-if="student.sex">性别:{{student.sex}}</h2>
                <h2>年龄:真实{{student.age.rAge}},对外{{student.age.sAge}}</h2>
                <h2>朋友们</h2>
                <ul>
                    <li v-for="(f,index) in student.friends" :key="index">
                        {{f.name}}--{{f.age}}
                    </li>
                </ul>
            </div>
        </body>
    
        <script type="text/javascript">
            Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
    
            const vm = new Vue({
                el:'#root',
                data:{
                    school:{
                        name:'尚硅谷',
                        address:'北京',
                    },
                    student:{
                        name:'tom',
                        age:{
                            rAge:40,
                            sAge:29,
                        },
                        friends:[
                            {name:'jerry',age:35},
                            {name:'tony',age:36}
                        ]
                    }
                },
                methods: {
                    addSex(){
                        // Vue.set(this.student,'sex','男')
                        this.$set(this.student,'sex','')
                    }
                }
            })
        </script>
    </html>

    9.Vue监测数据改变的原理_数组

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8" />
            <title>Vue监测数据改变的原理_数组</title>
            <!-- 引入Vue -->
            <script type="text/javascript" src="../js/vue.js"></script>
        </head>
        <body>
            <!-- 准备好一个容器-->
            <div id="root">
                <h1>学校信息</h1>
                <h2>学校名称:{{school.name}}</h2>
                <h2>学校地址:{{school.address}}</h2>
                <h2>校长是:{{school.leader}}</h2>
                <hr/>
                <h1>学生信息</h1>
                <button @click="addSex">添加一个性别属性,默认值是男</button>
                <h2>姓名:{{student.name}}</h2>
                <h2 v-if="student.sex">性别:{{student.sex}}</h2>
                <h2>年龄:真实{{student.age.rAge}},对外{{student.age.sAge}}</h2>
                <h2>爱好</h2>
                <ul>
                    <li v-for="(h,index) in student.hobby" :key="index">
                        {{h}}
                    </li>
                </ul>
                <h2>朋友们</h2>
                <ul>
                    <li v-for="(f,index) in student.friends" :key="index">
                        {{f.name}}--{{f.age}}
                    </li>
                </ul>
            </div>
        </body>
    
        <script type="text/javascript">
            Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
    
            const vm = new Vue({
                el:'#root',
                data:{
                    school:{
                        name:'尚硅谷',
                        address:'北京',
                    },
                    student:{
                        name:'tom',
                        age:{
                            rAge:40,
                            sAge:29,
                        },
                        hobby:['抽烟','喝酒','烫头'],
                        friends:[
                            {name:'jerry',age:35},
                            {name:'tony',age:36}
                        ]
                    }
                },
                methods: {
                    addSex(){
                        // Vue.set(this.student,'sex','男')
                        this.$set(this.student,'sex','')
                    }
                }
            })
        </script>
    </html>

    10.总结Vue数据监测

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8" />
            <title>总结数据监视</title>
            <style>
                button{
                    margin-top: 10px;
                }
            </style>
            <!-- 引入Vue -->
            <script type="text/javascript" src="../js/vue.js"></script>
        </head>
        <body>
            <!--
                Vue监视数据的原理:
                    1. vue会监视data中所有层次的数据。
    
                    2. 如何监测对象中的数据?
                                    通过setter实现监视,且要在new Vue时就传入要监测的数据。
                                        (1).对象中后追加的属性,Vue默认不做响应式处理
                                        (2).如需给后添加的属性做响应式,请使用如下API:
                                                        Vue.set(target,propertyName/index,value) 或 
                                                        vm.$set(target,propertyName/index,value)
    
                    3. 如何监测数组中的数据?
                                        通过包裹数组更新元素的方法实现,本质就是做了两件事:
                                            (1).调用原生对应的方法对数组进行更新。
                                            (2).重新解析模板,进而更新页面。
    
                    4.在Vue修改数组中的某个元素一定要用如下方法:
                                1.使用这些API:push()、pop()、shift()、unshift()、splice()、sort()、reverse()
                                2.Vue.set() 或 vm.$set()
                    
                    特别注意:Vue.set() 和 vm.$set() 不能给vm 或 vm的根数据对象 添加属性!!!
            -->
            <!-- 准备好一个容器-->
            <div id="root">
                <h1>学生信息</h1>
                <button @click="student.age++">年龄+1岁</button> <br/>
                <button @click="addSex">添加性别属性,默认值:男</button> <br/>
                <button @click="student.sex = '未知' ">修改性别</button> <br/>
                <button @click="addFriend">在列表首位添加一个朋友</button> <br/>
                <button @click="updateFirstFriendName">修改第一个朋友的名字为:张三</button> <br/>
                <button @click="addHobby">添加一个爱好</button> <br/>
                <button @click="updateHobby">修改第一个爱好为:开车</button> <br/>
                <button @click="removeSmoke">过滤掉爱好中的抽烟</button> <br/>
                <h3>姓名:{{student.name}}</h3>
                <h3>年龄:{{student.age}}</h3>
                <h3 v-if="student.sex">性别:{{student.sex}}</h3>
                <h3>爱好:</h3>
                <ul>
                    <li v-for="(h,index) in student.hobby" :key="index">
                        {{h}}
                    </li>
                </ul>
                <h3>朋友们:</h3>
                <ul>
                    <li v-for="(f,index) in student.friends" :key="index">
                        {{f.name}}--{{f.age}}
                    </li>
                </ul>
            </div>
        </body>
    
        <script type="text/javascript">
            Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
    
            const vm = new Vue({
                el:'#root',
                data:{
                    student:{
                        name:'tom',
                        age:18,
                        hobby:['抽烟','喝酒','烫头'],
                        friends:[
                            {name:'jerry',age:35},
                            {name:'tony',age:36}
                        ]
                    }
                },
                methods: {
                    addSex(){
                        // Vue.set(this.student,'sex','男')
                        this.$set(this.student,'sex','')
                    },
                    addFriend(){
                        this.student.friends.unshift({name:'jack',age:70})
                    },
                    updateFirstFriendName(){
                        this.student.friends[0].name = '张三'
                    },
                    addHobby(){
                        this.student.hobby.push('学习')
                    },
                    updateHobby(){
                        // this.student.hobby.splice(0,1,'开车')
                        // Vue.set(this.student.hobby,0,'开车')
                        this.$set(this.student.hobby,0,'开车')
                    },
                    removeSmoke(){
                        this.student.hobby = this.student.hobby.filter((h)=>{
                            return h !== '抽烟'
                        })
                    }
                }
            })
        </script>
    </html>
  • 相关阅读:
    page指令
    CMD设IP
    JDBC的几种驱动
    Python的闭包使用
    1189. 扫雷游戏
    1287. 递增的三元子序列
    Pip安装使用国内源的两种方法
    Python Classmethod和Staticmethod函数
    Git提交远程仓库
    Git分支管理
  • 原文地址:https://www.cnblogs.com/y593216/p/16749611.html
Copyright © 2020-2023  润新知