如何在搜索时添加加载图标?(Vue.js 2)

sam*_*toh 3 javascript vue.js vue-component vuejs2

我的组件是这样的:

<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>
Run Code Online (Sandbox Code Playgroud)

当我搜索时,在显示数据之前,我想添加一个加载图标

我怎么能在vue.js 2中做到这一点?

Amr*_*pal 10

出于可用性的考虑,我建议使用具有自己的vuex状态的加载器.

  1. 这将允许您从任何组件控制它.
  2. 您可以通过简单的函数调用轻松使用它.
  3. 自然地避免道具和事件.

首先定义您需要此特定加载器的位置:

  1. 是用于所有api呼叫吗?
  2. 一些浏览器密集型任务(如处理加载的文件).
  3. 或者更具体的东西(可能仅在用户尝试登录时才显示加载程序)

如果你的加载器没有紧密耦合到任何组件,如案例1.那么将你的加载器保存在主vue文件中会更加明智(如果你使用的是vue-cli,那么App.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>
Run Code Online (Sandbox Code Playgroud)

有了这个,您不必在每个其他组件文件中添加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>
Run Code Online (Sandbox Code Playgroud)

请注意,我使用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
}
Run Code Online (Sandbox Code Playgroud)

一个用法示例:

// 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))
      }
    })
  })
Run Code Online (Sandbox Code Playgroud)

现在,无论使用登录的组件如何,都不需要将加载程序组件保留在那里.