最近做一个需求,产品要求一个发票列表可以多选发送到邮箱,而且分页加载,并且按照月份排序,滑动的时候月份的部分吸顶,先看看设计图吧。
由于整个项目都是基于vue开发的,项目里有的页面是用vux中的scroll组件实现分页的,看文档里这个组件都已经不维护了,所以用的是vue-infinite-scroll组件,分页就不用多说了。
这里有个多选与全选,如果点了全选,这一页的30条数据被选中,然后滑动翻页了,又出来30条数据,默认没选中,那么这个时候全选就不勾选了,这一块的逻辑都是可以在computed中完成的。其实做这个博客记载的,主要是记录一下多个标题滑动吸顶的功能,最开始就想着直接用以前用过的position: sticky;的,结果发现不行,就想着是不是之前是只有一个需要吸顶的,所以可以做到,现在这个需求有多个标题需要吸顶所以不行了?后来又想着怎么去取每个日期的距离顶部的scrollTop,为零了就把position改成fixed,如果只有一个头部吸顶,这样完全是可行的,document.querySelector('#searchBar').offsetTop直接拿到选中元素的头部的距离,然后window.addEventListener('scroll', this.handleScroll)绑定一个scroll事件去监听,不过querySelector只会返回第一个对象,也没办法取到很多个不同的。然后看到了一篇关于position: sticky;的元素的博客,如果元素sticky了,那么它的父元素的visibility需要是visible,我一看自己页面里面写的父元素的visibility果然是hidden的,所以导致了不能吸顶。
其实position: sticky就可以简单粗暴的解决吸顶的需求,而且兼容性还不错,不过又有新的幺蛾子,后面吸顶的日期会前面的盖住,直接出现的就是多个日期重叠了,加个z-index就行了吧,列表是个循环,每个日期部分的z-index都可以根据自己的index来动态设置保证比前面的高,不过设计图里的日期背景色是灰色的,吸顶了之后是白色的,要想遮住前面的只能给日期设置背景色灰色,就导致了吸顶后日期有一点点小的灰色的背景,跟产品沟通后,暂时这样来吧,只是以后最好需要吸顶的部分背景色最好跟头部保持一致,这样体验就更好了。废话扯了这么多,还是上代码吧。
<template>
<!-- -->
<div id="MyInvoice" class="z_footer_hide" :class="{'z_mini_hide':Browser.miniProgram}">
<div class="g_layout_bd">
<div class="m_invoice_wrap">
<div class="m_invoice_hd">
<span :class="{'filter_checked':filterChecked}" @click="filterClick">筛选</span>
<img class="filter_img" :class="{'filter_checked':filterChecked}" @click="filterClick" src="../../../../static/images/Settings/invoiceManagement/filter.png" alt="">
<img class="filter_checked_img" :class="{'filter_checked':filterChecked}" @click="filterClick" src="../../../../static/images/Settings/invoiceManagement/filter_checked.png" alt="">
</div>
<div class="m_invoice_bd">
<div class="invoice_list" v-show="!isShowFirstLoading && invoiceList && invoiceTotalCount > 0"
v-infinite-scroll="loadMore" infinite-scroll-distance="80">
<!-- 发票列表 -->
<div class="invoice_item_list">
<div class="invoice_item" v-for="(item, index) in invoiceList" :key="index" :class="{'invoice_item_title': item.objectType==1}" :style="{zIndex:item.objectType==1?parseInt(11+index):''}">
<span class="invoice_time" v-if="item.objectType==1">{{item.groupTitle}}</span>
<div class="invoice_content" v-if="item.objectType==2">
<check-icon slot="icon" v-if="isChoose" class="u_single_checked" :value="item.isChecked"
@update:value="onClickItemChecked($event, item)"></check-icon>
<div class="invoice_box">
<div class="attachCreateAt">{{item.attachCreateAt}}</div>
<div class="attachNo">发票号码:{{item.attachNo}}</div>
<div class="attachPrice">
<span class="blueFont" v-if="item.invoiceType===0">{{item.price}}<i>元</i></span>
<span class="redFont" v-if="item.invoiceType===1">{{item.price}}<i>元</i></span>
<span class="check_invoiceBtn" @click="invoicePreview(item.attachId)">查看发票</span>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 暂无发票信息 -->
<div class="m_invoice_empty" v-if="!isShowFirstLoading && invoiceTotalCount == 0 && noInvoice">
<div class="u_empty_img">
<img src="../../../../static/images/coin/norecordof_white.png" />暂无发票信息
</div>
</div>
<!-- 加载更多 -->
<p class="u_load_more" v-if="!isShowFirstLoading && nextPage">
<i class='weui-loading'></i>正在加载更多</p>
<div class="to_bottom_show" v-if="!isShowFirstLoading && !nextPage && invoiceTotalCount > 0">
<divider class="m_divider">没有更多了</divider>
</div>
</div>
<div class="m_invoice_ft" v-if="invoiceTotalCount > 0">
<div class="m_invoice_foot_hd" v-if="isChoose">
<check-icon :value.sync="isCheckedAll" @click.native="onClickAllCheckedGoods">全选</check-icon>
<p>已选中<span class="total_num">{{checkedCount}}</span>张 汇总金额: <span class="total_price"><i class="yen">¥</i>{{checkedTotalPrice}}</span></p>
</div>
<div class="m_invoice_foot_ft">
<div v-if="isChoose" class="bottom_btn">
<span class="cancelSend" @click="cancelSend">取消</span>
<span class="confirmSend" :class="{'noCheckInvoice':checkedInvoiceList.length==0}" @click="confirmSend">发送至邮箱</span>
</div>
<div v-else class="sendToEmail" @click="chooseInvoice">发送至邮箱</div>
</div>
</div>
<div class="eyui-gotopbtn" @click="onClickScrollToTop" v-if="!isChoose && isShowScrollTop">
<a href="javascript:;" class="iconfont icon-zhiding"></a>
</div>
</div>
</div>
<!-- 弹出层:加载中 -->
<div v-transfer-dom>
<!-- 页面首次加载进度条 -->
<model-loading v-if="isShowFirstLoading"></model-loading>
</div>
<!-- 筛选弹出层 -->
<div v-transfer-dom>
<popup v-model="showfilterpop" position="top">
<div class="filterpop">
<div class="filterpop_hd" @click="showfilterpop=false">
<span>筛选</span>
<img class="filter_img" src="../../../../static/images/Settings/invoiceManagement/filter.png" alt="">
</div>
<div class="filterpop_bd">
<div class="filter_title">开票时间</div>
<div class="dateTimeBox">
<x-button class="dateTimeBtn" :class="{'chosenTime':choosenStartTime}" @click.native="showStartTime" :text="startTime"></x-button>
<img class="dateTime_arrow" :class="{'arrowRotate':arrowRotateStartTime}" src="../../../../static/images/Settings/invoiceManagement/arrow_up.png" alt="">
</div>
至
<div class="dateTimeBox">
<x-button class="dateTimeBtn" :class="{'chosenTime':choosenEndTime}" @click.native="showEndTime" :text="endTime"></x-button>
<img class="dateTime_arrow" :class="{'arrowRotate':arrowRotateEndTime}" src="../../../../static/images/Settings/invoiceManagement/arrow_up.png" alt="">
</div>
<div class="filter_title">发票类型</div>
<div>
<span class="invoiceType" :class="{'chosenType':chosenType0}" @click="chooseInvoiceType(0)">电子普通发票</span>
<span class="invoiceType" :class="{'chosenType':chosenType1}" @click="chooseInvoiceType(1)">红字普通发票</span>
</div>
</div>
<div class="filterpop_ft">
<div class="reset_btn" @click="resetFilter">重置</div>
<div class="confirm_btn" @click="confirmFilter">确定</div>
</div>
</div>
</popup>
</div>
<!-- 弹出层:加载中 -->
<div v-transfer-dom>
<popup v-model="isshowEmails" :height="showEmailsHeight" position="bottom" class="invoicelayer" :hide-on-blur="false">
<popup-header right-text='' title="填写邮箱地址" @on-click-right="isshowEmails = false"></popup-header>
<div class="invoiceEmail">
<div class="invoiceInput">
<input v-model="emailsValue" class="int-type" placeholder="请填写邮箱地址" type="text" ref="inputFiled1" @keyup="checkemaillist" maxlength="50">
<span @click="clearInputValue">
<icon type="clear" class="icon-right" v-if="emailsValue!=''" style="color:#999"></icon>
</span>
</div>
<div class="warmtext" ref="emailWarn">请输入正确的邮箱地址</div>
<div class="maillist" v-if="isShowlist">
<ul>
<li v-for="(item ,index) in emaliList" :key="index" @click="listItem(index)">{{item}}</li>
</ul>
</div>
<div class="constract-send-to">
<div class="bottomBtn">
<div class="sendBtn">
<button @click="onclicksendemail">发送至邮箱</button>
</div>
</div>
</div>
</div>
</popup>
</div>
</div>
</template>
<script>
import {
XHeader,
XButton,
Divider,
TransferDom,
Group,
GroupTitle,
Cell,
XInput,
CheckIcon,
LoadMore,
Badge,
DatetimePlugin,
Popup,
PopupHeader,
Icon
} from "vux";
import Vue from "vue";
Vue.use(DatetimePlugin);
import ModelLoading from "@/components/model-loading";
import {
ERROR_IMAGE_PATH,
IMAGE_BASE_PATH
} from "@/plugins/common";
import APIs from "@/api";
import CONFIG from "@/config";
import { accNum } from "@/plugins/conmus";
import cookie from "@/plugins/cookie";
export default {
directives: {
TransferDom
},
components: {
XHeader,
Divider,
ModelLoading,
XButton,
Group,
GroupTitle,
Cell,
XInput,
CheckIcon,
LoadMore,
Badge,
Popup,
PopupHeader,
Icon
},
data() {
return {
conf: CONFIG,
isShowFirstLoading: true,
isChoose: false,
// 发票列表
invoiceList: [],
filterChecked:false,//筛选是否选中
showfilterpop:false,//筛选弹出层
startTime:'起始日期',
endTime:'截止日期',
choosenStartTime:false,//起始日期选中
arrowRotateStartTime:false,
choosenEndTime:false,//截止日期选中
arrowRotateEndTime:false,
invoiceType:'',//发票类型-0.电子普通发票 1.红字普通发票
chosenType0:false,//电子普通发票选中
chosenType1:false,//红字普通发票选中
// 起始页码默认为1
page: 1,
pageSize: 30,
nextPage: false,//true:有下一页 false:没有
lastGroupTitle:'',//类型:String 可有字段 备注:上一页的最后一组的组名
firstSearchDate:'', //类型:String 必有字段 备注:查询第一页的时间
checkedCount:0,//已选中发票数量
checkedTotalPrice:0,//已选择发票总价
checkedInvoiceList:[],//已选择发票列表
isShowScrollTop: false,
isshowEmails:false,//邮箱弹出层
showEmailsHeight:'50%',//邮箱弹出层高度
emailsValue:'',
isShowlist:false,
emaliList:false,
noInvoice:false,//暂无发票信息
};
},
mounted() {
if (cookie.getCookie("ua_id")) {
this.userAgent = cookie.getCookie('ua_id');
this.usertoken = cookie.getCookie('token');
this.passwordVersion = cookie.getCookie('app_passwordVersion');
cookie.setCookie("ua_id", this.userAgent, 30);
cookie.setCookie("appToken", this.usertoken, 30);
cookie.setCookie("passwordVersion", this.passwordVersion, 30);
} else {
let userInfo = {
name: "userInfo"
};
//ios
this.$bridge.callhandler("App_Echo", userInfo, data => {
this.z_app = false;
this.userAgent = data.ua_id;
});
//Android
this.$bridge.AndroidGetDate("App_Echo", userInfo, data => {
this.z_app = false;
this.userAgent = data.ua_id;
});
}
this.onPageInit();
},
computed: {
...accNum,
// 发票总数量
invoiceTotalCount() {
return this.invoiceList.length;
},
// 是否已全选
isCheckedAll: {
get: function () {
let items = this.invoiceList,
checkedCount = 0,//选中的发票数量
titleCount=0,//分组的标题数量
checkedTotalPrice=0,//选中的发票金额
checkedInvoiceList=[];//选中的发票列表
if (items && items.length > 0) {
for (let i in items) {
if (this.isChoose && !!items[i].isChecked) {
checkedCount++;
checkedTotalPrice = parseFloat(accNum.accAdd(checkedTotalPrice,items[i].price));
checkedInvoiceList.push({
fileUrl:items[i].attachUrl, //类型:String 必有字段 备注:发票路径
invoiceType:items[i].invoiceType, //类型:String 必有字段 备注:发票类型
invoiceNo:items[i].attachNo //类型:String 必有字段 备注:发票号码
});
}
//去掉分组的标题
if(items[i].objectType==1){
titleCount++;
}
}
this.checkedCount = checkedCount;
this.checkedTotalPrice = checkedTotalPrice;
this.checkedInvoiceList = checkedInvoiceList;
return checkedCount == items.length - titleCount;
}
return false;
},
set: function (checked) {
let items = this.invoiceList;
for (let i in items) {
if (this.isChoose && items[i].objectType==2) {
this.$set(items[i], "isChecked", checked);
}
}
}
},
// 是否显示加载进度
isShowLoading: {
get: function () {
return this.$vux.isLoading;
},
set: function (val) {
this.$store.commit("updateLoading", val);
}
},
},
methods: {
onPageInit() {
// 页面初始化时
this.getinvoiceList().then(() => {
this.isShowFirstLoading = false;
})
.catch(() => {
this.isShowFirstLoading = false;
});
},
//是否加载下一页
loadMore() {
if (this.nextPage) {
this.page++;
this.getinvoiceList(true);
}
},
//点击筛选
filterClick(){
this.showfilterpop = true;
},
//点击起始日期
showStartTime () {
var self = this;
var endDate = this.endTime=='截止日期'?new Date().toLocaleDateString().replace(/\//g,'-'):this.endTime;
this.$vux.datetime.show({
value:self.startTime=='起始日期'?'':self.startTime,
cancelText: '取消',
confirmText: '确定',
format: 'YYYY-MM-DD',
startDate:'2016-01-01',
endDate:endDate,
onConfirm (val) {
self.choosenStartTime = true;
self.startTime = val;
},
onShow () {
self.arrowRotateStartTime = true;
},
onHide () {
self.arrowRotateStartTime = false;
}
})
},
//点击截止日期
showEndTime(){
var self = this;
var startDate = this.startTime=='起始日期'?'2016-01-01':this.startTime;
this.$vux.datetime.show({
value:self.endTime=='截止日期'?'':self.endTime,
cancelText: '取消',
confirmText: '确定',
format: 'YYYY-MM-DD',
startDate:startDate,
endDate:new Date().toLocaleDateString().replace(/\//g,'-'),
onConfirm (val) {
self.choosenEndTime = true;
self.endTime = val;
},
onShow () {
self.arrowRotateEndTime = true;
},
onHide () {
self.arrowRotateEndTime = false;
}
})
},
//点击选择发票类型
chooseInvoiceType(type){
if(type===0){
this.chosenType0=!this.chosenType0;
}else if(type===1){
this.chosenType1=!this.chosenType1;
}
if(this.chosenType0 && !this.chosenType1){
this.invoiceType = 0;
}else if(!this.chosenType0 && this.chosenType1){
this.invoiceType = 1;
}else{
this.invoiceType = '';
}
},
//点击确认按钮
confirmFilter(){
this.showfilterpop = false;
if(this.startTime!=='起始日期' || this.endTime!=='截止日期' || this.invoiceType!==''){
this.filterChecked = true;
}else{
this.filterChecked = false;
}
//筛选条件初始化
this.initFilter();
//查询发票列表
this.getinvoiceList();
},
//点击重置按钮
resetFilter(){
this.filterChecked = false;
this.invoiceType = '';
this.chosenType0 = false;
this.chosenType1 = false;
this.startTime = '起始日期';
this.choosenStartTime = false;
this.endTime = '截止日期';
this.choosenEndTime = false;
},
//筛选条件初始化
initFilter(){
this.invoiceList=[];
this.isChoose = false;
// 起始页码默认为1
this.page= 1;
this.pageSize=30;
this.nextPage=false;//true:有下一页 false:没有
this.lastGroupTitle='';//类型:String 可有字段 备注:上一页的最后一组的组名
this.firstSearchDate=''; //类型:String 必有字段 备注:查询第一页的时间
},
// 单选
onClickItemChecked(e, item) {
// 默认状态下
if (this.isChoose) {
this.$set(item, "isChecked", e);
}
},
// 全选
onClickAllCheckedGoods() {},
// 滚动到头部
onClickScrollToTop(e) {
this.$refs.scrollerBottom.reset({
top: 0
});
},
//点击查看发票
invoicePreview(attachId){
if(this.Browser.miniProgram){
wx.miniProgram.navigateTo({
url: `/pages/orders/InvoicePreview/index?attachId=${attachId}`
});
}else{
this.$router.push({
path: `/Settings/invoiceManagement/InvoicePreview?attachId=${attachId}`
});
}
},
//点击发送至邮箱
chooseInvoice(){
this.isChoose = true;
},
//点击取消发送
cancelSend(){
this.isChoose = false;
},
//点击确认发送
confirmSend(){
if(this.checkedInvoiceList.length==0){
return;
}else if(this.checkedInvoiceList.length>30){
this.$vux.toast.text('不可选择超过30张发票,请分批发送~',"middle");
}else{
this.isshowEmails=true;
//ios
if (/(iPhone|iPad|iPod|iOS)/i.test(navigator.userAgent)) {
document.body.addEventListener('focusout', () => {
//键盘收起时需要body页面scrollTop改变
setTimeout(function () {
var scrollHeight = document.documentElement.scrollTop || document.body.scrollTop || 0;
window.scrollTo(0, Math.max(scrollHeight - 1, 0));
},10);
})
}else if(/(Android)/i.test(navigator.userAgent)){
var clientHeight = document.documentElement.clientHeight || document.body.clientHeight;
window.addEventListener('resize', () => {
var nowClientHeight = document.documentElement.clientHeight || document.body.clientHeight;
if (clientHeight > nowClientHeight) {
//键盘弹出的事件处理
this.showEmailsHeight = '80%';
}else {
//键盘收起的事件处理
this.showEmailsHeight = '50%';
}
});
}
}
},
// 获取我的发票
getinvoiceList(flag) {
var startTime = this.startTime=='起始日期'?'':this.startTime;
var endTime = this.endTime=='截止日期'?'':this.endTime;
!this.isShowFirstLoading?this.isShowLoading = true:this.isShowLoading = false;
return new Promise((resolve, reject) => {
this.__getinvoiceList(startTime,endTime,this.invoiceType,this.page, this.pageSize,this.lastGroupTitle,this.firstSearchDate)
.then(
({
data: {
success,
data: {
groupList,
nextPage,
mail,
lastGroupTitle,
firstSearchDate
},
message
}
}) => {
this.isShowLoading = false;
if (success) {
if (groupList) {
this.noInvoice = false;
if (!flag) {
this.invoiceList = groupList;
} else {
this.invoiceList = this.invoiceList.concat(groupList);
}
}else{
this.noInvoice = true;
}
this.nextPage = nextPage;
this.lastGroupTitle = lastGroupTitle?lastGroupTitle:'';
this.firstSearchDate = firstSearchDate?firstSearchDate:'';
this.emailsValue = mail?mail:'';
} else {
this.__warn(message);
}
// 完成后
resolve();
}
)
.catch(error => {
reject(error);
});
});
},
// 拉取发票信息
// page: 分页页码
async __getinvoiceList(startTime,endTime,invoiceType,page, pageSize,lastGroupTitle,firstSearchDate) {
let options = {
headers: { "Content-Type": "application/json" }
};
return await this.axios.post(APIs.GET_INVOICE_LIST,{
startTime, //类型:String 必有字段 备注:时间筛选-起始时间
endTime, //类型:String 必有字段 备注:时间筛选-结束时间
invoiceType,//类型:Number 必有字段 备注:-1.全部 0.电子普通发票 1.红字普通发票
page, //类型:String 必有字段 备注:当前页
pageSize, //类型:String 必有字段 备注:页容量
lastGroupTitle, //类型:String 可有字段 备注:上一页的最后一组的组名
firstSearchDate //类型:String 必有字段 备注:查询第一页的时间
},options);
},
//清空邮箱输入
clearInputValue(){
this.$refs.inputFiled1.value = "";
this.emailsValue = "";
this.isShowlist = false;
this.$refs.emailWarn.style.display = "none";
},
//邮箱自动补全
checkemaillist() {
var txt = this.emailsValue;
var flag = "";
if (
this.emailsValue != "" &&
this.emailsValue != null &&
this.emailsValue != undefined
) {
this.$refs.emailWarn.style.display = "none";
var after = txt.split("@")[1]; //获取输入@后面的字符
txt = txt.split("@")[0]; //输入@前面的字符
console.log(after);
// if(after==''||after!=null || after!=undefined){
this.emaliList = [txt + "@qq.com", txt + "@163.com", txt + "@sina.com"];
// }
this.isShowlist = true;
if (after == "q" || after == "qq" || after == "Q" || after == "QQ" || after == "qq."|| after == "qq.c"|| after == "qq.co"|| after == "qq.com") {
this.emaliList = [txt + "@qq.com"];
} else if (after == "1" || after == "16" || after == "163"|| after == "163."|| after == "163.c"|| after == "163.co"|| after == "163.com") {
this.emaliList = [txt + "@163.com"];
} else if (after == "s" || after == "si" || after == "sin" || after == "sina" || after == "sina."|| after == "sina.c"||
after == "sina.co"|| after == "sina.com")
{
this.emaliList = [txt + "@sina.com"];
} else {
if (after != "" && this.emailsValue.indexOf("@") >= 0) {
this.isShowlist = false;
}
}
} else {
this.isShowlist = false;
flag = "";
}
},
listItem(index){
this.emailsValue = this.emaliList[index];
this.isShowlist = false;
if(this.emailsValue.length>50){
this.$vux.toast.text('邮箱地址不可超过50个字符', "middle");
}
},
//发送至邮箱
onclicksendemail(){
var regEmail = /^[a-zA-z0-9]+@[a-zA-Z0-9]+\.\w{2,3}$/;
if (this.emailsValue == "") {
this.$refs.emailWarn.style.display = "block";
return
} else if (!regEmail.test(this.emailsValue)) {
this.$refs.emailWarn.style.display = "block";
return
} else if (this.emailsValue.length>50){
this.$refs.emailWarn.style.display = "block";
return
}
else {
this.$refs.emailWarn.style.display = "none";
}
//显示加载中
this.isShowLoading = true;
let options = {
headers: { "Content-Type": "application/json" }
};
return this.axios.post(APIs.SEND_MAIL,{
toAddress:this.emailsValue, //类型:String 必有字段 备注:收件箱地址
invoiceNum:this.checkedCount, //类型:Number 必有字段 备注:发票数量
sumPrice:this.checkedTotalPrice, //类型:Number 必有字段 备注:发票金额
invoiceList:this.checkedInvoiceList //类型:Array 必有字段 备注:无
},options).then(
({ data: { success, message, data}}) => {
if(success){
this.isshowEmails = false;
}
//隐藏加载中
this.isShowLoading = false;
this.$vux.toast.text(message,"middle");
});
}
}
};
</script>
<style lang="less">
#MyInvoice{
background: #FAF7FA;
padding-top: 0px;
.m_invoice_hd{
position: fixed;
top:0px;
left:0px;
right: 0px;
z-index: 10;
}
.m_invoice_hd{
background: #fff;
text-align: right;
height: 35px;
line-height: 35px;
padding:0 16px;
span{
font-size: 15px;
color:#333;
margin-right: 2px;
font-weight: bold;
}
span.filter_checked{
color:#0095FF;
}
img{
width:10px;
height:10px;
}
.filter_checked_img,.filter_img.filter_checked{
display: none;
}
.filter_checked_img.filter_checked{
display: inline-block;
}
}
.m_invoice_bd{
padding-top: 35px;
padding-bottom: 80px;
.invoice_list{
height:100%;
}
.u_load_more {
text-align: center;
height: 40px;
line-height: 40px;
}
.m_divider{
margin: 0 auto;
padding-left: 30px;
padding-right: 30px;
font-size: 14px;
}
}
.m_invoice_ft{
position: fixed;
bottom: 0;
width:100%;
z-index:100;
background: #FAF7FA;
.sendToEmail{
width: 90%;
height:40px;
line-height: 40px;
text-align: center;
margin:5px auto;
background: #0095FF;
color:#fff;
border-radius: 40px;
}
.m_invoice_foot_hd{
height:40px;
line-height: 40px;
font-size: 13px;
color:#333;
display: flex;
align-items: center;
justify-content: space-between;
background: #fff;
padding: 0 15px 0 20px;
.total_price{
font-size: 16px;
font-weight: bold;
color: #FF0000;
.yen{
font-size: 12px;
margin-right: 5px;
}
}
}
.m_invoice_foot_ft{
.bottom_btn{
display: flex;
font-size: 15px;
color:#333;
text-align: center;
height:40px;
line-height: 40px;
.cancelSend{
width:50%;
}
.confirmSend{
width:50%;
background: #0095FF;
color:#fff;
&.noCheckInvoice{
background: #ccc;
}
}
}
}
}
.invoice_item_list{
padding:0 10px;
height: 100%;
.invoice_item{
width:100%;
margin-top: 10px;
.invoice_time{
font-size:15px;
font-weight:bold;
color:#333;
background: #FAF7FA;
}
.invoice_content{
background: #fff;
padding:15px 15px 15px 11px;
font-size: 14px;
display: flex;
align-items: center;
border-radius:5px;
.u_single_checked{
margin-right: 10px;
}
.invoice_box{
width:100%;
}
.attachCreateAt{
padding-bottom: 5px;
}
.attachNo{
padding-bottom: 10px;
}
.attachPrice{
padding-top: 3px;
display: flex;
justify-content: space-between;
i{
font-size: 13px;
color: #333;
margin-left: 3px;
font-weight: normal;
}
}
.blueFont{
color:#0095FF;
font-size: 18px;
font-weight: bold;
}
.redFont{
color:#FF0000;
font-size: 18px;
font-weight: bold;
}
.check_invoiceBtn{
padding:5px 10px;
border:1px solid #ccc;
border-radius:30px;
font-size: 12px;
color: #333;
}
}
}
.invoice_item_title{
width: 70%;
position: sticky;
top: 5px;
}
}
//暂无发票信息
.m_invoice_empty {
height:calc(~"100vh - 82px");
.u_empty_img {
margin: 0 auto;
padding-top: 100px;
text-align: center;
font-size: 14px;
color: #333;
width: 128px;
&>img {
max-width: 100%;
max-height: 100%;
margin-bottom: 17px;
}
}
}
}
// 筛选弹出框
.filterpop{
background:#fff;
.filterpop_hd{
background: #fff;
text-align: right;
height: 35px;
line-height: 35px;
padding:0 16px;
span{
font-size: 15px;
color:#333;
margin-right: 2px;
font-weight: bold;
}
img{
width:10px;
height:10px;
}
}
.filterpop_bd{
padding-left: 15px;
font-size: 13px;
.filter_title{
padding:10px 0 15px 0;
color: #333;
font-weight: bold;
font-size: 15px;
}
.weui-btn:after{
border:none;
}
.weui-btn + .weui-btn{
margin-top: 0px;
}
.dateTimeBox{
display: inline-block;
position: relative;
}
.dateTimeBtn{
width:125px;
height:30px;
line-height: 30px;
background:#F8F8F8;
border-radius:15px;
color:#B8B8B8;
font-size: 13px;
text-align: left;
text-indent: 8px;
}
.dateTimeBtn.chosenTime{
color:#333;
}
.dateTime_arrow{
width:9px;
height:9px;
position: absolute;
right:10px;
top:11px;
transform: rotate(180deg);
}
.dateTime_arrow.arrowRotate{
transform: rotate(360deg);
}
.invoiceType{
padding:0px 17px;
height:30px;
line-height: 30px;
color:#333;
background: #F8F8F8;
border-radius: 15px;
margin-right: 10px;
display: inline-block;
margin-bottom: 27px;
}
.invoiceType.chosenType{
background: #0095FF;
color:#fff;
}
}
.filterpop_ft{
height:40px;
line-height: 40px;
display: flex;
background: #fff;
font-size: 15px;
color:#333;
text-align: center;
.reset_btn{
width:50%;
}
.confirm_btn{
width:50%;
background: #0095FF;
color:#fff;
}
}
}
.dp-header .dp-item.dp-right{
color: #0095FF;
}
// 邮箱弹出层
.invoicelayer{
background:rgba(255,255,255,1);
border-radius:15px 15px 0px 0px;
z-index: 1000;
&.vux-popup-dialog{
background: #fff;
}
.vux-popup-header{
background: #fff;
}
.vux-popup-header-title{
font-weight: bold;
}
.vux-popup-header.vux-1px-b:after {
border: 0;
}
.vux-popup-header > .vux-popup-header-right:before {
content: "\E611";
font-family: "iconfont" !important;
font-size: 16px;
font-style: normal;
position: absolute;
right: 0;
padding: 0 15px;
color: #999;
}
::-webkit-input-placeholder { /* WebKit browsers */
color: #999;
font-size: 14px;
}
::-moz-placeholder { /* Mozilla Firefox 19+ */
color: #999;
font-size: 14px;
}
:-ms-input-placeholder { /* Internet Explorer 10+ */
color: #999;
font-size: 14px;
}
.invoiceEmail{
margin: 5px 38px;
.invoiceInput{
border-bottom:1px #eee solid ;
}
.warmtext{
font-size:12px;
color:rgba(255,0,0,1);
margin-top:7px ;
display: none;
}
.maillist{
color: #999;
font-size: 13px;
line-height: 24px;
border:1px solid rgba(238,238,238,1);
border-top:0 ;
padding: 5px 0;
li{
padding:5px 0 5px 15px;
line-height: 16px;
overflow: hidden;
text-overflow: ellipsis;
}
}
.int-type{
line-height: 35px;
color: #333;
outline: 0;
font-size: 14px;
width: 91%;
outline: none;
border:none;
}
}
.constract-send-to {
height: 50px;
padding: 0;
text-align: center;
position: fixed;
bottom: 0;
z-index: 499;
left: 0px;
width: 100%;
background: #fff;
.bottomBtn{
width: 100%;
display: flex;
}
.sendBtn{
margin: 0 auto;
width: 100%;
button {
width:90%;
height:40px;
background:rgba(0,149,255,1);
border-radius:20px;
color: #fff;
font-size: 14px;
outline: none;
border: 0;
img {
width: 19px;
vertical-align: middle;
margin-right: 5px;
margin-bottom: 2px;
}
}
}
}
}
</style>
总结一下,代码里面几个要点:1、computed里面isCheckedAll就是用来判断是否全选的逻辑;2、ios和安卓还有两个键盘弹出时不同处理的方式,ios弹出键盘会把页面自动顶上去,所以ios做的处理就是键盘收起后,顶上去的页面自动滚下来,安卓键盘弹出会把弹出层缩小,所以安卓里做的就是键盘弹出时,弹出层高度增加,键盘收起,弹出层高度还原;3、position: sticky的元素--invoice_item_title的父元素--invoice_item_list的visibility一定不能是hidden,哪怕不设置visibility属性都行,否则滑动吸顶无效。