Vue2.0進階組件篇2 解析餓了麼(spinner組件)

做者 混元霹靂手-ziksangjavascript

前兩天一個同窗問我想叫我寫了一個spinner組件,那OK我就是那麼能知足你們的口味,若是寫一個spinner組件,別看一個小小的組件如何去寫,不少人問我vuex,vue-router怎麼玩,這東西有什麼好玩的,看看api文檔就能夠去玩了,而後我就看看了餓了麼spinner組件的寫法,他是如何去組織本身的代碼結構的
由於餓了麼的spinner組件本質上是基於px來寫的,我常常會遇到一個問題,我用的是rem怎麼辦,px畢竟仍是不適配,那只有拿出個人開山釜本身打造一個rem版本的,若是有餓了麼開發人員看到我這文章,雖然小弟我沒辦法和大家肩並肩一塊兒打造組件,那我就借鑑一下,人在江湖走那有不被抄。css


接下來仍是按着咱們約定的來
關於組件篇我就直接拿demo再進行細化分析給你們講一些細節的知識點,我相信會更有意思一點,爲何我要把基礎給你們講的那麼詳細呢,由於基礎打的好組件才寫的好
1.本文分享 解析餓了麼(spinner組件)

2.代碼運行vue-cli 2.1版本html

3.組件代碼都在components文件夾裏前端

4.主代碼邏輯都在 App.vue文件夾裏vue

我什麼都不要我只要java

css3

餓了麼向外爆露出三個接口
color : 顏色 size : 大小 type : 樣式類型web

首先index.html,先用rem佈局,原理略知一二,就很少說了,反正就是移動端給你作適配vue-router

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>y</title>
    <meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
    <script>
        (function(doc, win) {
            var docEl = doc.documentElement,
                resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
                recalc = function() {
                    var clientWidth = docEl.clientWidth;
                    if (!clientWidth) return;
                    if (clientWidth >= 640) {
                        docEl.style.fontSize = '100px';
                    } else {
                        docEl.style.fontSize = 100 * (clientWidth / 640) + 'px';
                    }
                };

            if (!doc.addEventListener) return;
            win.addEventListener(resizeEvt, recalc, false);
            doc.addEventListener('DOMContentLoaded', recalc, false);
        })(document, window);
    </script>
</head>

<body>
    <div id="app"></div>
    <!-- built files will be auto injected -->
</body>

</html>複製代碼

接下來咱們在components寫spinner組件,這裏我就寫兩個組件一個是snake,和double-bouncevuex

首先咱們在components先寫一個snake,咱們先建立一個spinner文件夾,就單個type形式的如何寫,既然教你們了,就一步一步來寫,寫的麻煩點就麻煩點。

個人文件目錄是在components裏創了一個=》zk-spinner文件夾=》又建立了一個src文件夾=>又建立了一個snake.vue文件
components/zk-spinner/src/snake.vue

<template>
    <div class='snake' :style="{
        'border-top-color' : spinnerColor,
        'border-left-color' : spinnerColor,
        'border-bottom-color' : spinnerColor,
        'height' : spinnerSize,
        'width' : spinnerSize
    }">
    </div>
</template>
<script>
export default {
    name : 'snake',
    computed : {
        spinnerColor () {
            return this.color || this.$parent.color || 'red'
        },
        spinnerSize () {
            return (this.size || this.$parent.size || .44)+'rem'
        }
    },
    props : {
        color : String,
        size :  Number
    }
}
</script>
<style>
.snake {
    animation : ziksang-spinner-rotate 0.8s infinite linear;
    border : 4px solid transparent;
    border-radius : 50%;
}
@keyframes  ziksang-spinner-rotate {
    0% {
        transform : rotate(0deg);
        transform : rotate(360deg)
    }
}

</style>複製代碼

App.vue

<template>
    <snake></snake>
</template>

<script>
import snake from './components/zk-spinner/src/snake.vue'
export default {
    components : {
        snake
    }
}
</script>

<style>
</style>複製代碼

你會發現一個小蛇就在來回的轉啊轉,很漂亮,這裏只用到了向外暴露的兩處一個是color,一個是顏色,這裏用的是compunted來計算返回給template模板裏,這時好處是什麼呢,能夠用默認樣式,還能夠用本身定樣式
this.color || this.$parent.color || 'red'
(this.size || this.$parent.size || .44)+'rem'
這裏表明若是本身沒有設定樣式則用父元素的樣式,父元素沒有樣式,則用默認樣式,你後續會發現 this.color 和 this.size和默認就是根本沒有任何用的東西,這裏設計的就是一個並句,回頭看到後面我再給你們分析

咱們再來寫一個double-bounce樣式
components/zk-spinner/src/double-bounce.vue

<template>
    <div class="double-bounce" :style='{
        width:spinnerSize,
        height:spinnerSize
    }'>
        <div class="double-bounce1" :style='{backgroundColor : spinnerColor}'></div>
        <div class="double-bounce2" :style='{backgroundColor : spinnerColor}'></div>
    </div>
</template>

<script>
export default {
    name : 'double-bounce',
    computed : {
        spinnerColor () {
            return this.color || this.$parent.color || 'red'
        },
        spinnerSize () {
            return (this.size || this.$parent.size || .44)+'rem'
        }
    },
    props : {
        color : String,
        size :  Number
    }
}
</script>

<style>
.double-bounce {
  position: relative;
}

.double-bounce1, .double-bounce2 {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  background-color: #67CF22;
  opacity: 0.6;
  position: absolute;
  top: 0;
  left: 0;

  -webkit-animation: bounce 2.0s infinite ease-in-out;
  animation: bounce 2.0s infinite ease-in-out;
}

.double-bounce2 {
  -webkit-animation-delay: -1.0s;
  animation-delay: -1.0s;
}

@-webkit-keyframes bounce {
  0%, 100% { -webkit-transform: scale(0.0) }
  50% { -webkit-transform: scale(1.0) }
}

@keyframes bounce {
  0%, 100% { 
    transform: scale(0.0);
    -webkit-transform: scale(0.0);
  } 50% { 
    transform: scale(1.0);
    -webkit-transform: scale(1.0);
  }
}
</style>複製代碼

App.vue

<template>
    <div>
        <snake></snake>
        <double-bounce></double-bounce>
    </div>
</template>

<script>
import snake from './components/zk-spinner/src/snake.vue'
import doubleBounce from './components/zk-spinner/src/double-bounce.vue'
export default {
    components : {
        snake,
        doubleBounce
    }
}
</script>

<style>
</style>複製代碼

此時你會發現一個東西,其實本質上,作再多樣spinner樣式,只要去基於css3寫一些東西,就能夠了,咱們能夠借鑑前兩天掘進裏有一我的發的什麼7種loading樣式,個人收藏夾裏有,大家能夠去找一下,按照裏面的樣式,你能夠作更多spinner
裏面不少東西都是換湯不要藥,從兩個spinner裏能夠發現computed和props裏面共用的都是一樣的,那如今我有隻有兩個spinner,若是我如今有十個spinner可提供給你們用的,那啓不是要寫十下,基於編程思想,我要仍是要抽取出來,咱們提取到common.vue裏

components/zk-spinner/src/common.js

export default {
    computed: {
        spinnerColor() {
            return this.color || this.$parent.color || 'red'
        },
        spinnerSize() {
            return (this.size || this.$parent.size || .6) + 'rem'
        }
    },
    props: {
        color: String,
        size: Number
    }
}複製代碼

如今問題來了,咱們如今有兩個組件,一個是snack,和 double-bounce,咱們要更完善一點,再把他們兩個掛到一個組件上,那就用到了動態組件,is來進行改造

<template>
     <component :is="spinner"></component>
</template>

<script>
    const SPINNERS= [
        'snake',         //第一段
        'double-bounce'
    ]
    const parseSpinner = function(index){
        if(Object.prototype.toString.call(index) == '[object Number]'){
            if(index >= SPINNERS.length){
                console.warn(`'${index}' spinner not found, use the default spinner.`);
                index = 0   //第二段
            }
            return SPINNERS[index]
        }
        if(SPINNERS.indexOf(index) === -1){
            console.warn(`'${index}' spinner not found, use the default spinner.`);
            index = SPINNERS[0]  //第三段
        }
        return index
    }

    export default {
        name : 'zk-spinner',
        computed : {
            spinner () {
                return `spinner-${parseSpinner(this.type)}`
            }    //第四段
        },
        components: {   //第五段
            SpinnerSnake: require('./src/snake.vue'),
            SpinnerDoubleBounce : require('./src/double-bounce.vue')
        },
        props: {
            type: {
                default: 0    //第六段
            },
            size: {
                type: Number,
                default: .6
            },
            color: {
                type: String,
                default: 'red'
            }
        }
    }
</script>複製代碼

App.vue

<template>
    <div> <zk-spinner :type='1' color='#000' ></zk-spinner> <zk-spinner :type='0' color='#000' ></zk-spinner> </div> </template> <script> import zkSpinner from './components/zk-spinner/zk-spinner.vue' export default { components : { zkSpinner } } </script> <style> </style>複製代碼

我對這裏進行詳細的解釋一下,以上我分了六段,我以爲按着順序講不必定是好事,咱們按着我所學習的想法和大家說,
1.我先從props裏的將要從父組件接收的數據,我在common.js裏把this.color,this.size 和默認的都刪除了,由於不管snake仍是double-bounce他們的父組件是誰,是這個動態組件,本質上這個動態組件也就是他們一個掛載的地點,沒有必要再進行數據傳遞,咱們只要進行繼承父組件接收的數據便可。因此this.color和this.size都沒有沒有用的,由於咱們根本不傳遞數據,默認數據咱們也在動態組件裏進行設了default
2.咱們再看看components裏面,咱們進行兩個組件引入
3.咱們再看看computed,咱們經過計算屬性,經過不一樣的計算返回不一樣的組件
4.咱們再看看SPINNERS變量裏,咱們對組件名進行了定議
5.在第二段裏當咱們在type裏傳入的是一個數字的話,若是數字大於PINNERS變量的總長度,咱們則默認給第一個樣式,咱們再給出提醒
6.在第三段裏另外一種傳法,傳入一個字符傳,先對看SPINNERS變量進行一個匹配,若是匹配到則用這個,沒有的話仍是默認用snake這個樣式,再給出warn提示

最後咱們都明白了這三個用法了,type是如何封裝出來的,size和color又是如何封裝出來的,其實若是你真的能把組件系統搞明白了,對你的邏輯思惟和封裝一些js的能力也是一種提高,大型項目又有幾個能作,因此vuex這東西你們只要沒事看看api文檔本身手動試試就沒有什麼問題了,若是有空的話,若是我夠精通的話,我會給你們進行分享的,支持混元霹靂手ziksang,感謝你們!!!

渣渣前端開發工程師,喜歡鑽研,熱愛分享和講解教學, 微信 zzx1994428 QQ494755899

支持我繼續創做和感到有收穫的話,請向我打賞點吧

若是轉載請標註出自@混元霹靂手ziksang

相關文章
相關標籤/搜索