優雅地使用loading

前言

      不知道從何時開始有了寫博客的想法,奈何本身的知識儲備還很薄弱,遲遲沒法下筆。這是個人第一篇博客,算是記錄一下本身學習前端以來的一些知識吧。若有錯漏,懇請指出,您的批評和指正是我前進路上的一大動力!css

      在平時的開發過程當中,咱們須要異步等待數據,經常會利用loading圖來增強用戶的體驗,讓用戶知道咱們有在加載,那麼如何在開發過程當中更爲優雅地使用loading呢?開發小程序的時候咱們只須要一句wx.showLoading()就完事兒了,而在web開發中也有相應的UI框架來幫咱們完成這件事情。那到底是怎麼實現的呢,讓咱們來一塊兒看一下。前端


先實現一個簡單的loading

      代碼以下vue

<div class="container">
  <div class="loading"></div>
</div>
.container {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}

.loading {
  width: 100px;
  height: 100px;
  border-radius: 100%;
  border: 5px #ffffff solid;
  border-right-color: #87CEEB;
  animation: loading 1s linear infinite;
}

@keyframes loading {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}複製代碼

     這樣咱們就實現了一個比較簡單的轉圈圈loading圖,下面我將分別敘述在vue和react中如何優雅地使用這個loading。react

Vue部分

     首先先用vue init webpack生成一個vue腳手架,插件的目錄以下圖所示webpack

     

     loading.vue裏寫進了咱們上面實現的簡單loading的代碼,加上一點點邏輯web

<script>
  export default {
    name: "loading",
    data() {
      return {
        show: false
      }
    }
  }
</script>複製代碼

   index.js小程序

//先引入loading組件
import LoadingComponent from './loading'
const Loading = {}
Loading.install = function (Vue) {
// 生成一個Vue的子類 同時這個子類也就是組件
const LoadingConstructor = Vue.extend(LoadingComponent)
// 生成一個該子類的實例
const instance = new LoadingConstructor()
// 將這個實例掛載在我建立的div上
// 並將此div加入全局掛載點內部
instance.$mount(document.createElement('div'))
document.body.appendChild(instance.$el)
//注入vue的原型鏈
Vue.prototype.$loading = {
    show() {
        instance.show = true
    },
    close(){  
        instance.show = false
        }
    }
}
export default Loading

複製代碼

這裏咱們生成個一個Vue的子類,而後將它的實例掛載到全局。將一些方法注入到Vue的原型鏈中,這樣就能夠在任何組件中經過相似於this.$loading.show()的方法來控制loading圖的顯示和隱藏。最後咱們導出Loading對象。而後在main.js中引入Loading插件,並調用Vue.use()方法來註冊插件bash



最後,讓咱們來測試一下吧。測試代碼以下,用setTimeout來模擬異步請求。app

<script>
  export default {
    name: 'HelloWorld',
    data() {
      return {
        msg: ''
      }
    },
    mounted() {
      this.$loading.show()
      setTimeout(()=>{
        this.$loading.close()
        this.msg = '加載完遼!'
      },3000)
    }
  }
</script>複製代碼



奶思!測試成功!框架


React部分

在此以前,我先介紹一下react中的高階組件(HOC)

高階組件

在React中,多個不一樣的組件中若是須要用到相同的功能,這個解決方法,一般有Mixin和高階組件。可是因爲Mixin過多會使使得組件難以維護,在React ES6中Mixin再也不被支持。高階組件是一個接替Mixin實現抽象組件公共功能的好方法。高階組件實際上是一個函數,接收一個組件做爲參數,返回一個包裝組件做爲返回值,相似於高階函數。

具體實現

先用create-react-app 生成一個測試腳手架,高階組件目錄以下圖所示


index.css主要是loading的樣式,index.js的代碼以下

import React from 'react';
import './index.css'

function hoc(ComponentClass) {
    return class HOC extends ComponentClass {
        render() {
            if (!this.state.loading) {
                console.log(this.state.loading)
                return super.render()
            }
            else {
                return (<div>
                    <div className="container">
                        <div className="loading"></div>
                    </div>
                </div>)
            }
        }
    }
}

export default hoc複製代碼

咱們定義了一個hoc函數,接受一個組件做爲參數。經過this.state來操做組件的state屬性,經過super.render()來渲染組件。最後導出hoc函數。而後在組件中引入,以下

import hoc from '../hoc/loading/index'

class Home extends Component {
    constructor(props) {
        super(props)
        this.state = {
            msg: '還沒加載好',
            loading: true
        }
    }

    render() {
        return (
            <div>
                {this.state.msg}
            </div>
        );
    }

    componentDidMount() {
        let loading = this.state.loading
        setTimeout(() => {
            this.setState({
                loading: !loading,
                msg: '加載完遼!'
            })
        }, 3000)
    }
}

export default hoc(Home)複製代碼

一樣是採用setTimeout來模擬異步請求,測試結果也是成功的。react部分並無用裝飾器來使用高階組件,還不夠優雅。。。(在create-react-app中把網上的處理方法都試了一遍,仍是報錯。。)

最後

     至此,在Vue和React中如何優雅地使用loading就到此結束遼。這是一個超簡易版的demo,但仍是但願能分享給你們。寫完才真正體會到了那句老話,紙上得來終覺淺,絕知此事要躬行。

相關文章
相關標籤/搜索