面试题答案
一键面试实现思路
- 创建加载动画组件:在Vue组件中创建一个加载动画的组件,比如使用CSS动画或SVG来展示加载效果。
- Axios拦截器:利用Axios的请求拦截器和响应拦截器。请求拦截器在请求发起时触发,设置加载动画显示的状态;响应拦截器在请求结束(无论成功或失败)时触发,设置加载动画隐藏的状态。
- Vuex状态管理(可选但推荐):如果项目较为复杂,可以使用Vuex来管理加载动画的显示和隐藏状态,便于在不同组件中共享和使用该状态。
关键代码示例
- 创建加载动画组件
Loading.vue
<template>
<div v-if="isLoading" class="loading-container">
<div class="loading-spinner"></div>
</div>
</template>
<script>
export default {
data() {
return {
isLoading: false
};
}
};
</script>
<style scoped>
.loading-container {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
z-index: 9999;
}
.loading-spinner {
width: 40px;
height: 40px;
border: 4px solid rgba(0, 123, 255, 0.6);
border-top-color: #007bff;
border-radius: 50%;
animation: spin 1s ease-in-out infinite;
-webkit-animation: spin 1s ease-in-out infinite;
}
@keyframes spin {
to {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
</style>
- 在
main.js
中配置Axios拦截器
import Vue from 'vue';
import axios from 'axios';
import Loading from './components/Loading.vue';
// 创建Vue实例用于访问Vuex等
const app = new Vue();
axios.interceptors.request.use(config => {
app.$root.$emit('showLoading');
return config;
}, error => {
app.$root.$emit('hideLoading');
return Promise.reject(error);
});
axios.interceptors.response.use(response => {
app.$root.$emit('hideLoading');
return response;
}, error => {
app.$root.$emit('hideLoading');
return Promise.reject(error);
});
// 在Vue根实例中监听事件来控制加载动画
Vue.prototype.$on('showLoading', () => {
Loading.isLoading = true;
});
Vue.prototype.$on('hideLoading', () => {
Loading.isLoading = false;
});
- 在
App.vue
中引入加载动画组件
<template>
<div id="app">
<Loading />
<!-- 其他组件内容 -->
</div>
</template>
<script>
import Loading from './components/Loading.vue';
export default {
components: {
Loading
}
};
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
如果使用Vuex,实现会略有不同:
- 在
store.js
中定义加载动画状态
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
export default new Vuex.Store({
state: {
isLoading: false
},
mutations: {
setLoading(state, status) {
state.isLoading = status;
}
},
actions: {
showLoading({ commit }) {
commit('setLoading', true);
},
hideLoading({ commit }) {
commit('setLoading', false);
}
}
});
- 在
main.js
中配置Axios拦截器
import Vue from 'vue';
import axios from 'axios';
import store from './store';
axios.interceptors.request.use(config => {
store.dispatch('showLoading');
return config;
}, error => {
store.dispatch('hideLoading');
return Promise.reject(error);
});
axios.interceptors.response.use(response => {
store.dispatch('hideLoading');
return response;
}, error => {
store.dispatch('hideLoading');
return Promise.reject(error);
});
- 在
Loading.vue
中使用Vuex状态
<template>
<div v-if="isLoading" class="loading-container">
<div class="loading-spinner"></div>
</div>
</template>
<script>
import { mapState } from 'vuex';
export default {
computed: {
...mapState(['isLoading'])
}
};
</script>
<style scoped>
// 样式同之前
</style>