Vue2(三):绑定样式、条件渲染(v-if,v-show)、列表渲染(v-for)、key的原理、列表过滤、列表排序

一、绑定样式

1.绑定class样式

(1)字符串写法

适用于:样式类名不确定,需要动态获取。

 <div id="root">
        <div class="basic" :class="mood" @click="changeMood">test</div>
        <!-- class是原本的,:class是在绑定事件,去vue那里找mood -->
    </div>
    <script type="text/javascript">
    
    new Vue({
        el:'#root',
        data:{
            mood:'normal'
        },
       methods:{
           changeMood(){
               this.mood="happy"
           }
       }
    })

点击盒子之后从normal到happy,但是sad没用上啊

methods:{
           changeMood(){
               const arr=['happy','normal','sad']
               const i=Math.floor(Math.random()*3)
            //    Math.random()里面不用填(0,1),就是生成[0,1)的数,*3[0,3)
               this.mood=arr[i]
           }
       }

把三种心情装数组里随机生成

(2)数组写法

 数组写法适用于:要绑定样式个数和名字都不确定

 <div class="basic" :class="arr"></div>
    </div>
    <script type="text/javascript">
    
    new Vue({
        el:'#root',
        data:{
            mood:'normal',
            arr:['a1','a2','a3']
        },

(3)对象写法

适用于:要绑定样式个数和名字都确定,要动态决定。

<div id="root">
        <div class="basic" :class="obj"></div>
    </div>
    <script type="text/javascript">
    
    new Vue({
        el:'#root',
        data:{
            mood:'normal',
            obj:{
                a1:false,
                a2:true
            }
        },

2.绑定style样式(用的不多)

(1)对象写法

<div id="root">
        <div class="basic" :style="styleObj">hh</div>
    </div>
    <script type="text/javascript">
    
    new Vue({
        el:'#root',
        data:{
            styleObj:{
                fontSize:'40px',
                color:'red'
              //这里面:前面的都得是存在的东西,不能随便写
            }
        },

(2)数组写法(比较少用)

<div id="root">
        <div class="basic" :style="[styleObj,styleObj2]">hh</div>
    </div>
    <script type="text/javascript">
    
    new Vue({
        el:'#root',
        data:{
            mood:'normal',
            styleObj:{
                fontSize:'40px'
            },
            styleObj2:{
                color:'red'
            }
        },

二、条件渲染

1.v-show

适用于:切换频率较高的场景。(不会动DOM树,只是隐藏,相当于添加display:none)
特点:不展示的DOM元素未被移除,仅仅是使用样式隐藏掉
备注:使用v-if的时,元素可能无法获取到,而使用v-show一定可以获取到。这是因为v-if会一不小心把标签直接从页面上干掉,而v-show不会干掉,只会隐藏。

<div id="root">
       <h3 v-show="a">欢迎来到{{name}}</h3>
       <!-- v-show:false==display:none -->
    </div>
    <script type="text/javascript">
    
    const vm=new Vue({
        el:'#root',
        data:{
           name:'尚硅谷',
           a:false
        }

2.v-if(结构都给干掉了)

(1).v-if=“表达式”
(2).v-else-if=“表达式”
(3).v-else(后面不跟条件
适用于:切换频率较低的场景。
特点:不展示的DOM元素直接被移除。
注意:v-if可以和:v-else-if、v-else一起使用,但要求结构不能被“打断”,几个div连着一起写。

<div id="root">
       <h3>当前的n值为:{{n}}</h3>
       <button @click="n++">点我n++</button>
       <div v-if="n===1">1</div>
       <div v-else-if="n===2">2</div>
       <!-- 只能成立一个,直接跳出循环,但是好多if叠在一起不一定只能同时成立一个 -->
       <div v-else>3</div>
    </div>
    <script type="text/javascript">
    
    const vm=new Vue({
        el:'#root',
        data:{
           n:1
        },

实现点击按钮n++,n=1跳出1,等于2跳出2,等于其他跳出3

template只能配合v-if使用,可以把很多h2包起来一起实现,不破坏结构(想要n===1时跳出三个h2)

三、列表渲染!!!

1.v-for

遍历数组:

只要用遍历去生成了多个相同的结构必须得设置key去区分

一个形参:
<div id="root">
       <ul>
           <h2>人员列表</h2>
           <li v-for="p in person" :key="p.id">
               {{p.name}}-{{p.age}}
               <!-- p不用去下边找,也可以是形参 -->
           </li>
           <!-- 让vue来做遍历 -->
       </ul>
    </div>
    <script type="text/javascript">
    
    const vm=new Vue({
        el:'#root',
        data:{
           person:[
               {id:'001',name:'张三',age:'18'},
               {id:'002',name:'李斯',age:'19'},
               {id:'003',name:'王五',age:'17'}
           ]
        },
多个形参:
<li v-for="(p,index) in person" :key="index">
               {{p}}-{{index}}
               <!-- p不用去下边找,也可以是形参 -->
           </li>

遍历对象:

<ul>
        <h2>汽车列表</h2>
        <li v-for="(value,k) in car" :key="k">
            {{k}}-{{value}}
        </li>
    </ul>
    </div>
    <script type="text/javascript">
    
    const vm=new Vue({
        el:'#root',
        data:{
           car:{
               name:'奥迪',
               value:'80万'
           }
        }//name-奥迪
           value-80万

2.key的作用与原理!!!

面试题:key在vue中写了怎么处理?写了用什么值比较好?react、vue中的key有什么作用?(key的内部原理)

1、 虚拟DOM中key的作用:
key是虚拟DOM对象的标识,当数据发生变化时,Vue会根据【新数据】生成【新的虚拟DOM】, 随后Vue进行【新虚拟DOM】与【旧虚拟DOM】的差异比较(diff算法),比较规则如下:

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是没有问题的。

key相当于人的身份证号,如果没有写key,默认就是index

当我们把老刘添加到第一位

methods: {
                add() {
                    const p = { id: 004, name: '老刘', age: 90 };
                    this.persons.unshift(p);
                }
            },

这个图中,以前的虚拟dom转换成过真实dom,生成新的虚拟dom之后,就和旧的进行对比,首先对比key=0的,发现新的是老刘,旧的是张三不一样,但是后面input框是一样的(输入的数据存在的真实dom中,虚拟的都是text input框),而且旧的input框生成过真实dom了就直接拿下来input,老刘是新的直接下来,导致老刘后面是张三的框,到了王五那里,旧的没有key=3,所以王五和王五的新框都直接下来(所以王五的input是新的)

这个就是用index当key出现了错误,而且效率低,张三、李四、王五都是上边掉下来的都没复用

四、列表过滤-模糊搜索

1.数据监视实现

 <div id="root">
       <ul>
           <h2>人员列表</h2>
           <input type="text" placeholder="请输入名字" v-model=keywords>
           <li v-for="p in fliperson" :key="p.id">
               {{p.name}}-{{p.age}}-{{p.sex}}
           </li>
       </ul>
    </div>
    <script type="text/javascript">
    
    const vm=new Vue({
        el:'#root',
        data:{
           keywords:'',
           person:[
               {id:'001',name:'周冬雨',age:'18',sex:'女'},
               {id:'002',name:'马冬梅',age:'19',sex:'女'},
               {id:'003',name:'周杰伦',age:'17',sex:'男'},
               {id:'004',name:'王伦',age:'17',sex:'男'}
           ],
           fliperson:[]
        },
        watch:{
            keywords:{
                immediate:true,
                //没输入就是空串,打开就自动运行了
                handler(newValue){
                this.fliperson=this.person.filter((p)=>{
                    // return p.name包含val
                    return p.name.indexOf(newValue)!==-1

                })
            }
        }
        }
     
    })

    </script>

2.computed实现

计算属性拿不到用户输入的东西val

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

    </script>

下去得好好看一下,好多方法都忘了

五、列表排序

每次点击sortType,计算属性都重新进行,原顺序能显示出来是person我们一直没动,动的是filperson

<body>
    <div id="root">
       <ul>
           <h2>人员列表</h2>
           <input type="text" placeholder="请输入名字" v-model=keywords>
           <button @click="sortType=2">年龄升序</button>
           <button @click="sortType=1">年龄降序</button>
           <button @click="sortType=0">原顺序</button>
           <li v-for="p in filperson" :key="p.id">
               {{p.name}}-{{p.age}}-{{p.sex}}
           </li>
       </ul>
    </div>
    <script type="text/javascript">
    
    const vm=new Vue({
        el:'#root',
        data:{
           keywords:'',
           sortType:0,
           person:[
               {id:'001',name:'周冬雨',age:'18',sex:'女'},
               {id:'002',name:'马冬梅',age:'19',sex:'女'},
               {id:'003',name:'周杰伦',age:'17',sex:'男'},
               {id:'004',name:'王伦',age:'17',sex:'男'}
           ],
        },
        computed:{
            filperson(){
                
                    const arr= this.person.filter((p) => {
                        //在这里筛选完之后立马返回去了,筛选完就排序才对
                        return p.name.indexOf(this.keywords)!==-1;
                    })
                    if(this.sortType){
                        arr.sort((p1,p2)=>{
                            return this.sortType===1?p2.age-p1.age:p1.age-p2.age
                        })
                        
                    }
                    return arr
                
        }}
     
    })
       
    </script>
</body>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值