Weex 动态Modal设计
来源:互联网 发布:淘宝下架是什么意思 编辑:程序博客网 时间:2024/06/09 13:55
Weex 动态Modal设计
我们在项目中使用了各种自定义的对话框、弹出框等控件,其中各种控件都是在各自的页面中弹出,其中最大的问题就是在tabbar中子页面弹出的modal不能显示全屏。本文的目的即是设计一个动态的Modal放在tabbar外面,通过与子页面的调用方法来开启对应的动态组件。
构建动态组件
Weex中用的组件实际是使用Vue.js生成的代码,由于Vue 2.0之后的代码都是预编译的,以前使用动态template的方法已经不适用,能构建动态组件的方法只有<component>
以及render
方法创建, 本文暂时先采用<component>
来实现, 关于更多的<component>
的知识可以参考Vue动态组件文档。
最基本的动态组件(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>
主要是通过动态修改is绑定的modalCurrentView
组件来进行切换,可以用此方法来实现类似tabbar切换之类的效果。
其中我们的数据采用的是Vuex进行管理,也就是存储在store.js文件中:
import Vuex from 'vuex'// Vuex is auto installed on the webif (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
方法可以控制切换成那一个组件,不过调用store的方法显得有些麻烦,而且在WebStorm上没有任何提示,我们可以在其中再次封装一个modal.js来进行调用:
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) },}
至此一个简单的动态modal架构就出来了, 我们只需要在最外层的页面增加此动态控件即可:
<template> <div class="cRoot" @androidback="onClickAndroidBack" @viewappear="viewappear" @viewdisappear="viewdisappear"> ...... // 添加动态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>
我们需要调用显示modal就可以使用:
import vModal from '../modal.js';vModal.openModal("pop-head"); //其中"pop-head"是我们再v-modal.vue文件中引入的components;vModal.closeModal(); //需要关闭的时候,只需要调用此方法即可
组件之间传值
Modal的显示和隐藏都没有问题了,但是还有一个问题就是封装的组件点击事件是直接往上传递,也就是传到动态的modal后就直接传到最外面的页面了,类似tabbar子页面就不会接收到事件。此时需要我们使用非父子关系之间的传值,简单的方法有两种, 一种是通过Vuex来实现, 另一种就是使用Vue组件通信, 因为我们定义了单独的modal.js,用第一种方法,调用modal时还要额外多引入文件,因此我们采用第二种方法。
Vue非父子关系之间的通信非常简单,只需要在modal.js加入几行代码即可:
import store from './store.js'import Vue from 'vue'export default { eventBus:new Vue({}), //定义一个通用的Vue对象进行通信 closeModal () { store.dispatch("changeModalShow", false) }, openModal (view) { store.dispatch("changeModalView", view); store.dispatch("changeModalShow", true) },}
不过我们原来的组件点击的时候不再采用原来的this.$emit("eventName", eventData);
,因为此方法只会冒泡到最外面的页面, 而传入不到调用的页面;应该改用如下的方法:
import vModal from '../modal.js'vModal.eventBus.$emit("eventName", eventData);
而接收事件的组件可以mounted
方法中进行监听:
mounted:function(){ var that= this; vModal.eventBus.$on("eventName", (eventData)=> { });},
通过此方法, 我们就可以在动态modal包括的组件和调用动态modal的组件之间建立了联系。
动态组件的参数传递
动态modal还有一个很大的问题,就是包含的组件如果需要传递参数,怎么办呢?
我们首先定义一个统一的变量作为动态modal的传入参数, 在store.js中进行修改,加入参数:
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>
的参数传入
<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>
在自定义的弹出显示的组件内容中我们可以使用props来接收这些参数:
module.exports = { props:{ modalData:{default:{}} },}
不过用此方法传递的参数,对子组件的修改比较多, 更好的方法是使用render函数来动态构建一个组件, 通过修改控件的tag来实现,不过在实际使用的时候碰到了一些问题,暂时先用这种不太优雅的方式实现,后续再进行改进吧。
有什么问题可以访问我的简书或者在CSDN博瑞立方终端组中留言交流。
- Weex 动态Modal设计
- Weex Android SDK源码分析之Module(modal)
- Weex
- weex
- WEEX
- weex
- 扩展bootstrap的modal模态框-动态添加modal框-弹出多个modal框
- Modal
- Modal
- modal
- modal
- modal
- 客户端动态化系列之——Weex
- bootstrap 动态添加modal,隐藏后背景仍然残留的问题 bootstrap-modal-backdrop-remaining
- Bootstrap如何弹出modal窗,并动态传值?
- 省市区域modal模态框设计(项目总结1)
- Weex——关于移动端动态性的思考、实现和未来
- 深度揭秘阿里移动端高性能动态化方案Weex
- Linux C/C++开发环境配置相关
- VC6.0 不能断点调试的解决方法 VC6.0没有debug模式
- lucene源码-实例化indexsearch
- zepto.js自定义打包集成其它模块构建流程
- 文章标题
- Weex 动态Modal设计
- Linux清屏
- leetcode 368. Largest Divisible Subset
- Codeforces Round #367 (Div. 2) D Vasiliy's Multiset(01Trie)
- java注解:学习注解的好处和JDK提供的三种基本注解
- SSM框架搭建详细解析
- 2017年总结
- C语言char*字符串数组和unsigned char[]数组的相互转换
- 卷积