本文所涉及代码全在vue-cnodehtml
上图是咱们demo项目的总体结构,咱们能够看见在第三级有三个东西router,全局组件,功能组件。其中全局组件和功能组件是脱离于router的,由于这两部分是全部逻辑组件共有的。咱们将他提出来,放在App.vue里面而不是放在router下面的路由组件中,是为了只引用一次而后全局调用。vue
可是,具体的路由逻辑组件须要展示的全局组件内容是不同的,须要功能组件交互的内容也不同,因此须要在不一样的路由逻辑组件中对全局组件和功能组件进行控制。node
本文就是介绍如何经过vuex对全局组件和功能组件进行控制的。git
说是控制,其实就是组件间交互,vue中组件交互有不少方式,咱们这里用vuex。github
咱们将单独创建一个module(doc_state),用来作功能组件和全局组件的功能交互,在module中咱们将初始化功能组件或则全局组件须要的数据,和函数方法等。以下图所示:vue-router
// doc state 须要一些变量来记录文档状态 import { SET_TIP } from '../mutation_types' const state = { tip: { text: '', time: 2000, callback: null } } const mutations = { [SET_TIP] (state, tip) { state.tip = tip } } export default { state, mutations }
这里咱们以tip(提示)组件为例子讲解,全部doc modules在/src/vuex/modules/doc_state
。vuex
而后咱们定义doc_actions定义咱们的action:segmentfault
import * as types from '../mutation_types' export const setTip = ({dispatch}, tip) => { if (!tip.time) tip.time = 2000 // 默认tip展示时间 dispatch(types.SET_TIP, tip) }
actions,会在路由逻辑组件中引用,调用action就能控制咱们的tip组件。app
再把 doc_state挂载到store.js就能够了~ide
import docState from './modules/doc_state' export default new Vuex.Store({ modules: { docState, content, userInfo }, strict: debug, middlewares: debug ? [] : [] })
在咱们的common文件夹里面新建一个tip.vue。他就是咱们的提示信息组件。(路径/src/components/common/tip.vue
)
首先咱们须要获取tip在vuex里面的数据:
vuex: { getters: { tip: ({ docState }) => docState.tip } },
而后就是具体的逻辑了:
data () { return { tipVisible: false } }, watch: { tip: 'tipShow' }, methods: { tipShow () { let self = this self.tipVisible = true setTimeout(function () { self.tipVisible = false if (self.tip.callback) { self.tip.callback() } }, self.tip.time) } }
上面的tipVisible是咱们用来控制控制展现的变量,在template里面:
<template> <div v-if="tipVisible" class="tip"> <div class="tip-wrap"> <p>{{ tip.text }}</p> </div> </div> </template>
tip组件一共作了三件事:
监听vuex获取的tip变量,在tip变量改变时执行tipShow方法。
展现信息
展现时间结束后,执行回调函数(若是有)
上面就完成了tip组件的整套逻辑,最后咱们还须要把tip组件挂在App.vue。
template:
<template> <div id="app"> <cn-header></cn-header> <sidebar></sidebar> <router-view></router-view> <tip></tip> <loading></loading> </div> </template>
js:
import tip from './components/common/tip' export default { components: { tip, }, }
这样咱们就能在全部路由逻辑组件调用了。
拿登陆组件做为例子。
首先咱们须要引入action:
import { setMenu, setTip } from '../../vuex/actions/doc_actions' export default { vuex: { actions: { setTip, setDetail } } }
咱们在登陆出错的时候会给用户提示信息:
this.setBaseInfo(this.access, (res) => { if (res.success) { this.success() } this.setTip({ text: res.msg }) })
只要调用this.setTip
方法就能够了。是否是很简单?组件写好后,后面你们再使用就只需调用这一个方法。
注意
这里须要主要传入回调函数的this的指向。建议这样:
this.setTip({ text: 'lala', callback: () => { this.xxx() } })
箭头函数有个做用就是会绑定它声明地方的this。这样咱们就能够在callback里面调用当前组件的方法了。不用箭头函数,bind一下也是能够的~
你能够发现咱们的组件交互彻底是经过数据去控制的。在搭建功能组件和vuex的module时会复杂一点,可是逻辑更清晰,咱们在debug时候也更方便。在子组件调用时也很是的简单,就至关提供了一个接口。
其余