项目在开发时经常用到确认提示框,为了开发速度,我选择了uniapp
提供的uni.showModal
方法,简单方便,不用额外写标签,但是在项目后期,客户提出原生确认框字体小,不好点,颜色不能跟随页面主色等问题。
翻看官方API可用配置寥寥无几,去插件市场有一个原生插件可以使用,支持Android和iOS,准备安装试试时,发现需要付费,思考一下,好用的话也能接受,考虑到大量页面需要修改,非常耗时,购买以后,其他项目都可以使用,还是很划算的,于是在我准备付费时,又提示我购买这个插件需要绑定某一个项目,其他项目如果要使用还需要重新购买。看到这,我果断放弃了,开始考虑前端替换方案。
项目目前使用了uview 1.0
的UI库,其提供的u-modal
组件,它的UI样式满足需求,可以自定义,但就是不能像原生一样直接通过一个方法调用,非常不方便。
于是我就想对其进行改造能够使用方法调用,并且api和uniapp的showModal保持一致,这样就可以最大化的少改动原来的逻辑了。
方案如下:
1,先在需要使用u-modal
的页面引入组件,通过在class中添加dark
样式来确认该框使用什么主题的颜色
<u-modal class="custom-modal dark" v-model="alertModal.show" :title="alertModal.title" :content="alertModal.content" :show-cancel-button="true" @confirm="alertModal.confirm(true)" @cancel="alertModal.confirm(false)"></u-modal>
2,在APP.vue
中加入自定义的主题样式,为了减少调用api时传入的参数,我直接使用了全局样式对组件样式进行覆盖,通过class类名进行作用域限定
// 自定义模态框自定义样式
.custom-modal.dark {
background-color: #19073b;
.u-model {
background-color: #19073b;
}
.u-model__title,.u-model__content,.u-model__content__message,.u-model__footer {
background-color: #19073b;
color: #fff;
}
.u-model__footer__button {
color: #fff !important;
&:last-child {
color: yellow !important;
}
}
}
3,在main.js
文件中全局注册该确认框所需的data
和methods
方法,为了减少工作量,利用了mixin
,虽然官方不建议使用。本来调用方法名要使用showModal
,但是提示我该方法已经被注册过了,于是在方法名前面加了一个$
//全局封装modal框,api模仿uni.showModal
//样式在APP.vue中
Vue.mixin({
data() {
return {
alertModal: {
show: false,
title: "温馨提示",
content: "",
confirm: () => {}
}
}
},
methods: {
$showModal(opts) {
const {success, ...rest} = opts;
Object.keys(rest).forEach(key => {
this.alertModal[key] = opts[key];
});
this.alertModal.confirm = (flag) => {
let result = flag ? {confirm: true, cancel: false} : {confirm: false, cancel: true};
success && success(result);
}
this.alertModal.show = true;
}
}
});
4,接下来就是批量替换页面中的调用部分了,全局搜索uni.showModal
,修改为this.$showModal
就可以了
this.$showModal({
title: '温馨提示',
content: '',
success: (res) => {
if (res.confirm) {
//console.log('用户点击确认');
} else if (res.cancel) {
//console.log('用户点击取消');
}
}
});