本文所涉及代碼全在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時候也更方便。在子組件調用時也很是的簡單,就至關提供了一個接口。
其餘