Weex 動(dòng)態(tài)Modal設(shè)計(jì)

Weex 動(dòng)態(tài)Modal設(shè)計(jì)

我們在項(xiàng)目中使用了各種自定義的對(duì)話框蜡豹、彈出框等控件,其中各種控件都是在各自的頁面中彈出久锥,其中最大的問題就是在tabbar中子頁面彈出的modal不能顯示全屏。本文的目的即是設(shè)計(jì)一個(gè)動(dòng)態(tài)的Modal放在tabbar外面,通過與子頁面的調(diào)用方法來開啟對(duì)應(yīng)的動(dòng)態(tài)組件听诸。

構(gòu)建動(dòng)態(tài)組件

Weex中用的組件實(shí)際是使用Vue.js生成的代碼,由于Vue 2.0之后的代碼都是預(yù)編譯的蚕泽,以前使用動(dòng)態(tài)template的方法已經(jīng)不適用晌梨,能構(gòu)建動(dòng)態(tài)組件的方法只有<component>以及render方法創(chuàng)建, 本文暫時(shí)先采用<component>來實(shí)現(xiàn)须妻, 關(guān)于更多的<component>的知識(shí)可以參考Vue動(dòng)態(tài)組件文檔仔蝌。

最基本的動(dòng)態(tài)組件(v-modal.vue)如下:

<template>
    <div class="cModal" append="tree">
        <component v-bind:is="modalCurrentView"></component>
    </div>
</template>

<style>
    .cModal{
        width: 750;
        background-color: transparent;
        display: flex;
        justify-content: center;
        align-items: center;
        position: absolute;
        left: 0;
        right: 0;
        top: 0;
        bottom: 0;
    }
</style>

<script>
    module.exports = {
        computed:{
            modalCurrentView() {
                return this.$store.state.modalCurrentView
            }
        },
        components:{
            "pop-call"      : require("../module/personal/mainpage/v-pop-call.vue"),
            "pop-head"      : require("../module/personal/mainpage/v-pop-head.vue"),
            "pop-version"   : require("../module/personal/mainpage/v-pop-version.vue"),
            "action-sheet"  : require("../manage/camera/action_sheet/v-action-sheet.vue"),
        }
    }
</script>

<component>主要是通過動(dòng)態(tài)修改is綁定的modalCurrentView組件來進(jìn)行切換,可以用此方法來實(shí)現(xiàn)類似tabbar切換之類的效果荒吏。

其中我們的數(shù)據(jù)采用的是Vuex進(jìn)行管理敛惊,也就是存儲(chǔ)在store.js文件中:

import Vuex from 'vuex'

// Vuex is auto installed on the web
if (WXEnvironment.platform !== 'Web') {
  Vue.use(Vuex)
}

var store = new Vuex.Store({
  state:{
      modalIsShow:false,
      modalCurrentView:"pop-call"
  },
  mutations:{
      CHANGE_MODAL_SHOW (state, isShow) {
          state.modalIsShow = isShow
      },
      CHANGE_MODAL_VIEW (state, view) {
          state.modalCurrentView = view
      }
  },

  actions:{
      changeModalShow(context, state) {
          context.commit("CHANGE_MODAL_SHOW", state);
      },
      changeModalView(context, view) {
          context.commit("CHANGE_MODAL_VIEW", view);
      }
  }
})

export default store

可以從store.js中看出,我們可以用changeModalShow方法來控制Modal的顯示和隱藏绰更,用changeModalView方法可以控制切換成那一個(gè)組件豆混,不過調(diào)用store的方法顯得有些麻煩,而且在WebStorm上沒有任何提示动知,我們可以在其中再次封裝一個(gè)modal.js來進(jìn)行調(diào)用:

import store from './store.js'
import Vue from 'vue'

export default {
    closeModal () {
        store.dispatch("changeModalShow", false)
    },
    openModal (view) {
        store.dispatch("changeModalView", view);
        store.dispatch("changeModalShow", true)
    },
}

至此一個(gè)簡單的動(dòng)態(tài)modal架構(gòu)就出來了皿伺, 我們只需要在最外層的頁面增加此動(dòng)態(tài)控件即可:

<template>
    <div class="cRoot" @androidback="onClickAndroidBack"
                       @viewappear="viewappear"
                       @viewdisappear="viewdisappear">
        ......
        // 添加動(dòng)態(tài)modal
        <modal v-if="modalIsShow"></modal>
    </div>
</template>

<script>
    var nav = weex.requireModule('event');
    var storage = weex.requireModule("storage");
    module.exports = {
        ......
        components:{
            ......
            "modal"         : require("./v-modal.vue")
        },
        computed:{
            modalIsShow () {
                return this.$store.state.modalIsShow
            }
        }
    }
</script>

我們需要調(diào)用顯示modal就可以使用:

import vModal from '../modal.js';
vModal.openModal("pop-head");   //其中"pop-head"是我們再v-modal.vue文件中引入的components;
vModal.closeModal();            //需要關(guān)閉的時(shí)候盒粮,只需要調(diào)用此方法即可

組件之間傳值

Modal的顯示和隱藏都沒有問題了鸵鸥,但是還有一個(gè)問題就是封裝的組件點(diǎn)擊事件是直接往上傳遞,也就是傳到動(dòng)態(tài)的modal后就直接傳到最外面的頁面了丹皱,類似tabbar子頁面就不會(huì)接收到事件妒穴。此時(shí)需要我們使用非父子關(guān)系之間的傳值,簡單的方法有兩種摊崭, 一種是通過Vuex來實(shí)現(xiàn)讼油, 另一種就是使用Vue組件通信, 因?yàn)槲覀兌x了單獨(dú)的modal.js呢簸,用第一種方法矮台,調(diào)用modal時(shí)還要額外多引入文件,因此我們采用第二種方法根时。

Vue非父子關(guān)系之間的通信非常簡單瘦赫,只需要在modal.js加入幾行代碼即可:

import store from './store.js'
import Vue from 'vue'

export default {
    eventBus:new Vue({}),    //定義一個(gè)通用的Vue對(duì)象進(jìn)行通信
    closeModal () {
        store.dispatch("changeModalShow", false)
    },
    openModal (view) {
        store.dispatch("changeModalView", view);
        store.dispatch("changeModalShow", true)
    },
}

不過我們原來的組件點(diǎn)擊的時(shí)候不再采用原來的this.$emit("eventName", eventData);,因?yàn)榇朔椒ㄖ粫?huì)冒泡到最外面的頁面蛤迎, 而傳入不到調(diào)用的頁面确虱;應(yīng)該改用如下的方法:

import vModal from '../modal.js'

vModal.eventBus.$emit("eventName", eventData);

而接收事件的組件可以mounted方法中進(jìn)行監(jiān)聽:

mounted:function(){
    var that= this;
    vModal.eventBus.$on("eventName", (eventData)=> {

    });
},

通過此方法, 我們就可以在動(dòng)態(tài)modal包括的組件和調(diào)用動(dòng)態(tài)modal的組件之間建立了聯(lián)系替裆。

動(dòng)態(tài)組件的參數(shù)傳遞

動(dòng)態(tài)modal還有一個(gè)很大的問題校辩,就是包含的組件如果需要傳遞參數(shù)窘问,怎么辦呢?

我們首先定義一個(gè)統(tǒng)一的變量作為動(dòng)態(tài)modal的傳入?yún)?shù)宜咒, 在store.js中進(jìn)行修改惠赫,加入?yún)?shù):

var store = new Vuex.Store({
  state:{
      modalIsShow:false,
      modalCurrentView:"pop-call",
      modalData:{}
  },
  mutations:{
      ...
      CHANGE_MODAL_DATA (state, data) {
          state.modalData = data
      }
  },

  actions:{
      ...
       changeModalData(context, data) {
          context.commit("CHANGE_MODAL_DATA", data);
      }
  }
})
export default store

而在定義的modal.js中修改openModal方法:

openModal (view, data) {
    store.dispatch("changeModalData", data);
    store.dispatch("changeModalView", view);
    store.dispatch("changeModalShow", true)
},

定義的modalData可以通過<component>的參數(shù)傳入

<template>
    <div class="cModal" append="tree">
        <component v-bind:is="modalCurrentView" :modalData="modalData"></component>
    </div>
</template>

......

<script>
    import Vue from 'vue'
    module.exports = {
        computed:{
            modalCurrentView() {
                return this.$store.state.modalCurrentView
            },
            modalData() {
                let data = this.$store.state.modalData;
            }
        },
        ......
    }
</script>

在自定義的彈出顯示的組件內(nèi)容中我們可以使用props來接收這些參數(shù):

module.exports = {
        props:{
                modalData:{default:{}}
        },
}

不過用此方法傳遞的參數(shù),對(duì)子組件的修改比較多荧呐, 更好的方法是使用render函數(shù)來動(dòng)態(tài)構(gòu)建一個(gè)組件, 通過修改控件的tag來實(shí)現(xiàn)纸镊,不過在實(shí)際使用的時(shí)候碰到了一些問題倍阐,暫時(shí)先用這種不太優(yōu)雅的方式實(shí)現(xiàn),后續(xù)再進(jìn)行改進(jìn)吧逗威。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末峰搪,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子凯旭,更是在濱河造成了極大的恐慌概耻,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,723評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件罐呼,死亡現(xiàn)場離奇詭異鞠柄,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)嫉柴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門厌杜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人计螺,你說我怎么就攤上這事夯尽。” “怎么了登馒?”我有些...
    開封第一講書人閱讀 152,998評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵匙握,是天一觀的道長。 經(jīng)常有香客問我陈轿,道長圈纺,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,323評(píng)論 1 279
  • 正文 為了忘掉前任麦射,我火速辦了婚禮赠堵,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘法褥。我一直安慰自己茫叭,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,355評(píng)論 5 374
  • 文/花漫 我一把揭開白布半等。 她就那樣靜靜地躺著揍愁,像睡著了一般呐萨。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上莽囤,一...
    開封第一講書人閱讀 49,079評(píng)論 1 285
  • 那天谬擦,我揣著相機(jī)與錄音,去河邊找鬼朽缎。 笑死惨远,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的话肖。 我是一名探鬼主播北秽,決...
    沈念sama閱讀 38,389評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼最筒!你這毒婦竟也來了贺氓?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,019評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤床蜘,失蹤者是張志新(化名)和其女友劉穎辙培,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體邢锯,經(jīng)...
    沈念sama閱讀 43,519評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡扬蕊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,971評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了丹擎。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片厨相。...
    茶點(diǎn)故事閱讀 38,100評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖鸥鹉,靈堂內(nèi)的尸體忽然破棺而出蛮穿,到底是詐尸還是另有隱情,我是刑警寧澤毁渗,帶...
    沈念sama閱讀 33,738評(píng)論 4 324
  • 正文 年R本政府宣布践磅,位于F島的核電站,受9級(jí)特大地震影響灸异,放射性物質(zhì)發(fā)生泄漏府适。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,293評(píng)論 3 307
  • 文/蒙蒙 一肺樟、第九天 我趴在偏房一處隱蔽的房頂上張望檐春。 院中可真熱鬧,春花似錦么伯、人聲如沸疟暖。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽俐巴。三九已至骨望,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間欣舵,已是汗流浹背擎鸠。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評(píng)論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留缘圈,地道東北人劣光。 一個(gè)月前我還...
    沈念sama閱讀 45,547評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像糟把,于是被迫代替她去往敵國和親绢涡。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,834評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容