2017-02-25 7 views
0

私のコンポーネントは、このようなものです:私が検索するときは前のデータを表示し、検索中に読み込みアイコンを追加するには? (Vue.js 2)

<template> 
    ... 
     <input type="text" class="form-control" v-model="rawFilter" placeholder="Search" @keyup="getPlayers"> 
    ... 
</template> 

<script> 
    import _ from 'lodash' 
    ... 
    export default { 
     ... 
     data() { 
      return{ 
       msg:'hello vue', 
       rawFilter:'', 
       loading:false 
      } 
     }, 
     ... 
     methods: { 
      getPlayers: _.debounce(function(e) { 
       const text = e.target.value.trim() 
       this.$store.dispatch('getPlayers', { 
        q: text 
       }) 
      },1000), 
      ... 
     } 
    } 
</script> 

、私はvue.js 2でそれを行うことができますどのようにロードアイコン

を追加したいです?

答えて

0

テンプレートにローディングdivを追加して、loadingフラグに基づいて表示を切り替えることができます。この

new Vue({ 
 
    el: '#app', 
 
    data: { 
 
    show: true, 
 
\t isLoading: false, 
 
    }, 
 
\t methods:{ 
 
\t \t loadData: function(){ 
 
\t \t \t this.isLoading = true; 
 
\t \t \t setTimeout(function(){ 
 
\t \t \t \t this.isLoading = false; 
 
\t \t \t }.bind(this),1000); 
 
\t \t } 
 
\t } 
 
})
.loading{ 
 
\t display: none; 
 
\t position: absolute; 
 
    width: 100%; 
 
    height: 100%; 
 
    top: 0; 
 
    background: rgba(128, 128, 128, 0.5); 
 
} 
 
.loading.show{ 
 
\t display: initial; 
 
}
<!DOCTYPE html> 
 
<html> 
 
<head> 
 
    <meta charset="utf-8"> 
 
    <meta name="viewport" content="width=device-width"> 
 
    <title>JS Bin</title> 
 
</head> 
 
<body> 
 
<div id="app"> 
 
\t <div class="loading" v-bind:class="{ show: isLoading }"> 
 
\t \t <span>Loading</span> 
 
\t </div> 
 
\t <button @click="loadData">Load</button> 
 
</div> \t 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.0.3/vue.js"></script> 
 
</body> 
 
</html>

ような何かあなたはかなりのCSSを使用したロードインジケータを作ることができる、またはあなたはすでに利用可能なものを使用することができ、たとえばあなたが単にする必要がhttp://tobiasahlin.com/spinkit/http://loading.io/

1

を使用することができますフラグにアタッチしてv-ifを使用すると、vueリソースを使用している場合、beforeコールバックでloadingフラグをtrueに設定し、再受信後にfalseに設定することができますsponse:

Vueのインスタンス

methods: { 
    loadData() { 
     this.$http.get('/search', { 
     before:() => { 
      this.loading = true; 
     } 
     }).then(response => { 
     // Deal with response 
     }).then(() => { 
      //set loading flag to false 
      this.loading = false; 
     }) 
    } 
    }, 
    data: { 
    loading: false 
    } 

HTML

<div id="app"> 
    <button @click="loadData"> 
    Get Data 
    </button> 

    <!-- Only show if loading is true --> 
    <div v-if="loading" v-cloak> 
    <i class="fa fa-circle-o-notch fa-spin fa-3x fa-fw"></i> 
    <span>Loading...</span> 
    </div> 
</div> 

がここにJSFiddleです:ユーザビリティの便宜上https://jsfiddle.net/hyeycoan/

4

、私はそのを持ってローダーを使用することをお勧めします自身のvuex状態。

  1. これにより、どのコンポーネントからでも制御できるようになります。
  2. 簡単な関数呼び出しで簡単に使用できます。
  3. もちろん、小道具やイベントは避けてください。すべてのAPI呼び出しに使用することが

    1. です:あなたは、この特定のローダーを必要とする場所

    最初に定義しますか?

  4. ブラウザの負荷が高いタスク(ロードされたファイルの処理など)があります。
  5. それとも自然の中で、より具体的なもの(多分、ユーザがログインしようとしているときにのみローダーを表示)

あなたのローダがしっかりとケース1のように任意のコンポーネントに結合されていない場合、それはより多くのSENSになるだろう(あなたがしてApp.vueをVUE-cliを使用している場合)メインVUEファイルにそのような

何かごローダーを保つために:これにより

<template> 
    <div id="app"> 
    <loader></loader> 
    <router-view></router-view> 
    </div> 
</template> 

<script> 
import Loader from './components/shared/loader/Loader' 

export default { 
    name: 'app', 
    components: { 
    Loader 
    } 
} 
</script> 

を、あなたはloader.vueを追加する必要はありません他のすべてのコンポーネントファイルに保存されます。 しかし、まず、使用しているローダコンポーネントとストアを示します。

<template> 
    <div class='loader-container' :class='{"show": show, "hidden": !show}'> 
    <div class="curved-div"> 
     <div class="colour-magic"> 
     <i class='fa fa-circle-o-notch rotate'></i> 
     </div> 
     <div class="loading"> 
     {{ loading }} 
     </div> 
    </div> 
    </div> 
</template> 

<script> 
import { mapGetters } from 'vuex' 
import * as NameSpace from '../../../store/NameSpace' 

export default { 
    data() { 
    return { 
     loading: 'Loading...' 
    } 
    }, 
    computed: { 
    ...mapGetters({ 
     show: NameSpace.GET_LOADER_STATE 
    }) 
    } 
} 
</script> 

<style scoped> 
.loader-container { 
    position: fixed; 
    width: 100%; 
    height: 100%; 
    background: rgba(0,0,0,0.8); 
} 

.curved-div { 
    position: absolute; 
    top: 50%; 
    left: 50%; 
    transform: translateX(-50%); 
    border-radius: .3rem; 
    width: 20rem; 
    padding:1rem; 
    background: white; 
    box-shadow: 0 0 .1rem #fefefe; 
} 

.curved-div > * { 
    display: inline-block; 
} 

.rotate { 
    border-radius: 50%; 
    padding: .5rem; 
    animation-name: rotate; 
    animation-duration: .7s; 
    animation-iteration-count: infinite; 
    animation-delay: 0s; 
} 

.loading { 
    text-align: center; 
    width: 12rem; 
    font-size: 1.8rem; 
} 

.show { 
    visibility: visible; 
    opacity: 1; 
    z-index: 1; 
    transition: opacity 0.5s ease-out, visibility 0.5s ease-out, z-index 0.5s ease-out; 
} 

.hidden { 
    opacity: 0; 
    visibility: hidden; 
    z-index: 0; 
    transition: opacity 0.5s ease-out, visibility 0.5s ease-out, z-index 0.5s ease-out; 
} 

@keyframes rotate { 
    0% { 
    transform: rotateZ(0deg); 
    } 
    100% { 
    transform: rotateZ(360deg); 
    } 
} 

.colour-magic { 
    animation-name: colorMagic; 
    animation-duration: 20s; 
    animation-iteration-count: infinite; 
    animation-delay: 0s; 
} 

@keyframes colorMagic { 
    0% { color: rgb(179,10,10); } 
    10% { color: rgb(227,132,22); } 
    20% { color: rgb(164,153,7); } 
    30% { color: rgb(26,171,19); } 
    40% { color: rgb(19,144,177); } 
    50% { color: rgb(14,16,221); } 
    60% { color: rgb(27,9,98); } 
    70% { color: rgb(58,11,111); } 
    80% { color: rgb(126,14,129); } 
    90% { color: rgb(208,19,121); } 
    100% { color: rgb(198,18,18); } 
} 
</style> 

私はローダーにfont-awesomeを使用しています。

import * as NameSpace from '../NameSpace' 
// you can also use the namespace: true in your store and eliminate the need of NameSpace.js  

const state = { 
    [NameSpace.LOADER_STATE]: false 
} 

const getters = { 
    [NameSpace.GET_LOADER_STATE]: state => { 
    return state[NameSpace.LOADER_STATE] 
    } 
} 

const mutations = { 
    [NameSpace.MUTATE_LOADER_STATE]: (state, payload) => { 
    state[NameSpace.LOADER_STATE] = payload 
    } 
} 

const actions = { 
    [NameSpace.LOADER_SHOW_ACTION]: ({ commit }, payload) => { 
    commit(NameSpace.MUTATE_LOADER_STATE, payload) 
    } 
} 

export default { 
    state, 
    getters, 
    mutations, 
    actions 
} 

使用例:ここで

とが格納され

// This is not a .vue file it is a .js file, therefore a different way of using the store. 
import Vue from 'vue' 
import * as NameSpace from 'src/store/NameSpace' 
import loaderState from 'src/store/modules/loader' 

/** 
* Pass the mutation function to reduce the text length 
* This function can now be used in the api calls to start/stop the loader 
* as the api starts and finishes. 
*/ 
let loaderSwitch = loaderState.mutations[NameSpace.MUTATE_LOADER_STATE].bind(null, loaderState.state) 

login (username, password) { 
    loaderSwitch(true) 
    return new Promise((resolve, reject) => { 
    SomeEndpoint.logIn(username, password, { 
     success (user) { 
     loaderSwitch(false) 
     resolve(user.attributes) 
     }, 
     error (user, error) { 
     loaderSwitch(false) 
     reject(errorHelper(error.code)) 
     } 
    }) 
    }) 

次に、拘わらずログインが使用される成分の、ローダ成分が保たれる必要はありません。

関連する問題