史上最詳細 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

相關文章
相關標籤/搜索