史上最详细 VUE2.0 全套 demo 讲解 基础4(条件渲染)

三篇基础发布之后,收到最多的就是谢谢楼主,其次的就是错别字有点多,这篇我肯定写完之后读三遍,现在已经是夜里2点了,如果还有没有发现大家就容忍一下,这次我将要讲的是条件渲染,对于条件渲染我觉得思来思去真没有什么好写的,但是既然我说过了这个是掘进史上最详细那我就要坚持我的创作,做一个最完整的教程出来,但是如果你真的从头到尾把这文章看下去,我相信你肯定会有收获

接下来还是按着我们约定的来

1.本文分享 计算属性

2.代码运行vue-cli 2.1版本

3.组件代码都在components文件夹里

4.主代码逻辑都在 App.vue文件夹里

我什么都不要我只要

v-if 条件渲染

在1.0的时候我们只有v-if v-else
但在2.0的时候多了一个v-else-if 我只能说有用的不行不行的
更多什么专业名词的解释去看看官网那肯定比我这里好,我这里就是讲一些官网没有,甚至比官网还好的demo

先简单的看一个demo
如果是通常思维写法,我相信肯定是这么写

应用场景
因为我处在一家金融公司,理财师可以取消和申请客户活动的参与次格,如果客户是已经参与的那我可以取消参与,如果不是参与的我可以申请参与,正常做项目我们不可能因为逻辑稍微复杂我们分开两个页面做,一个做取消,一个做申请,那是一件很傻的事,如果再多一个选项你启不是要再写一个页面,但是我们现在只能在页面根据不同的判断,只能显示取消或者申请两个其中之一,那就用v-if v-else

<template>
     <div>
         <h1 v-if="result == 'No'">申请参与</h1>
         <h1 v-else>取消参与</h1>
     </div>
</template>

<script>
     export default {
         data () {
             return {
                 result : 'No'
             }
         }
     }
</script>

OK那没有问题,如果result是no的话我们就申请参与,否则就是取消参与,这只是一个试用的例子,我们正常的场景肯定不是这样的,不用看这个result值肯定是调取后台结口,经过查询返还你result这个字段,那就是一个异步请求,我们可以模拟一下,看看会有什么结果,你结对意想不到

<template>
     <div>
         <h1 v-if="result == 'No'">申请参与</h1>
         <h1 v-else>取消参与</h1>
     </div>
</template>

<script>
     export default {
         created () {
             setTimeout(()=>{
                 this.result = 'No'
             },1000)
         },
         data () {
             return {
                 result : ''
             }
         }
     }
</script>

我们在created生命周期里模拟一个ajax请求,当发送请求后,两秒钟后请求返回,会发生什么结果,结果一脸蒙B,你会发现先显示取消参与,两秒后会再显示申请参与,这本质上跟我们正常的判断逻辑js一样,if…..else……
如果if不成立直接成立else,因为2秒后result发生了变化,从新计算了v-if和v-else,
如果你的页面中result参数是从sessionStorage取到或者是从url参数上截取来的,ok不会有影响
这是一个坑一个大坑那怎么办那就轮到v-if-else出场了

<template>
     <div>
         <h1 v-if="result == 'No'">申请参与</h1>
         <h1 v-else-if="result == 'Yes'">取消参与</h1>
     </div>
</template>

<script>
     export default {
         created () {
             setTimeout(()=>{
                 this.result = 'No'
             },1000)
         },
         data () {
             return {
                 result : ''
             }
         }
     }
</script>

我们拿v-else-if 再做一个判断,在ajax不返回之前如果result不等于no或者不等于yes我则什么都不显示,让初始result直接等于””,直到接口返回改变了数据,从新渲染了页面,则会显示申请参与,不会像上面造成那种一闪的效果

v-if and v-for template

1.因为 v-if 是一个指令,需要将它添加到一个元素上。但是如果我们想切换多个元素呢?此时我们可以把一个 template 元素当做包装元素,并在上面使用 v-if。最终的渲染结果不会包含 template 元素。
2.v-if 与 v-for 一起使用
当 v-if 与 v-for 一起使用时,v-for 具有比 v-if 更高的优先级。
我把以上两种官方给的这句话我用一个demo给大家展示一下就明白了

应用场景
这个场景也是我这两天做项目刚做到的,现在一个用户可以每天领一份保险,保险有效期七天,时间长了,他就有会很多保单,有生效的保单和过期的保单,所有保单还有保单详情,产品经理要我把过期的保单只显示一个保单号,没过期的保单所有详情全显示出来

<template>
     <div>
        <div v-for='(item,index) in insurance'>
            <template v-if='nowTime < item.endtime'>
                <p>{{item.code}}</p>
                <p>{{item.name}}</p>
                <p>{{item.tel}}</p>
                <hr></hr>
            </template>
            <template v-else-if='nowTime > item.endtime'>
                <p>{{item.code}}</p>
                <hr></hr>
            </template>
        </div>
     </div>
</template>

<script>
     export default {
         created () {
                let myDate = new Date();
                let year = myDate.getFullYear(); //获取完整的年份(4位,1970-????)
                let month = myDate.getMonth()+1; //获取当前月份(0-11,0代表1月)
                let day = myDate.getDate(); //获取当前日(1-31)
                if(day<10){
                    day = '0'+day
                }
                if(month<10){
                    month = "0"+month
                }
                this.nowTime=`${year}-${month}-${day}`
             var insurance = [
                 {endtime :'2017-02-01',code : '111111111',name:'ziksang', tel:'1000000000'},
                 {endtime :'2017-02-03',code : '222222222',name:'ziksang2', tel:'2000000000'},
                 {endtime :'2017-09-10',code : '333333333',name:'ziksang3', tel:'3000000000'},
                 {endtime :'2999-02-01',code : '444444444',name:'ziksang4', tel:'4000000000'}
             ]
             this.insurance = insurance
         },
         data () {
             return {
                 nowTime : "",
                 insurance : []
             }
         }
     }
</script>

endtime:保单结束时间
code:保单号
name : 保单用户名
tel:保单用户手机

我先在最外层做一个循环v-for,再通过根据当前时间与保单结束时间对比,如果当前时间大于保单结束日,则用v-else-if 里面的模板,反之则用v-if里的模板,每个模板有着自己不同的dom结构,我想大家一定恍然大悟看懂了

过了一天,我很生气生气,产品经理跑过来又跟我说了一个需求,他说霹雳手,我一看他叫我霹雳手我就知道他要找我麻烦了,我回了句请叫我混元霹雳手-ziksang哈哈,不出我所料,在上面的需求加了一个功能,

改动应用场景

上面的一个功能不变,如果是过期的保险不光要显示保单号,再过期的保单上面加一个按钮,如果用户点击之后可以显示详情,再点击之后又可以收起来,只显示保单号,我当场就说了一句话没有vue做不到的,给我十分种 ,啪啪啪之后就改好了

这里牵到两个知识点,官方话语:
v-if 是“真正的”条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。
v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。
相比之下, v-show 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。
一般来说, v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件不太可能改变,则使用 v-if 较好。
注意, v-show 不支持 template 语法,也不支持 v-else。

<template>
     <div>
        <div v-for='(item,index) in insurance'>
            <template v-if='nowTime < item.endtime'>
                <p>{{item.code}}</p>
                <p>{{item.name}}</p>
                <p>{{item.tel}}</p>
                <hr></hr>
            </template>
            <template v-else-if='nowTime > item.endtime'>
                <button @click='item.arrow = !item.arrow'>按钮</button>
                <p>{{item.code}}</p>
                <p v-show='item.arrow == true'>{{item.name}}</p>
                <p v-show='item.arrow == true'>{{item.tel}}<p>
                <hr></hr>
            </template>
        </div>
     </div>
</template>

<script>
     export default {
         created () {
                let myDate = new Date();
                let year = myDate.getFullYear(); //获取完整的年份(4位,1970-????)
                let month = myDate.getMonth()+1; //获取当前月份(0-11,0代表1月)
                let day = myDate.getDate(); //获取当前日(1-31)
                if(day<10){
                    day = '0'+day
                }
                if(month<10){
                    month = "0"+month
                }
                this.nowTime=`${year}-${month}-${day}`
             var insurance = [
                 {endtime :'2017-02-01',code : '111111111',name:'ziksang', tel:'1000000000',arrow:false},
                 {endtime :'2017-02-03',code : '222222222',name:'ziksang2', tel:'2000000000',arrow:false},
                 {endtime :'2017-09-10',code : '333333333',name:'ziksang3', tel:'3000000000',arrow:false},
                 {endtime :'2999-02-01',code : '444444444',name:'ziksang4', tel:'4000000000',arrow:false}
             ]
             this.insurance = insurance
         },
         data () {
             return {
                 nowTime : "",
                 insurance : []
             }
         }
     }
</script>

1.这里我再每份保单里加了一个字段为arrow作为按钮开关
2.因为过期保单里的详情是用户虽时会切换显示的,所以我们用到v-show,减少dom来回去除的开销。很神奇吧,一个demo就把条件渲染讲的明明白白,透透彻彻。

我看我分享的这段时间里,有些同学都觉得我分享的东西很基础,基础的才是万变不离其中的东西,下篇我将给大家分享点复杂点的东西,我自己写的vue日历组件,支持接口最大时间小最时间起始时间区间段不让选时间,尽请期待。

原文链接:https://juejin.im/post/58dd0bbbb123db00603b8bc1

发表评论

登录后才能评论