场景是在项目中很多地方都需要用到相同的函数, 例如
- this.$message({
- type: 'success',
- message: '提示语'
- })
如果出现次数过多, 会造成书写麻烦和代码复杂的情况.
解决思路: 首先对函数进行抽象封装, 封装后利用 vue 的 mixin 将其注入到各个 vue 中.
因为这里的函数是大部分组件中都可能用到的, 固利用 vue 的全局混合.
新建一个 global 文件:
- const globalMethods = {
- methods: {
- tipSuccess(msg) {
- this.$message({
- type: 'success',
- message: msg
- })
- },
- tipError(msg) {
- this.$message({
- type: 'error',
- message: msg
- })
- },
- },
- }
- export {
- globalMethods
- }
在新建 Vue 的原型中利用 mixin 混入 (main.JS 中, 创建 vue 实例前):
Vue.mixin(globalMethods)
任意 vue 中使用:
this.tipSuccess('成功提示')
利用 Vuex 实现全局请求加载动画
场景是希望在所有请求的时候添加上加载动画.
首先遇到的问题是, 加载动画应该挂载在哪里? 某个组件中? 这里需要根据具体的场景看, 如果你的是多组件多页面, 那么每一个全新的页面都需要添加一个加载动画, 如果是一个单页面应用, 可以建议添加在最外层的父组件上. 例如本项目中的页面结构:
上方导航栏是在 main.vue 文件中
下方是整体一个 retouer-view, 因此我们如果需要在所有页面中添加加载动画, 可以直接写在 main.vue 中
- // 利用 elementUi 的 v-loading
- <template>
- <div class="main" v-loading="this.$store.state.isRequesting">
- <h3>
- <i class="el-icon-menu"> </i> 舜新建材公司库存管理系统 </h3>
- <keep-alive>
- <router-view></router-view>
- </keep-alive>
- </div>
- </div>
- </template>
上方代码中用到的 this.$store.state.isRequesting 就是我们实现全局请求添加加载动画的核心方法: 利用 vuex.
首先在新建 store 文件夹, index.JS 文件:
- import Vue from 'vue'
- import Vuex from 'vuex'
- Vue.use(Vuex)
- const state = {
- isRequesting: false,
- isError: false
- }
- const mutations = {
- saveIsRequesting(state, isRequesting) {
- state.isRequesting = isRequesting;
- },
- saveIsError(state, isError) {
- state.isError = isError;
- },
- }
- const actions = {
- setIsRequesting({
- commit
- }, isRequesting) {
- commit('saveIsRequesting', isRequesting);
- },
- setIsError({
- commit
- }, isError) {
- commit('saveIsError', isError);
- },
- }
- export default new Vuex.Store({
- state,
- actions,
- mutations
- })
上方代码的作用是新建了一个 vuex 的 store, 并且添加了两个变量 isRequestin 和 isError, 分别用来标记是否需要提示正在请求 (加载动画), 和是否请求出错 (提示服务器错误), 请求成功的提示场景比较多, 所以需要在代码中自己实现.
记得在新建 Vue 实例的时候注入 store:
- new Vue({
- el: '#app',
- router,
- store,
- components: {
- App
- },
- template: '<App/>'
- })
然后需要在自己封装的请求函数中添加对这两个变量的控制, 本项目中是封装的 fetch.JS:
- // 关键代码
- import store from '../store/index'
- try {
- // 在请求开始和结束时改变状态
- store.dispatch('setIsRequesting', true)
- const response = await fetch(url, requestConfig);
- const responseData = await response.JSON();
- store.dispatch('setIsRequesting', false)
- return responseData;
- } catch (err) {
- // 错误时改变状态
- store.dispatch('setIsRequesting', false)
- store.dispatch('setIsError', true)
- throw new Error(err)
- }
然后就可以在 main 中实现自动提示了.
自动加载动画可以依赖 ElementUI 用 v-loading 实现:
<pre class="hljs ini">v-loading="this.$store.state.isRequesting"</pre>
服务器错误提示需要自己手动实现, 这里利用了 vue 的 computed 和 watch 两个钩子函数:
- computed: {
- isError() {
- return this.$store.state.isError;
- }
- },
- watch: {
- isError(newVal) {
- if (newVal) {
- this.tipError('服务器出错啦 T.T');
- // 显示完后重置为 false
- this.$store.dispatch('setIsError', false);
- }
- }
- }
至此, 我们的请求提示封装就完成了, 最终实现的效果是在任何请求发出时都会自动出现加载动画, 并且在请求出错时提示服务器错误, 不需要在每一个请求的时候都 try..catch 了.
兄弟组件通信
场景是两个不相关的组件需要通信, 因为不是父子组件关系固不能利用 this.$emit 来传递.
固利用了 vue 提供的事件 bus.
新建一个 bus.JS 文件
- import Vue from 'vue';
- export default new Vue();
在需要监听事件的组件中:
- import Bus from '../util/bus';
- Bus.$on('eventName', this.handle);
触发事件的组件中:
- import Bus from '../util/bus';
- Bus.$emit('refreshGoodList');</pre>
对前端技术感兴趣的同学, 欢迎加入 QQ 群: 838051760, 不管你是小白还是大牛我都欢迎, 还有我整理的一套高效率学习路线和教程与您免费分享, 同时每天更新视频资料.
来源: http://www.qdfuns.com/article/51070/aebf9e83b0885e00e77e9653bf4ebef4.html