【vue】v-if

//index.js
import Vue from "vue";
import Helloworld from "./helloworld.vue";
const vm = new Vue({
    render:createElement => createElement(Helloworld)
}).$mount('#root');

v-if,条件渲染。
条件块内的事件监听和子组件,生存还是毁灭,v-if说了算。
如果v-if绑定的变量值是false,则不渲染条件块;
如果v-if绑定的变量值是true,则渲染条件块。
因此,如果频繁地切换v-if对应的变量值,会有很大的渲染开销。
涉及到频繁切换,用v-show可能比用v-if会更合理。

v-if

模板中使用v-if
//helloworld.vue
<template>
    <div v-if="isShow">hello world</div>
</template>

<script>
export default {
    data(){
        return {
            // isShow:true
            isShow:false
        }
    }
}
</script>

isShowtrue时显示文本“hello world”,false则不显示该文本。

使用render函数
//helloworld.vue
<template>
    <Helloworld/>
</template>

<script>
export default {
    components:{
        "Helloworld":{
            render:function(createElement){
                if(this.isShow){
                    return createElement('p','hello world');
                }else{
                    return null;
                }
            },
            data:function(){
                return {
                    isShow:true
                }
            }
        }
    }
}
</script>

v-if 包裹多个元素

<template>来包裹元素,最终的渲染结果里不包含<template>元素。

模板里使用v-if
//helloworld.vue
<template>
    <div>
        <template v-if="isShow">
            <p>hello</p>
            <p>world</p>
        </template>
    </div>
<!-- 
    <div v-if="isShow">
        <p>hello</p>
        <p>world</p>
    </div>
     -->
<!-- 
    <template v-if="isShow">
        <p>hello</p>
        <p>world</p>
    </template>
 -->
</template>

<script>
export default {
    data(){
        return {
            isShow:true
        }
    }
}
</script>

在这里插入图片描述

使用render函数
//helloworld.vue
<template>
    <Helloworld/>
</template>

<script>
export default {
    components:{
        "Helloworld":{
            render:function(createElement){
                if(this.isShow){
                    return createElement(
                        'div',
                        [
                            createElement('p','hello'),
                            createElement('p','world')
                        ]
                    )
                }else{
                    return null;
                }
            },
            data:function(){
                return {
                    isShow:true
                }
            }
        }
    }
}
</script>

v-if/v-else

模板里使用v-if/v-else
//helloworld.vue
<template>
    <div v-if="isShow">hello world</div>
    <div v-else>have a nice day</div>
</template>

<script>
export default {
    data(){
        return {
            isShow:true
        }
    }
}
</script>
使用render函数
//helloworld.vue
<template>
    <Helloworld/>
</template>

<script>
export default {
    components:{
        "Helloworld":{
            render:function(createElement){
                if(this.isShow){
                    return createElement('p','hello world');
                }else{
                    return createElement('p','have a nice day');
                }
            },
            data:function(){
                return {
                    isShow:true
                }
            }
        }
    }
}
</script>

v-if/v-else-if/v-else

模板里使用 v-if/v-else-if/v-else
//helloworld.vue
<template>
    <div v-if="color==='red'"></div>
    <div v-else-if="color==='green'">绿</div>
    <div v-else-if="color==='blue'"></div>
    <div v-else></div>
</template>

<script>
export default {
    data(){
        return {
            color:"red"
        }
    }
}
</script>
使用render函数
//helloworld.vue
<template>
    <Helloworld/>
</template>

<script>
export default {
    components:{
        "Helloworld":{
            render:function(createElement){
                switch(this.color){
                    case "red":return createElement('div','红');break;
                    case "green":return createElement('div','绿');break;
                    case "blue":return createElement('div','蓝');break;
                    default:return createElement('div','黄');
                }
            },
            data:function(){
                return {
                    color:"red"
                }
            }

        }
    }
}
</script>

v-if 可能存在的坑

  • 坑1:复用已有元素
//helloworld.vue
<template>
    <div>
        <template v-if="isLogged">
            <label for="username">Username</label>
            <input type="text" id='username' placeholder='enter your name' autocomplete="off"/>
        </template>
        <template v-else>
            <label for="email">Email</label>
            <input type="text" id='email' placeholder='enter your email' autocomplete="off"/>            
        </template>
        <div><button @click='handleClick'>toggle</button></div>
    </div>
</template>
<script>

export default {
    data(){
        return {
            isLogged:true
        }
    },
    methods:{
        handleClick:function(){
            this.isLogged = !this.isLogged
        }
    }
}
</script>

在这里插入图片描述
username输入框中输入文本“Tom”,切换到email输入框时,文本“Tom”没被清除。
这是因为,从username切换到emaillabel还是那个labelinput还是那个input
vue并没有因为切换重新生成新的DOM元素,而是重用了原有的DOM元素。

针对以上问题,其解决方法就是使用key避免元素复用。

//helloworld.vue
<template>
    <div>
        <template v-if="isLogged">
            <label for="username">Username</label>
            <input type="text" id='username' key='username' placeholder='enter your name' autocomplete="off"/>
        </template>
        <template v-else>
            <label for="email">Email</label>
            <input type="text" id='email' key='email' placeholder='enter your email' autocomplete="off"/>            
        </template>
        <div><button @click='handleClick'>toggle</button></div>
    </div>
</template>
<script>

export default {
    data(){
        return {
            isLogged:true
        }
    },
    methods:{
        handleClick:function(){
            this.isLogged = !this.isLogged
        }
    }
}
</script>

在这里插入图片描述

input添加key后,从username切换到emaillabel还是那个label,但input不再是原来那个input了。
此时,input#usernameinput#email就不会互相干扰了。

  • 坑2:把v-if和v-for应用在同一个元素上
<body>
    <div id="root">
        <ul>
            <li  v-for="user in users"
                 v-if="user.isActive"
                 v-bind:key="user.id"
            >{{user.name}}</li>
        </ul>
    </div>
</body>
import Vue from "vue";

const vm = new Vue({
    el:"#root",
    data:{
        users:[
            {id:"1",name:"Nicholas",isActive:true},
            {id:"2",name:"Greg",isActive:false},
            {id:"3",name:"Kate",isActive:false}
        ]
    }
});

下面的代码和以上等效。

<body>
    <div id="root">
    </div>
</body>
import Vue from "vue";

const vm = new Vue({
    el:"#root",
    data:{
        users:[
            {id:"1",name:"Nicholas",isActive:true},
            {id:"2",name:"Greg",isActive:false},
            {id:"3",name:"Kate",isActive:false}
        ]
    },
    render:function(createElement){
        return createElement("ul",
            this.users.map(user => {
                if(user.isActive){
                    return createElement("li",{"key":user.id},user.name);
                }
            })
        )
    }
});

v-for的优先级比v-if高,所以即使只是渲染了Nicholas这一个用户,仍遍历了整个列表user。后续每次重新渲染,都将遍历完整列表。

如何破局?使用计算属性。

<body>
    <div id="root">
        <ul>
            <li  v-for="user in activeUsers"
                 v-bind:key="user.id"
            >{{user.name}}</li>
        </ul>
    </div>
</body>
import Vue from "vue";

const vm = new Vue({
    el:"#root",
    data:{
        users:[
            {id:"1",name:"Nicholas",isActive:true},
            {id:"2",name:"Greg",isActive:false},
            {id:"3",name:"Kate",isActive:false}
        ]
    },
    computed:{
        activeUsers:function(){
            return this.users.filter(user => user.isActive);
        }
    }
});
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值