史上最详细 VUE2.0 全套 demo 讲解 基础3(计算属性)

做者 混元霹雳手-Ziksangjavascript

二天基础1+基础2忽然突破了1000的收藏率,这使我更以为你们承认我这种分享模式,这也看的出来vue的热度,我在这段时间的分享中,我一直脑海里在转,如何用最好的demo,和更好的流程去写文章,我相信从基础1开始看,必定能在工做上面有不少大的收获,接下来仍是按着咱们约定的来前端

1.本文分享 计算属性

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

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

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

我什么都不要我只要vue

计算属性java

在计算属性中,在咱们前面基础1和基础2分享中有两个地方能够计算属性,咱们认为全部属性的计算都是变向的在过滤值,经过数据的不断变化计算出不一样的值和操做不一样的方法
1.模板内的表达式
2.属性v-bind:里的能够进行表达式
3.指令中咱们也能够进行表达式
以上三者优点在那里,简洁,省代码量,若是只是一个小操做,比方说一些简单的数值++,字符拼接,三元表达式,那使用至关好
以上三者的劣势,一但要处理的逻辑复杂,若是用到if()流程控制语句,变量赋值,代码量大了就很难于维护,咱们可能就会想到用filter,那filter的场景适用于那里后面再说,先看一下简单的demoweb

App.vueajax

<template>
   <div> <p @click="count++">{{count+'分'}}</p> <input v-model='message'> <p>{{message.split('').reverse().join('') }}</p> </div> </template>
<script>
    export default {
        data () {
            return {
                count : 0,
                message : ''
            }
        }
    }
</script>复制代码

从上面不难看出
1.模板内使用字符拼接,ok代码很清楚目的的所在
2.经过指令点击,也能少一个methods方法,也很简洁
3.经过输入框输入文字,在p标签里面进行计算转换的时候,那我以为语意化就不是很强烈了,那用什么办法呢,用filtervue-cli

用filter的优点
filter给咱们用于计算和过滤一些模板表达式和v-bind:属性表达式一些弊端的地方进行计算,他会返回当前计算的值,能够进行传参在多地方共用这个过滤方法,
劣势
若是咱们要计算多个数据不一样变化结合而成的地方那filter就能难过到了,本质上filter我认为就是1v1,对单个数据进行过滤,能够进行传参,同方法,但不一样参,很是适用缓存

<template>
   <div> <input v-model='message'> <p>{{message | reverseString}}</p> </div> </template>
<script>
    export default {
        data () {
            return {
                message : ''
            }
        },
        filters : {
            reverseString (value) {
                if(!value) return ''
                value = value.split('').reverse().join('') 
                return value
            }
        }
    }
</script>复制代码

咱们把上个例子中第二个例子反转字符串这个方法用filter来实现,很明显示代码量多了那么一点点,可是总体的语意化至关明显了,让人一看这里就要进行一些过滤计算,能过reverseString,就能知道是反转字符串微信

1. computed

以上说了这么多前面的用法,由于咱们模板语法和filter过滤来对computed的应用场景作一个铺垫,划分更加明确
computed能够作那些呢,适用于什么场景呢?
他规避了模板语法和filter两个全部的劣势,他的优点在于经过计算全部依赖的数据进行计算,而后返回一个值,记住能够依赖方法里全部的数据,只要一个数据发生变化,则会重新计算,来更新视图的改变,verygood,好东西看看怎么玩app

应用场景 :
这是一个简单实用的应用场景,后面再作一个好玩的应用场景
咱们填写备注的时候咱们会有一个字数的限制和字数显示的限制,经过输入字符,咱们要提醒用户还有输入多少字

<template>
   <div>
        <textarea v-model="content" :maxlength="totalcount"></textarea>
        <p>你还能够输入{{reduceCount}}字</p>
   </div>
</template>
<script>
    export default {
        data () {
            return {
                totalcount : 200 , //总共只给输入200字
                content : ''
            }
        },
        computed : {
            reduceCount () {
                return this.totalcount - this.content.length
            }
        }
    }
</script>复制代码

经过一直监听文字的字符的长度来出发compunted里reduceCount这个方法,来再次进行计算,返回值给视图,让视图进行变化。这也是一个很简单的demo例子,那很好,前面我说了能够监听多个数据,只要一个数据变了,整个方法就会重新计算,反馈到视图,这个方法只是一个简单的应用,请看下个demo例子,大家就能看懂一切的一切

这个例子是我想了一个多小时才次决定的例子,那就最就萨德事件使中韩足球最热门的一个事件,作IT作DEMO就是要玩起来,政治咱们先不讨论,咱们用技术来感化一下咱们的爱国情
demo场景分析
1.咱们要声明那些数据
一.比赛时间 用time来维护
二.比赛双方的进球数 用对象来维护
三.比赛的播报状况 在90分钟内,要显示中国领先或者韩国队领先或者双方僵持,若是到了90分种咱们要显示中国队赢仍是韩国队赢,仍是平局
第三个数据很是关键,咱们用什么来维护,能够说比赛状况是多样化的,用一个数据去定死维护,不符合场景,那我先列出那经过改变这些变化,咱们不但要检测双方的进球数,还要经过时间来比对,是90分钟内,仍是已经结束比赛了,来显示不一样的文案。因此咱们要不断监听两个维护的数据,一是比赛时间,二是比赛两队进球数

<template>
   <div>
        <h1>比赛时间{{time}}s</h1>
        <h2>直播播报{{result}}</h2>
        <div>
             <p>中国队进球数:{{team.china}}</p>
             <button @click="team.china++">点击中国队进一球</button>
             <p>韩国队进球数:{{team.korea}}</p>
             <button @click="team.korea++">点击韩国队进一球</button>
        </div>
   </div>
</template>
<script>
    export default {
        created () {
            let time =  setInterval(()=>{
                this.time++
                if(this.time == 90){
                    clearInterval(time)
                }
            },1000)
        },
        data () {
            return {
                time : 0,
                team : {
                    china : 0,
                    korea : 0
                }
            }
        },
        computed : {
            result () {
               if(this.time<90){
                   if(this.team.china>this.team.korea){
                       return '中国队领先'
                   }else if(this.team.china<this.team.korea){
                       return '韩国队领先'
                   }else{
                       return '双方僵持'
                   }
               }else{
                   if(this.team.china>this.team.korea){
                       return '中国队赢'
                   }else if(this.team.china<this.team.korea){
                       return '韩国队赢'
                   }else{
                       return '平局'
                   }
               }
            }
        }
    }
</script>复制代码

上面的我用点击事件来进行双方进球数,把上面这个demo运行一下咱们能够充分的理解computed的涵意,说究竟是观察一个或者多个数据,每当其中一个数据改变的时候,这个函数就会重新计算,还有就是经过观察全部数据来维护一个状态,就是所谓的返回一个状态值,从上面这个demo咱们就能够很容易的知道computed到底用在什么场景,如何去维护返回一个多状态的场景

2.methods vs computed

在methods和computed能够作一样的事,可是,computed能够进行缓存,什么意思呢,就是在上个例子咱们对比赛时间和两个球队的进球数进行了检测数据,若是随着时间的改变,可是球数没动,对于computed来讲只会重新计算这个球数会进入缓存,不会再次计算,而重新计算的是这个时间,并且页面的dom更新也会出发methods来重新计算属性,因此若是不想让计算属性进入缓存,请求methods,可是我推荐用computed,语议化好一点麻,什么选项里就应该改作什么事,methods里面就是应该来管事件的。我的认为,一样的操做我就不演示demo了,看看官方的用法理解一下就能够了

3.computed vs watch

computed和watch均可以作同一件事,就像跑步运动员均可以跑步,可是分100米和1000米,术业有专功麻,两个选项都是对数据进行时时监听,可是两个的适用场景就不同了

一.computed前面说了是适用于对多数据变更进行监听,而后来维护一个状态,就是返回一个状态

二.watch是对一个数据监听,在数据变化时,会返回两个值 ,一个是value(当前值),二个是oldvalue是变化前的值,咱们能够经过这些变化也能够去维护一个状态,可是不符合场景,主要用于什么地方呢?主要用于监听一个数据来进行复杂的逻辑操做

<template>
   <div>
        <h1>比赛时间{{time}}s</h1>
        <h2>直播播报{{result}}</h2>
        <div>
             <p>中国队进球数:{{team.china}}</p>
             <button @click="team.china++">点击中国队进一球</button>
             <p>韩国队进球数:{{team.korea}}</p>
             <button @click="team.korea++">点击韩国队进一球</button>
        </div>
   </div>
</template>
<script>
    export default {
        created () {
            let time =  setInterval(()=>{
                this.time++
                if(this.time == 90){
                    clearInterval(time)
                }
            },1000)
        },
        data () {
            return {
                time : 0,
                team : {
                    china : 0,
                    korea : 0
                },
                result : "双方僵持"
            }
        },
        watch : {
            time (value,oldval) {
               if(value<90){
                   if(this.team.china>this.team.korea){
                       this.result =  '中国队领先'
                   }else if(this.team.china<this.team.korea){
                       this.result =  '韩国队领先'
                   }else{
                       this.result =  '双方僵持'
                   }
               }else{
                   if(this.team.china>this.team.korea){
                       this.result =  '中国队赢'
                   }else if(this.team.china<this.team.korea){
                       this.result =  '韩国队赢'
                   }else{
                       this.result =  '平局'
                   }
               }
            },
            team (value,oldval){
                if(this.time<90){
                   if(value.china>value.korea){
                       this.result =  '中国队领先'
                   }else if(value.china<value.korea){
                       this.result =  '韩国队领先'
                   }else{
                       this.result =  '双方僵持'
                   }
               }else{
                   if(value.china>value.korea){
                       this.result =  '中国队赢'
                   }else if(value.china<value.korea){
                       this.result =  '韩国队赢'
                   }else{
                       this.result =  '平局'
                   }
               }
            }
        }
    }
</script>复制代码

以上代码和computed的产生的效果如出一辙,可是很明显,就像我对computedwatch阐述过了应用场景,这个场景只是维护了一个比赛的状态,而不牵扯到逻辑操做,虽然也能完成,很明显,不管从代码量的比对,仍是可读性,仍是可维护性的比对都不胜于computed,可是说到底谁更强大呢,我仍是老实的说watch更强大,虽然他有场景的局限性,可是他能够作牵扯到计算属性的一切操做,缺点watch只能一个一个监听

watch应用场景
我想信图片预加载你们确定都有接触过,当图片量大的时候,为了保证页面图片都加载出来的时候,咱们才把主页面给显示出来,再进行一些ajax请求,或者逻辑操做
那此时你用computed对这种监听一个数据而后进行一系列逻辑操做和ajax请求,那watch再适合不过了,若是用computed的话那你连实现都实现不了,只有用watch监听

<template>
   <div v-show=show>
       <img src="https://img.alicdn.com/simba/img/TB14sYVQXXXXXc1XXXXSutbFXXX.jpg" alt="">
       <img src="//img.alicdn.com/tfs/TB1iZ6EQXXXXXcsXFXXXXXXXXXX-520-280.jpg_q90_.webp" alt="">
       <img src="https://img.alicdn.com/simba/img/TB1C0dOPXXXXXarapXXSutbFXXX.jpg" alt="">
       <img src="//img.alicdn.com/tfs/TB1iZ6EQXXXXXcsXFXXXXXXXXXX-520-280.jpg_q90_.webp" alt="">
   </div>
</template>
<script>
    export default {
        mounted () {
            var _this = this
            let imgs = document.querySelectorAll('img')
            console.log(imgs)
            Array.from(imgs).forEach((item)=>{
                let img = new Image()
                img.onload = ()=>{
                    this.count++
                }
                img.src=item.getAttribute('src')
            })
        },
        data () {
            return {
                count : 0,
                show : false
            }
        },
        watch : {
            count (val,oldval) {
                if(val == 4){
                    this.show = true
                    alert("加载完毕")
                    //而后能够对后台发送一些ajax操做
                }
            }
        }
    }
</script>复制代码

咱们能够发现发四张图片都加载完毕的时候页面才显示出来

根据完方有一句话说的很重要的一句

虽然计算属性在大多数状况下更合适,但有时也须要一个自定义的 watcher 。这是为何 Vue 提供一个更通用的方法经过 watch 选项,来响应数据的变化。当你想要在数据变化响应时,执行异步操做或开销较大的操做,这是颇有用的。

基于这个官方的理解再总结我我的的总体理解。给出computed和watch的总结,记住这几点的总结,在作项目的时候想一想这些总结,选择你的应用方法

computed :

监听多个数据或者一个数据来维护返回一个状态值 ,只要其中一个或多个数据发生了变化,则会重新计算整个函数体,重新返回状态值

watch :
只有一个一个监听据,只要这个数据发生变化,就会在返回两个参数,第一个是当前的值,第二个是变化前的值,每当变化的时候,则会触发函数体的里的逻辑行为,来进逻辑后续操做

其实我以为计算属性也好,computed,watch这几个都不是有多难,若是浅层面上看很容易理解,若是从深层面上看,不少小伙伴会存在什么问题,就是会滥用,混用,这些计算属性,我想经过这些demo例子讲解和分析,我相信你又上一层楼了,ok终于能够完结这篇了,下一篇我想看看你们想学什么能够给我留言,若是那个多我就先讲那个
1.事件处理
2.表单控件
3.条件渲染
4.class 和 style 绑定

渣渣前端开发工程师,喜欢钻研,热爱分享和讲解教学, 微信 zzx1994428 QQ494755899

支持我继续创做和感到有收获的话,请向我打赏点吧

若是转载请标注出自@混元霹雳手ziksang