299 lines
6.7 KiB
Vue
299 lines
6.7 KiB
Vue
|
|
<!-- PageBottom.vue -->
|
|||
|
|
<template>
|
|||
|
|
<view class="pageBottom" :style="{ position: position, bottom: isSubmit ? '60rpx' : '0' }">
|
|||
|
|
<view class="uni-flex uni-row buttons">
|
|||
|
|
<view class="flex-item " v-for="(item, index) in toolbar" :key="index" style="padding: 1ch;width: 100%;">
|
|||
|
|
<!-- 更多按钮:todo 1.按钮权限控制;2.动态宽度; -->
|
|||
|
|
<!-- type: 'primary' 蓝色(不同终端默认颜色不同),'default' 白色,'warn'红色 如想在多端统一颜色,请改用default,然后自行写样式 -->
|
|||
|
|
<!-- style: 支持自定义样式 -->
|
|||
|
|
<button :type="item.type && ['primary','default','warn'].includes(item.type) ? item.type : 'default'"
|
|||
|
|
@click="handleClick(item,index)" :style="item.style || ''" :loading="buttonStates[index]"
|
|||
|
|
:disabled="buttonStates[index]">
|
|||
|
|
{{ item.label }}{{ item.disable }}
|
|||
|
|
</button>
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
</view>
|
|||
|
|
</template>
|
|||
|
|
|
|||
|
|
<script>
|
|||
|
|
import {
|
|||
|
|
propsToAttrMap
|
|||
|
|
} from '@vue/shared';
|
|||
|
|
|
|||
|
|
export default {
|
|||
|
|
name: 'bottomBtnGroup',
|
|||
|
|
// 接收的 props
|
|||
|
|
props: {
|
|||
|
|
/// 头工具栏
|
|||
|
|
toolbar: {
|
|||
|
|
type: Array,
|
|||
|
|
default () {
|
|||
|
|
return [{
|
|||
|
|
label: "新增",
|
|||
|
|
type: "primary",
|
|||
|
|
event: function(done) {
|
|||
|
|
//方式1: 接收 done 回调 在业务结束时手动触发回调
|
|||
|
|
setTimeout(() => {
|
|||
|
|
console.log("延时5秒 新增方法完成")
|
|||
|
|
done(); //
|
|||
|
|
}, 5000);
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
label: "删除",
|
|||
|
|
type: "default",
|
|||
|
|
event: function(done) {
|
|||
|
|
setTimeout(() => {
|
|||
|
|
console.log("延时5秒 删除方法完成")
|
|||
|
|
done();
|
|||
|
|
}, 5000);
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
label: "取消",
|
|||
|
|
type: "primary",
|
|||
|
|
event: function() {
|
|||
|
|
//方式2:
|
|||
|
|
return new Promise(resolve => {
|
|||
|
|
console.log("取消方法完成")
|
|||
|
|
setTimeout(resolve, 5000);
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
//背景是否是白色
|
|||
|
|
backgroundWhite: {
|
|||
|
|
type: Boolean,
|
|||
|
|
default: false
|
|||
|
|
},
|
|||
|
|
//是否是提交表单的样式
|
|||
|
|
isSubmit: {
|
|||
|
|
type: Boolean,
|
|||
|
|
default: false
|
|||
|
|
},
|
|||
|
|
//按钮是否可点击的状态
|
|||
|
|
disable: {
|
|||
|
|
type: Boolean,
|
|||
|
|
default: false
|
|||
|
|
},
|
|||
|
|
position: {
|
|||
|
|
type: String,
|
|||
|
|
default: 'fixed'
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
created() {
|
|||
|
|
// 初始化每个按钮的loading状态
|
|||
|
|
this.initButtonStates();
|
|||
|
|
},
|
|||
|
|
data() {
|
|||
|
|
return {
|
|||
|
|
loading: false,
|
|||
|
|
// 存储按钮的loading状态(与toolbar对应)
|
|||
|
|
buttonStates: []
|
|||
|
|
|
|||
|
|
};
|
|||
|
|
},
|
|||
|
|
watch: {
|
|||
|
|
// 监听toolbar变化,重新初始化状态(适用于动态更新按钮列表的场景)
|
|||
|
|
toolbar: {
|
|||
|
|
handler() {
|
|||
|
|
this.initButtonStates();
|
|||
|
|
},
|
|||
|
|
deep: true
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 方法
|
|||
|
|
methods: {
|
|||
|
|
// 初始化按钮状态(为每个按钮添加loading属性)
|
|||
|
|
initButtonStates() {
|
|||
|
|
this.toolbar.map((item, index) => {
|
|||
|
|
//this.buttonStates.push(false)//vue3生效
|
|||
|
|
// 响应式更新
|
|||
|
|
this.$set(this.buttonStates, index, false); //vue2生效
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
async handleClick(item, index) {
|
|||
|
|
try {
|
|||
|
|
this.$set(this.buttonStates, index, true);
|
|||
|
|
this.$modal.loading("请等待...")
|
|||
|
|
//方式1:注意:此处约定 item.event() 返回一个Promise 否则loding状态不生效
|
|||
|
|
//return new Promise(resolve => setTimeout(resolve, 5000));
|
|||
|
|
//方式2:把 resolve/reject 作为“完成信号”传给业务函数,像调用方法传递done 方法,在业务处理结后调用
|
|||
|
|
await new Promise((resolve, reject) => {
|
|||
|
|
// 把 resolve/reject 作为“完成信号”传给业务函数
|
|||
|
|
item.event(resolve, reject);
|
|||
|
|
});
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('catch 按钮事件执行出错:', error);
|
|||
|
|
} finally {
|
|||
|
|
// 响应式更新
|
|||
|
|
console.info('finally 按钮事件执行');
|
|||
|
|
this.$set(this.buttonStates, index, false);
|
|||
|
|
this.$modal.closeLoading()
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
</script>
|
|||
|
|
|
|||
|
|
<style scoped lang="scss">
|
|||
|
|
.pageBottom {
|
|||
|
|
left: 0;
|
|||
|
|
bottom: 0;
|
|||
|
|
z-index: 30;
|
|||
|
|
display: flex;
|
|||
|
|
justify-content: center;
|
|||
|
|
align-items: center;
|
|||
|
|
flex-direction: column;
|
|||
|
|
width: 100%;
|
|||
|
|
padding: 20rpx 0 20rpx;
|
|||
|
|
|
|||
|
|
.button {
|
|||
|
|
display: flex;
|
|||
|
|
justify-content: center;
|
|||
|
|
align-items: center;
|
|||
|
|
width: 686rpx;
|
|||
|
|
height: 72rpx;
|
|||
|
|
font-weight: 400;
|
|||
|
|
font-size: 32rpx;
|
|||
|
|
color: #ffffff;
|
|||
|
|
border-radius: 16rpx;
|
|||
|
|
//background: rgb(22, 93, 255);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.backgroundWhite {
|
|||
|
|
background: #fff;
|
|||
|
|
color: #165dff;
|
|||
|
|
border: 2rpx solid rgb(22, 93, 255);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.buttons {
|
|||
|
|
display: flex;
|
|||
|
|
justify-content: center;
|
|||
|
|
width: 100%;
|
|||
|
|
position: fixed;
|
|||
|
|
bottom: 0;
|
|||
|
|
left: 0;
|
|||
|
|
padding: 24rpx 0 60rpx;
|
|||
|
|
background-color: #fff;
|
|||
|
|
//background-color: #165DFF;
|
|||
|
|
|
|||
|
|
.buttonOne {
|
|||
|
|
display: flex;
|
|||
|
|
justify-content: center;
|
|||
|
|
align-items: center;
|
|||
|
|
height: 90rpx;
|
|||
|
|
width: 664rpx;
|
|||
|
|
box-sizing: border-box;
|
|||
|
|
//background: rgb(22, 93, 255);
|
|||
|
|
border-radius: 16rpx;
|
|||
|
|
color: #FFFFFF;
|
|||
|
|
font-weight: 400;
|
|||
|
|
font-size: 32rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.buttonLeft {
|
|||
|
|
display: flex;
|
|||
|
|
justify-content: center;
|
|||
|
|
align-items: center;
|
|||
|
|
height: 90rpx;
|
|||
|
|
width: 332rpx;
|
|||
|
|
box-sizing: border-box;
|
|||
|
|
background: rgb(22, 93, 255);
|
|||
|
|
border-radius: 16rpx;
|
|||
|
|
color: #FFFFFF;
|
|||
|
|
font-weight: 400;
|
|||
|
|
font-size: 32rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.buttonRight {
|
|||
|
|
display: flex;
|
|||
|
|
justify-content: center;
|
|||
|
|
align-items: center;
|
|||
|
|
height: 90rpx;
|
|||
|
|
width: 332rpx;
|
|||
|
|
border-radius: 16rpx;
|
|||
|
|
background: rgb(22, 93, 255);
|
|||
|
|
font-weight: 400;
|
|||
|
|
font-size: 32rpx;
|
|||
|
|
color: #FFFFFF;
|
|||
|
|
margin-left: 22rpx;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.thirdbuttons {
|
|||
|
|
display: flex;
|
|||
|
|
justify-content: center;
|
|||
|
|
width: 100%;
|
|||
|
|
position: fixed;
|
|||
|
|
bottom: 0;
|
|||
|
|
left: 0;
|
|||
|
|
padding: 10rpx 0 60rpx;
|
|||
|
|
background-color: #fff;
|
|||
|
|
|
|||
|
|
.buttonLeft {
|
|||
|
|
display: flex;
|
|||
|
|
justify-content: center;
|
|||
|
|
align-items: center;
|
|||
|
|
height: 72rpx;
|
|||
|
|
width: 232rpx;
|
|||
|
|
box-sizing: border-box;
|
|||
|
|
border: 2rpx solid rgb(22, 93, 255);
|
|||
|
|
border-radius: 16rpx;
|
|||
|
|
background: rgb(255, 255, 255);
|
|||
|
|
color: #165DFF;
|
|||
|
|
font-weight: 400;
|
|||
|
|
font-size: 32rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.buttonMid {
|
|||
|
|
display: flex;
|
|||
|
|
justify-content: center;
|
|||
|
|
align-items: center;
|
|||
|
|
height: 72rpx;
|
|||
|
|
width: 232rpx;
|
|||
|
|
box-sizing: border-box;
|
|||
|
|
border: 2rpx solid rgb(22, 93, 255);
|
|||
|
|
border-radius: 16rpx;
|
|||
|
|
background: rgb(255, 255, 255);
|
|||
|
|
color: #165DFF;
|
|||
|
|
font-weight: 400;
|
|||
|
|
font-size: 32rpx;
|
|||
|
|
margin-left: 10rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.buttonRight {
|
|||
|
|
display: flex;
|
|||
|
|
justify-content: center;
|
|||
|
|
align-items: center;
|
|||
|
|
height: 72rpx;
|
|||
|
|
width: 232rpx;
|
|||
|
|
border-radius: 16rpx;
|
|||
|
|
background: rgb(22, 93, 255);
|
|||
|
|
font-weight: 400;
|
|||
|
|
font-size: 32rpx;
|
|||
|
|
color: #FFFFFF;
|
|||
|
|
margin-left: 10rpx;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.contentWhite {
|
|||
|
|
content: '';
|
|||
|
|
position: fixed;
|
|||
|
|
left: 0;
|
|||
|
|
bottom: 0;
|
|||
|
|
width: 100%;
|
|||
|
|
height: 240rpx;
|
|||
|
|
background: linear-gradient(to bottom,
|
|||
|
|
#f3ece400 0%,
|
|||
|
|
#F2F3F5 100%);
|
|||
|
|
pointer-events: none;
|
|||
|
|
}
|
|||
|
|
</style>
|