feat: Requirements changed
This commit is contained in:
parent
a2a4370327
commit
eea5ef4b28
|
|
@ -619,6 +619,10 @@ radio.white.checked .uni-radio-input {
|
||||||
/* ==================
|
/* ==================
|
||||||
按钮
|
按钮
|
||||||
==================== */
|
==================== */
|
||||||
|
|
||||||
|
.cu-tab-icon {
|
||||||
|
font-size: 28upx;
|
||||||
|
}
|
||||||
|
|
||||||
.cu-btn {
|
.cu-btn {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
@ -1701,6 +1705,14 @@ button.cuIcon.lg {
|
||||||
background-color: inherit;
|
background-color: inherit;
|
||||||
overflow: initial;
|
overflow: initial;
|
||||||
}
|
}
|
||||||
|
/* .cu-bar.tabbar {
|
||||||
|
flex-direction: column;
|
||||||
|
} */
|
||||||
|
|
||||||
|
.cu-bar.tabbar .title {
|
||||||
|
color: #C8C9CC;
|
||||||
|
font-size: 24upx;
|
||||||
|
}
|
||||||
|
|
||||||
.cu-bar.tabbar.shop .action {
|
.cu-bar.tabbar.shop .action {
|
||||||
width: 140upx;
|
width: 140upx;
|
||||||
|
|
@ -1710,20 +1722,22 @@ button.cuIcon.lg {
|
||||||
.cu-bar.tabbar .action.add-action {
|
.cu-bar.tabbar .action.add-action {
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
padding-top: 50upx;
|
color: #C8C9CC;
|
||||||
|
margin-top: -22upx;
|
||||||
|
font-size: 24upx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cu-bar.tabbar .action.add-action .bg-main-color {
|
||||||
|
margin-bottom: 6upx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cu-bar.tabbar .action.add-action [class*="cuIcon-"] {
|
.cu-bar.tabbar .action.add-action [class*="cuIcon-"] {
|
||||||
position: absolute;
|
position: relative;
|
||||||
width: 70upx;
|
width: 70upx;
|
||||||
z-index: 2;
|
|
||||||
height: 70upx;
|
height: 70upx;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
line-height: 70upx;
|
line-height: 70upx;
|
||||||
font-size: 50upx;
|
font-size: 50upx;
|
||||||
top: -35upx;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
margin: auto;
|
margin: auto;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
@ -1733,17 +1747,18 @@ button.cuIcon.lg {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 100upx;
|
width: 100upx;
|
||||||
height: 100upx;
|
height: 100upx;
|
||||||
top: -50upx;
|
top: -15upx;
|
||||||
left: 0;
|
left: -15rpx;
|
||||||
right: 0;
|
right: 0;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
box-shadow: 0 -3upx 8upx rgba(0, 0, 0, 0.08);
|
box-shadow: 0 -3upx 8upx rgba(0, 0, 0, 0.08);
|
||||||
border-radius: 50upx;
|
border-radius: 50upx;
|
||||||
background-color: inherit;
|
background-color: inherit;
|
||||||
z-index: 0;
|
z-index: 0;
|
||||||
|
border-bottom: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cu-bar.tabbar .action.add-action::before {
|
/* .cu-bar.tabbar .action.add-action::before {
|
||||||
content: "";
|
content: "";
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 100upx;
|
width: 100upx;
|
||||||
|
|
@ -1754,7 +1769,7 @@ button.cuIcon.lg {
|
||||||
margin: auto;
|
margin: auto;
|
||||||
background-color: inherit;
|
background-color: inherit;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
} */
|
||||||
|
|
||||||
.cu-bar.tabbar .btn-group {
|
.cu-bar.tabbar .btn-group {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,287 @@
|
||||||
|
<template>
|
||||||
|
<view>
|
||||||
|
<view class="page-content">
|
||||||
|
<!-- 所有内容的容器 -->
|
||||||
|
<slot></slot>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- <module-bar ref="moduleBar" :moduleBarInfos="moduleBarInfos" @getCurPageInfo="getCurPageInfo"></module-bar> -->
|
||||||
|
|
||||||
|
<m-tabbar fill fixed safeBottom
|
||||||
|
:tabbarHeight="140"
|
||||||
|
:current="current"
|
||||||
|
:tabbar="tabbar2"
|
||||||
|
:beforeChange="tabbarBeforeChange">
|
||||||
|
<template v-slot:tabbar_index_2>
|
||||||
|
<view class="custom_style" @click="switchToPublish">
|
||||||
|
<view class="action add-action">
|
||||||
|
<text class="cuIcon-add bg-main-color"></text>
|
||||||
|
</view>
|
||||||
|
<text class="title">发布</text>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
</m-tabbar>
|
||||||
|
|
||||||
|
<!-- 发布 -->
|
||||||
|
<view class="cu-modal content-mask" :class="isShowPublish?'show':''">
|
||||||
|
<view class="cu-dialog bottom-dialog margin-bottom-with-bar">
|
||||||
|
<view class="padding-xl">
|
||||||
|
<view class="flex justify-start margin-tb-xl">
|
||||||
|
<view class="cu-avatar round middle-avatar first-avatar">
|
||||||
|
<view class="cuIcon-formfill"></view>
|
||||||
|
</view>
|
||||||
|
<view class="flex flex-column-around text-left margin-left-sm text-white"
|
||||||
|
@click="goRouter('/pages/publish/publish-task')">
|
||||||
|
<view class="text-xl">发布任务</view>
|
||||||
|
<view>公司、家居家政雇佣上门服务</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="cu-bar tabbar margin-bottom-xl fixed-bottom-bar">
|
||||||
|
<view class="action add-action" @click.stop="isShowPublish = false">
|
||||||
|
<button class="cu-btn bg-gray cuIcon-close"></button>
|
||||||
|
<text class="mask-close-text">关闭</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 登录校验弹窗 -->
|
||||||
|
<vertify-login ref="vertifyLogin" @reload="reloadForwardPage"></vertify-login>
|
||||||
|
<vertify-phone ref="vertifyPhone" @reload="reloadForwardPage"></vertify-phone>
|
||||||
|
|
||||||
|
<valid ref="validRef"></valid>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
import valid from '@/pages/index/components/valid.vue';
|
||||||
|
let that
|
||||||
|
export default {
|
||||||
|
name: "CTabbar",
|
||||||
|
components: {
|
||||||
|
valid
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
current: {
|
||||||
|
type: Number,
|
||||||
|
default: 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
tabbar2: {
|
||||||
|
color: "#aaaaaa",
|
||||||
|
selectedColor: "#0081ff",
|
||||||
|
backgroundColor: "#FFFFFF",
|
||||||
|
list: [{
|
||||||
|
pagePath: "pages/index/home",
|
||||||
|
text: "首页",
|
||||||
|
cuIcon: 'homefill',
|
||||||
|
openType: 'switchTab'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pagePath: "pages/index/worker-home",
|
||||||
|
text: "师傅圈",
|
||||||
|
cuIcon: 'circle',
|
||||||
|
openType: 'switchTab'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
cuIcon: 'plus'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pagePath: "pages/index/msg-home",
|
||||||
|
text: "消息",
|
||||||
|
cuIcon: 'message',
|
||||||
|
openType: 'switchTab'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pagePath: "pages/index/my-home",
|
||||||
|
text: "我的",
|
||||||
|
cuIcon: 'my',
|
||||||
|
openType: 'switchTab'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
isShowPublish: false,
|
||||||
|
initParam: null
|
||||||
|
};
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
uni.hideTabBar();
|
||||||
|
that = this;
|
||||||
|
uni.$on('initValid', this.initValid)
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
// this.$refs.vertifyLogin.showModal();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
initValid(initParam) {
|
||||||
|
this.initParam = initParam
|
||||||
|
this.$refs.validRef.loadData(initParam)
|
||||||
|
},
|
||||||
|
goRouter(path) {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: path
|
||||||
|
})
|
||||||
|
},
|
||||||
|
async switchToPublish() {
|
||||||
|
const res = await this.authLogin()
|
||||||
|
if(res) {
|
||||||
|
this.isShowPublish = true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
tabbarBeforeChange: async (next, index) => {
|
||||||
|
console.log('tabbarBeforeChange==', index);
|
||||||
|
if (index === 4) {
|
||||||
|
const res = await that.authLogin()
|
||||||
|
console.log(res);
|
||||||
|
if(res){
|
||||||
|
next()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
next()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async authLogin() {
|
||||||
|
// 更新缓存中的userInfo
|
||||||
|
let res = await this.$request.storageExistUser();
|
||||||
|
// 获取缓存中的userInfo
|
||||||
|
let curUserInfo = this.$request.getCurUserInfo();
|
||||||
|
// 校验提示登录
|
||||||
|
if (!curUserInfo || !curUserInfo.openId) {
|
||||||
|
this.$refs.vertifyLogin.showModal();
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
this.$refs.vertifyLogin.hideModal();
|
||||||
|
}
|
||||||
|
// 校验提示获取手机号码
|
||||||
|
if (!curUserInfo.phone) {
|
||||||
|
this.$refs.vertifyPhone.showModal();
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
this.$refs.vertifyPhone.hideModal();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
reloadForwardPage() {
|
||||||
|
if(this.$refs.validRef.inByShare){
|
||||||
|
this.$refs.validRef.loadData(this.initParam)
|
||||||
|
} else {
|
||||||
|
this.authLogin()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
destroyed() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.page-content {
|
||||||
|
width: 100vw;
|
||||||
|
// height: calc(100vh - env(safe-area-inset-bottom) - 100rpx);
|
||||||
|
background-color: #F7F8FA;
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom_style {
|
||||||
|
position: relative;
|
||||||
|
z-index: 2;
|
||||||
|
color: #aaaaaa;
|
||||||
|
margin-top: -22upx;
|
||||||
|
font-size: 24upx;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom_style .action.add-action {
|
||||||
|
position: relative;
|
||||||
|
z-index: 2;
|
||||||
|
color: #aaaaaa;
|
||||||
|
margin-top: -22upx;
|
||||||
|
font-size: 24upx;
|
||||||
|
width: 70upx;
|
||||||
|
margin-bottom: 17rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom_style .action.add-action [class*="cuIcon-"] {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
width: 70upx;
|
||||||
|
height: 70upx;
|
||||||
|
border-radius: 50%;
|
||||||
|
line-height: 70upx;
|
||||||
|
font-size: 50upx;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom_style .action.add-action .bg-main-color {
|
||||||
|
margin-bottom: 6upx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom_style .action.add-action::after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
width: 100upx;
|
||||||
|
height: 100upx;
|
||||||
|
top: -14upx;
|
||||||
|
left: -14rpx;
|
||||||
|
right: 0;
|
||||||
|
margin: auto;
|
||||||
|
box-shadow: 0 -3upx 8upx rgba(0, 0, 0, 0.08);
|
||||||
|
border-radius: 50upx;
|
||||||
|
background-color: inherit;
|
||||||
|
z-index: -1;
|
||||||
|
border-bottom: transparent;
|
||||||
|
background-color: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom_style .title {
|
||||||
|
color: #aaaaaa;
|
||||||
|
font-size: 24upx;
|
||||||
|
}
|
||||||
|
.content-mask {
|
||||||
|
z-index: 9999;
|
||||||
|
background: rgba(0, 0, 0, 0.9);
|
||||||
|
}
|
||||||
|
|
||||||
|
.mask-close-text {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.middle-avatar {
|
||||||
|
width: 120rpx;
|
||||||
|
height: 120rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.middle-avatar [class*="cuIcon-"] {
|
||||||
|
font-size: 53rpx !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cu-avatar.first-avatar {
|
||||||
|
background-color: #0081ff;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cu-avatar.second-avatar {
|
||||||
|
background-color: #fbbd08;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cu-avatar.third-avatar {
|
||||||
|
background-color: #f37b1d;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cu-avatar.fourth-avatar {
|
||||||
|
background-color: #1cbbb4;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cu-dialog.bottom-dialog {
|
||||||
|
background-color: unset;
|
||||||
|
vertical-align: bottom;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
<view class="flex justify-start">
|
<view class="flex justify-start">
|
||||||
<view v-if="vCard.picUrl" class="cu-avatar" :class="avatarPubClass" :style="'background-image:url(' + vCard.picUrl + '); width: ' + avatarWidth + '; height: ' + avatarHeight + ';'">
|
<view v-if="vCard.picUrl" class="cu-avatar" :class="avatarPubClass" :style="'background-image:url(' + vCard.picUrl + '); width: ' + avatarWidth + '; height: ' + avatarHeight + ';'">
|
||||||
</view>
|
</view>
|
||||||
<view v-else-if="vCard.workerLogoUrl" class="cu-avatar" :class="avatarPubClass" :style="'background-image:url(' + vCard.workerLogoUrl + '); width: ' + avatarWidth + '; height: ' + avatarHeight + ';'">
|
<view v-else-if="vCard.workerLogoUrl" class="cu-avatar" :class="avatarPubClass" :style="'background-image:url(' + defaultHead(vCard.workerLogoUrl) + '); width: ' + avatarWidth + '; height: ' + avatarHeight + ';'">
|
||||||
</view>
|
</view>
|
||||||
<view v-else-if="vCard.customerLogoUrl" class="cu-avatar" :class="avatarPubClass" :style="'background-image:url(' + vCard.customerLogoUrl + '); width: ' + avatarWidth + '; height: ' + avatarHeight + ';'">
|
<view v-else-if="vCard.customerLogoUrl" class="cu-avatar" :class="avatarPubClass" :style="'background-image:url(' + vCard.customerLogoUrl + '); width: ' + avatarWidth + '; height: ' + avatarHeight + ';'">
|
||||||
</view>
|
</view>
|
||||||
|
|
@ -69,6 +69,14 @@
|
||||||
return {
|
return {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
defaultHead(url) {
|
||||||
|
if(url === 'https://thirdwx.qlogo.cn/mmopen/vi_32/POgEwh4mIHO4nibH0KlMECNjjGxQUq24ZEaGT4poC6icRiccVGKSyXwibcPq4BWmiaIGuG1icwxaQX6grC9VemZoJ8rg/132') {
|
||||||
|
return 'http://gqz.opsoul.com/2741722238771_.pic.jpg'
|
||||||
|
}
|
||||||
|
return url
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
<view class="cu-modal" :class="isShow?'show':''">
|
<view class="cu-modal" :class="isShow?'show':''">
|
||||||
<view class="cu-dialog">
|
<view class="cu-dialog">
|
||||||
<view class="padding-xl">
|
<view class="padding-xl">
|
||||||
<view>授予小程序绑定微信手机号码的权限</view>
|
<view>授予小程序绑定手机号码的权限</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="cu-bar bg-white">
|
<view class="cu-bar bg-white">
|
||||||
<navigator class="modal-bottom-oper margin-0 flex-sub text-black solid-right" open-type="exit" target="miniProgram">拒绝授权
|
<navigator class="modal-bottom-oper margin-0 flex-sub text-black solid-right" open-type="exit" target="miniProgram">拒绝授权
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name" : "dingdong-mall",
|
"name" : "dingdong-mall",
|
||||||
"appid" : "",
|
"appid" : "__UNI__5E048DE",
|
||||||
"description" : "",
|
"description" : "",
|
||||||
"versionName" : "1.0.0",
|
"versionName" : "1.0.0",
|
||||||
"versionCode" : "100",
|
"versionCode" : "100",
|
||||||
|
|
@ -48,7 +48,6 @@
|
||||||
"quickapp" : {},
|
"quickapp" : {},
|
||||||
/* 快应用特有相关 */
|
/* 快应用特有相关 */
|
||||||
"mp-weixin" : {
|
"mp-weixin" : {
|
||||||
/* 小程序特有相关 */
|
|
||||||
"appid" : "wxc39c2af3ea24cd37",
|
"appid" : "wxc39c2af3ea24cd37",
|
||||||
"setting" : {
|
"setting" : {
|
||||||
"urlCheck" : false,
|
"urlCheck" : false,
|
||||||
|
|
|
||||||
78
pages.json
78
pages.json
|
|
@ -1,6 +1,15 @@
|
||||||
{
|
{
|
||||||
"pages": [{
|
"pages": [{
|
||||||
"path": "pages/index/index"
|
"path": "pages/index/home"
|
||||||
|
}, {
|
||||||
|
|
||||||
|
"path": "pages/index/worker-home"
|
||||||
|
}, {
|
||||||
|
|
||||||
|
"path": "pages/index/msg-home"
|
||||||
|
}, {
|
||||||
|
|
||||||
|
"path": "pages/index/my-home"
|
||||||
}],
|
}],
|
||||||
"subPackages": [{
|
"subPackages": [{
|
||||||
"root": "pages/order/",
|
"root": "pages/order/",
|
||||||
|
|
@ -17,15 +26,15 @@
|
||||||
"path": "product-pick"
|
"path": "product-pick"
|
||||||
}, {
|
}, {
|
||||||
"path": "shop-detail"
|
"path": "shop-detail"
|
||||||
}, {
|
}, {
|
||||||
"path": "product-category"
|
"path": "product-category"
|
||||||
}, {
|
}, {
|
||||||
"path": "filtered-products"
|
"path": "filtered-products"
|
||||||
}]
|
}]
|
||||||
}, {
|
}, {
|
||||||
"root": "pages/my/",
|
"root": "pages/my/",
|
||||||
"pages": [{
|
"pages": [{
|
||||||
"path": "edit-user-basic-info"
|
"path": "edit-user-basic-info"
|
||||||
}, {
|
}, {
|
||||||
"path": "my-order"
|
"path": "my-order"
|
||||||
}, {
|
}, {
|
||||||
|
|
@ -46,26 +55,49 @@
|
||||||
"path": "my-team-member"
|
"path": "my-team-member"
|
||||||
}, {
|
}, {
|
||||||
"path": "serv-detail"
|
"path": "serv-detail"
|
||||||
}, {
|
}, {
|
||||||
"path": "statement-desc"
|
"path": "statement-desc"
|
||||||
}, {
|
}, {
|
||||||
"path": "withdraw"
|
"path": "withdraw"
|
||||||
}, {
|
}, {
|
||||||
"path": "b-account-bind"
|
"path": "b-account-bind"
|
||||||
}, {
|
}, {
|
||||||
"path": "my-money-bag"
|
"path": "my-money-bag"
|
||||||
}, {
|
}, {
|
||||||
"path": "member-approval"
|
"path": "member-approval"
|
||||||
|
}]
|
||||||
|
}, {
|
||||||
|
"root": "pages/publish/",
|
||||||
|
"pages": [{
|
||||||
|
"path": "publish-task"
|
||||||
}]
|
}]
|
||||||
}, {
|
|
||||||
"root":"pages/publish/",
|
|
||||||
"pages": [{
|
|
||||||
"path": "publish-task"
|
|
||||||
}]
|
|
||||||
}],
|
}],
|
||||||
// "pages": [{
|
// "pages": [{
|
||||||
// "path": "pages/my/serv-detail"
|
// "path": "pages/my/serv-detail"
|
||||||
// }],
|
// }],
|
||||||
|
"tabBar": {
|
||||||
|
"color": "#7A7E83",
|
||||||
|
"selectedColor": "#3cc51f",
|
||||||
|
"borderStyle": "black",
|
||||||
|
"backgroundColor": "#ffffff",
|
||||||
|
"list": [{
|
||||||
|
"pagePath": "pages/index/home",
|
||||||
|
"visible": "false"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pagePath": "pages/index/worker-home",
|
||||||
|
"visible": "false"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pagePath": "pages/index/msg-home",
|
||||||
|
"visible": "false"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pagePath": "pages/index/my-home",
|
||||||
|
"visible": "false"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"globalStyle": {
|
"globalStyle": {
|
||||||
"navigationStyle": "custom",
|
"navigationStyle": "custom",
|
||||||
"navigationBarTextStyle": "black"
|
"navigationBarTextStyle": "black"
|
||||||
|
|
@ -76,4 +108,4 @@
|
||||||
// "background": "#efeff4"
|
// "background": "#efeff4"
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,169 @@
|
||||||
|
<template>
|
||||||
|
<view>
|
||||||
|
<!-- 订阅授权 -->
|
||||||
|
<vertify-subscribe ref="vertifySubscribe"></vertify-subscribe>
|
||||||
|
<vertify-settingSubscribe ref="vertifySettingSubscribe"></vertify-settingSubscribe>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
curPageCode: 'indexPage',
|
||||||
|
isShowPublish: false,
|
||||||
|
forwardingPageCode: null,
|
||||||
|
curUserInfo: null,
|
||||||
|
inByShare: false,
|
||||||
|
inParam: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// async onLoad(option) {
|
||||||
|
// this.inParam = option;
|
||||||
|
// this.loadData(option);
|
||||||
|
// },
|
||||||
|
methods: {
|
||||||
|
async loadData(option) {
|
||||||
|
this.inParam = option;
|
||||||
|
this.curUserInfo = this.$request.getCurUserInfo();
|
||||||
|
// 更新分销人信息
|
||||||
|
if (option && option.distributor) {
|
||||||
|
let loginRes = await this.authLogin();
|
||||||
|
if (!loginRes) {
|
||||||
|
this.inByShare = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.inByShare = false;
|
||||||
|
let res = await this.$request.updateUser({
|
||||||
|
customerPlace: option.distributor,
|
||||||
|
customerId: this.curUserInfo.customerId
|
||||||
|
});
|
||||||
|
if (res && res.code === 0) {
|
||||||
|
this.inParam = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let _this = this;
|
||||||
|
|
||||||
|
// 提示授权订单进度消息提示
|
||||||
|
wx.getSetting({
|
||||||
|
withSubscriptions: true,
|
||||||
|
success(res) {
|
||||||
|
console.log(res.subscriptionsSetting)
|
||||||
|
if (res.subscriptionsSetting.mainSwitch && (!res.subscriptionsSetting.itemSettings
|
||||||
|
|| !res.subscriptionsSetting.itemSettings['JtsGFPDjYhL2GbHfKxvTJaR_lLp8xLyw8VeR01Y0JHM'])) {
|
||||||
|
// 提示授权订单进度消息提示
|
||||||
|
_this.$refs.vertifySubscribe.showModal();
|
||||||
|
} else if (!res.subscriptionsSetting.mainSwitch
|
||||||
|
|| res.subscriptionsSetting.itemSettings['JtsGFPDjYhL2GbHfKxvTJaR_lLp8xLyw8VeR01Y0JHM'] !== 'accept') {
|
||||||
|
_this.$refs.vertifySettingSubscribe.showModal();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
reloadForwardPage() {
|
||||||
|
if (this.inByShare) {
|
||||||
|
this.loadData(this.inParam);
|
||||||
|
} else {
|
||||||
|
this.getCurPageInfo({
|
||||||
|
curPageCode: this.forwardingPageCode
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async getCurPageInfo(data) {
|
||||||
|
let pageCode = data.curPageCode;
|
||||||
|
this.forwardingPageCode = pageCode;
|
||||||
|
// 登录校验
|
||||||
|
if (['publishPage', 'myPage'].indexOf(pageCode) >= 0) {
|
||||||
|
let loginRes = await this.authLogin();
|
||||||
|
if (!loginRes) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.forwardingPageCode = null;
|
||||||
|
|
||||||
|
if (pageCode === 'publishPage') {
|
||||||
|
this.isShowPublish = true;
|
||||||
|
} else {
|
||||||
|
this.isShowPublish = false;
|
||||||
|
this.curPageCode = pageCode;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
hidePublish() {
|
||||||
|
this.isShowPublish = false;
|
||||||
|
},
|
||||||
|
showPage(url) {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: url
|
||||||
|
})
|
||||||
|
},
|
||||||
|
async authLogin() {
|
||||||
|
// 更新缓存中的userInfo
|
||||||
|
let res = await this.$request.storageExistUser();
|
||||||
|
// 获取缓存中的userInfo
|
||||||
|
let curUserInfo = this.$request.getCurUserInfo();
|
||||||
|
// 校验提示登录
|
||||||
|
if (!curUserInfo || !curUserInfo.openId) {
|
||||||
|
this.$refs.vertifyLogin.showModal();
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
this.$refs.vertifyLogin.hideModal();
|
||||||
|
}
|
||||||
|
// 校验提示获取手机号码
|
||||||
|
if (!curUserInfo.phone) {
|
||||||
|
this.$refs.vertifyPhone.showModal();
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
this.$refs.vertifyPhone.hideModal();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.content-mask {
|
||||||
|
z-index: 9999;
|
||||||
|
background: rgba(0, 0, 0, 0.9);
|
||||||
|
}
|
||||||
|
|
||||||
|
.mask-close-text {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.middle-avatar {
|
||||||
|
width: 120rpx;
|
||||||
|
height: 120rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.middle-avatar [class*="cuIcon-"] {
|
||||||
|
font-size: 53rpx !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cu-avatar.first-avatar {
|
||||||
|
background-color: #0081ff;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cu-avatar.second-avatar {
|
||||||
|
background-color: #fbbd08;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cu-avatar.third-avatar {
|
||||||
|
background-color: #f37b1d;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cu-avatar.fourth-avatar {
|
||||||
|
background-color: #1cbbb4;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cu-dialog.bottom-dialog {
|
||||||
|
background-color: unset;
|
||||||
|
vertical-align: bottom;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -1,171 +1,195 @@
|
||||||
<template name="index">
|
<template name="index">
|
||||||
<view>
|
<c-tabbar :current="0">
|
||||||
<!-- 顶部操作条 -->
|
|
||||||
<!-- <cu-custom class="text-left">
|
|
||||||
<block slot="left-content">
|
|
||||||
<image :src="item.url" v-if="item.type=='image'"></image>
|
|
||||||
<text class="padding-left text-xl" style="float: left;">叮咚到家家政服务</text>
|
|
||||||
</block>
|
|
||||||
</cu-custom> -->
|
|
||||||
<!-- 轮播图-->
|
|
||||||
<swiper class="screen-swiper" :class="dotStyle?'square-dot':'round-dot'" :indicator-dots="true" :circular="true"
|
|
||||||
:autoplay="true" interval="5000" duration="500">
|
|
||||||
<swiper-item v-for="(item,index) in swiperList" :key="item.id">
|
|
||||||
<image mode="aspectFill" :src="item.url" v-if="item.type=='image'"></image>
|
|
||||||
<video :src="item.url" autoplay loop muted :show-play-btn="false" :controls="false" objectFit="cover"
|
|
||||||
v-if="item.type=='video'"></video>
|
|
||||||
</swiper-item>
|
|
||||||
</swiper>
|
|
||||||
<!-- 搜索栏 -->
|
|
||||||
<view class="cu-bar search bg-white">
|
|
||||||
<view class="search-form round">
|
|
||||||
<text class="cuIcon-search"></text>
|
|
||||||
<input @confirm="searchGoods" v-model="searchInfo.inputGoodsName" :adjust-position="true" type="text"
|
|
||||||
placeholder="输入搜索内容" confirm-type="search"></input>
|
|
||||||
</view>
|
|
||||||
<!-- 区域筛选picker -->
|
|
||||||
<view class="action">
|
|
||||||
<picker class="text-black text-bold" :mode="'multiSelector'" @change="regionChange" @columnchange="regionColChange"
|
|
||||||
:value="areaMultiIndex" :range-key="'areaName'" :range="areaList">
|
|
||||||
<text>{{searchInfo.area && searchInfo.area.length ? searchInfo.area[1].areaName : areaList[1][0].areaName}}</text>
|
|
||||||
<text class="text-xl"><text class="cuIcon-triangledownfill"></text></text>
|
|
||||||
</picker>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view>
|
<view>
|
||||||
<view class="margin-lr-sm">
|
<!-- 顶部操作条 -->
|
||||||
<!-- 大类 -->
|
<!-- <cu-custom class="text-left">
|
||||||
<view class="flex justify-between text-black">
|
<block slot="left-content">
|
||||||
<view class="padding text-lg" @click="showProductCategories">
|
<image :src="item.url" v-if="item.type=='image'"></image>
|
||||||
<text>分类</text>
|
<text class="padding-left text-xl" style="float: left;">叮咚到家家政服务</text>
|
||||||
<text class="cuIcon-apps text-main-color"></text>
|
</block>
|
||||||
<text class="cuIcon-triangledownfill"></text>
|
</cu-custom> -->
|
||||||
</view>
|
<!-- 轮播图-->
|
||||||
<view class="flex-twice">
|
<swiper class="screen-swiper" :class="dotStyle?'square-dot':'round-dot'" :indicator-dots="true"
|
||||||
<scroll-view scroll-x class="nav text-right" :scroll-with-animation="true" :scroll-left="scrollLeft">
|
:circular="true" :autoplay="true" interval="5000" duration="500">
|
||||||
<view class="cu-item" :class="index==tabCur?'text-main-color cur':''" v-if="index < 2"
|
<swiper-item v-for="(item,index) in swiperList" :key="item.id">
|
||||||
v-for="(item,index) in categories" :key="item.goodsCategoryId" @tap="tabSelect($event, item)" :data-index="index">
|
<image mode="aspectFill" :src="item.url" v-if="item.type=='image'"></image>
|
||||||
{{item.goodsCategoryName}}
|
<video :src="item.url" autoplay loop muted :show-play-btn="false" :controls="false"
|
||||||
</view>
|
objectFit="cover" v-if="item.type=='video'"></video>
|
||||||
</scroll-view>
|
</swiper-item>
|
||||||
</view>
|
</swiper>
|
||||||
</view>
|
<!-- 搜索栏 -->
|
||||||
<!-- 热门细类 -->
|
<view class="cu-bar search bg-white">
|
||||||
<view class="cu-list grid no-border hot-sub-category" :class="['col-5']" :style="'padding-top: 10rpx'">
|
<view class="search-form round">
|
||||||
<view class="cu-item align-center" v-for="(item,index) in hotServCategory" :key="index" v-if="tabCur === 0 && index < 15"
|
<text class="cuIcon-search"></text>
|
||||||
@click="chooseCategory(item)">
|
<input @confirm="searchGoods" v-model="searchInfo.inputGoodsName" :adjust-position="true"
|
||||||
<!-- <view class="hot-sub-category-icon" :class="['cuIcon-' + item.cuIcon,'text-' + item.color]">
|
type="text" placeholder="输入搜索内容" confirm-type="search"></input>
|
||||||
<view class="cu-tag badge" v-if="item.badge!=0">
|
</view>
|
||||||
<block v-if="item.badge!=1">{{item.badge}}</block>
|
<!-- 区域筛选picker -->
|
||||||
</view>
|
<view class="action">
|
||||||
</view> -->
|
<picker class="text-black text-bold" :mode="'multiSelector'" @change="regionChange"
|
||||||
<view class="cu-avatar round"
|
@columnchange="regionColChange" :value="areaMultiIndex" :range-key="'areaName'"
|
||||||
:style="'width: 100rpx; height: 100rpx; background-image:url(' + item.cover + ');'"></view>
|
:range="areaList">
|
||||||
<text>{{item.name}}</text>
|
<text>{{searchInfo.area && searchInfo.area.length ? searchInfo.area[1].areaName : areaList[1][0].areaName}}</text>
|
||||||
</view>
|
<text class="text-xl"><text class="cuIcon-triangledownfill"></text></text>
|
||||||
<view class="cu-item align-center" v-for="(item,index) in hotFittingsCategory" :key="index" v-if="tabCur === 1 && index < 15"
|
</picker>
|
||||||
@click="chooseCategory(item)">
|
</view>
|
||||||
<view class="cu-avatar round"
|
</view>
|
||||||
:style="'width: 100rpx; height: 100rpx; background-image:url(' + item.cover + ');'"></view>
|
<view>
|
||||||
<text>{{item.name}}</text>
|
<view class="margin-lr-sm">
|
||||||
</view>
|
<!-- 大类 -->
|
||||||
</view>
|
<view class="flex justify-between text-black">
|
||||||
<!-- 细类 -->
|
<view class="padding text-lg" @click="showProductCategories">
|
||||||
<!-- <view class="cu-list grid no-border" :class="['col-5']" v-if="subCategories.length > 5">
|
<text>分类</text>
|
||||||
<view class="cu-item" v-for="(item,index) in subCategories" :key="index"
|
<text class="cuIcon-apps text-main-color"></text>
|
||||||
v-if="index < subCategories.length && index > 4" @click="chooseCategory(item)">
|
<text class="cuIcon-triangledownfill"></text>
|
||||||
<view :class="['cuIcon-' + item.cuIcon,'text-' + item.color]">
|
</view>
|
||||||
</view>
|
<view class="flex-twice">
|
||||||
<text>{{item.goodsCategoryName}}</text>
|
<scroll-view scroll-x class="nav text-right" :scroll-with-animation="true"
|
||||||
</view>
|
:scroll-left="scrollLeft">
|
||||||
</view> -->
|
<view class="cu-item" :class="index==tabCur?'text-main-color cur':''" v-if="index < 2"
|
||||||
<!-- 超值服务 -->
|
v-for="(item,index) in categories" :key="item.goodsCategoryId"
|
||||||
<!-- <vertical-goods-card ref="discountGoodsCard" :goodsInfos="discountGoods.goodsInfos"
|
@tap="tabSelect($event, item)" :data-index="index">
|
||||||
:title="discountGoods.title"></vertical-goods-card> -->
|
{{item.goodsCategoryName}}
|
||||||
<!-- 热门服务 -->
|
</view>
|
||||||
<!-- <vertical-card :list="hotServCategory" :multiPicMode="true" title="大家都在买"></vertical-card> -->
|
</scroll-view>
|
||||||
</view>
|
</view>
|
||||||
<!-- 当前城市服务列表 -->
|
</view>
|
||||||
<view class="text-gray text-lg text-center margin flex align-center">
|
<!-- 热门细类 -->
|
||||||
<view class="divider"/>
|
<view class="cu-list grid no-border hot-sub-category" :class="['col-5']"
|
||||||
<text class="margin-lr-sm" style="flex-basis: 60%; color: #9E9E9E;">当前城市</text>
|
:style="'padding-top: 10rpx'">
|
||||||
<view class="divider"/>
|
<view class="cu-item align-center" v-for="(item,index) in hotServCategory" :key="index"
|
||||||
</view>
|
v-if="tabCur === 0 && index < 15" @click="chooseCategory(item)">
|
||||||
<view>
|
<!-- <view class="hot-sub-category-icon" :class="['cuIcon-' + item.cuIcon,'text-' + item.color]">
|
||||||
<view class="margin-top-sm margin-lr-sm waterfall-grid">
|
<view class="cu-tag badge" v-if="item.badge!=0">
|
||||||
<view @click="showDetails(item)" :key="item.goodsId" v-for="(item, index) in productList" class="waterfall-grid-item">
|
<block v-if="item.badge!=1">{{item.badge}}</block>
|
||||||
<flow-goods-card :product="item"></flow-goods-card>
|
</view>
|
||||||
</view>
|
</view> -->
|
||||||
</view>
|
<view class="cu-avatar round"
|
||||||
<load-status-bar ref="loadStatusBar1" @loadMore="loadProductPage"></load-status-bar>
|
:style="'width: 100rpx; height: 100rpx; background-image:url(' + item.cover + ');'">
|
||||||
</view>
|
</view>
|
||||||
<!-- 其他城市服务列表 -->
|
<text>{{item.name}}</text>
|
||||||
<view class="text-gray text-lg text-center margin flex align-center" style="padding-top: 60rpx;">
|
</view>
|
||||||
<view class="divider"/>
|
<view class="cu-item align-center" v-for="(item,index) in hotFittingsCategory" :key="index"
|
||||||
<text class="margin-lr-sm" style="flex-basis: 50%;">其他城市</text>
|
v-if="tabCur === 1 && index < 15" @click="chooseCategory(item)">
|
||||||
<view class="divider"/>
|
<view class="cu-avatar round"
|
||||||
</view>
|
:style="'width: 100rpx; height: 100rpx; background-image:url(' + item.cover + ');'">
|
||||||
<view>
|
</view>
|
||||||
<view class="margin-top-sm margin-lr-sm waterfall-grid">
|
<text>{{item.name}}</text>
|
||||||
<view @click="showDetails(item)" :key="item.goodsId" v-for="(item, index) in otherCityProductList" class="waterfall-grid-item">
|
</view>
|
||||||
<flow-goods-card :product="item"></flow-goods-card>
|
</view>
|
||||||
</view>
|
<!-- 细类 -->
|
||||||
</view>
|
<!-- <view class="cu-list grid no-border" :class="['col-5']" v-if="subCategories.length > 5">
|
||||||
<load-status-bar ref="loadStatusBar2" @loadMore="loadOtherCityProductPage"></load-status-bar>
|
<view class="cu-item" v-for="(item,index) in subCategories" :key="index"
|
||||||
|
v-if="index < subCategories.length && index > 4" @click="chooseCategory(item)">
|
||||||
|
<view :class="['cuIcon-' + item.cuIcon,'text-' + item.color]">
|
||||||
|
</view>
|
||||||
|
<text>{{item.goodsCategoryName}}</text>
|
||||||
|
</view>
|
||||||
|
</view> -->
|
||||||
|
<!-- 超值服务 -->
|
||||||
|
<!-- <vertical-goods-card ref="discountGoodsCard" :goodsInfos="discountGoods.goodsInfos"
|
||||||
|
:title="discountGoods.title"></vertical-goods-card> -->
|
||||||
|
<!-- 热门服务 -->
|
||||||
|
<!-- <vertical-card :list="hotServCategory" :multiPicMode="true" title="大家都在买"></vertical-card> -->
|
||||||
|
</view>
|
||||||
|
<!-- 当前城市服务列表 -->
|
||||||
|
<view class="text-gray text-lg text-center margin flex align-center">
|
||||||
|
<view class="divider" />
|
||||||
|
<text class="margin-lr-sm" style="flex-basis: 60%; color: #9E9E9E;">当前城市</text>
|
||||||
|
<view class="divider" />
|
||||||
|
</view>
|
||||||
|
<view>
|
||||||
|
<view class="margin-top-sm margin-lr-sm waterfall-grid">
|
||||||
|
<view @click="showDetails(item)" :key="item.goodsId" v-for="(item, index) in productList"
|
||||||
|
class="waterfall-grid-item">
|
||||||
|
<flow-goods-card :product="item"></flow-goods-card>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<load-status-bar ref="loadStatusBar1" @loadMore="loadProductPage"></load-status-bar>
|
||||||
|
</view>
|
||||||
|
<!-- 其他城市服务列表 -->
|
||||||
|
<view class="text-gray text-lg text-center margin flex align-center" style="padding-top: 60rpx;">
|
||||||
|
<view class="divider" />
|
||||||
|
<text class="margin-lr-sm" style="flex-basis: 50%;">其他城市</text>
|
||||||
|
<view class="divider" />
|
||||||
|
</view>
|
||||||
|
<view>
|
||||||
|
<view class="margin-top-sm margin-lr-sm waterfall-grid">
|
||||||
|
<view @click="showDetails(item)" :key="item.goodsId"
|
||||||
|
v-for="(item, index) in otherCityProductList" class="waterfall-grid-item">
|
||||||
|
<flow-goods-card :product="item"></flow-goods-card>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<load-status-bar ref="loadStatusBar2" @loadMore="loadOtherCityProductPage"></load-status-bar>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="occupancy-bottom-bar"></view>
|
||||||
|
<!-- 前往授权设置 -->
|
||||||
|
<view class="cu-modal" :class="isShowPrivSetting?'show':''">
|
||||||
|
<view class="cu-dialog">
|
||||||
|
<view class="padding-xl text-left">
|
||||||
|
<view>需先授权定位功能才可正常使用功能</view>
|
||||||
|
</view>
|
||||||
|
<view class="cu-bar bg-white">
|
||||||
|
<navigator class="modal-bottom-oper margin-0 flex-sub text-black" open-type="exit"
|
||||||
|
target="miniProgram">拒绝授权
|
||||||
|
</navigator>
|
||||||
|
<button class="cu-btn modal-bottom-oper margin-0 flex-sub text-main-color bg-white solid-left"
|
||||||
|
open-type="openSetting" @opensetting="authLocationCallback">前往授权</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="occupancy-bottom-bar"></view>
|
|
||||||
<!-- 前往授权设置 -->
|
<!-- <valid ref="validRef"></valid> -->
|
||||||
<view class="cu-modal" :class="isShowPrivSetting?'show':''">
|
</c-tabbar>
|
||||||
<view class="cu-dialog">
|
|
||||||
<view class="padding-xl text-left">
|
|
||||||
<view>需先授权定位功能才可正常使用功能</view>
|
|
||||||
</view>
|
|
||||||
<view class="cu-bar bg-white">
|
|
||||||
<navigator class="modal-bottom-oper margin-0 flex-sub text-black" open-type="exit" target="miniProgram">拒绝授权
|
|
||||||
</navigator>
|
|
||||||
<button class="cu-btn modal-bottom-oper margin-0 flex-sub text-main-color bg-white solid-left" open-type="openSetting" @opensetting="authLocationCallback">前往授权</button>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import verticalCard from '@/components/common-card/vertical-card.vue';
|
import verticalCard from '@/components/common-card/vertical-card.vue';
|
||||||
import loadStatusBar from '@/components/custom-bar/load-status-bar.vue';
|
import loadStatusBar from '@/components/custom-bar/load-status-bar.vue';
|
||||||
import flowGoodsCard from '@/components/goods-card/flow-goods-card.vue';
|
import flowGoodsCard from '@/components/goods-card/flow-goods-card.vue';
|
||||||
|
import CTabbar from '@/components/CTabbar.vue';
|
||||||
|
|
||||||
|
// import valid from './components/valid.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'index',
|
name: 'index',
|
||||||
components: {
|
components: {
|
||||||
verticalCard,
|
verticalCard,
|
||||||
loadStatusBar,
|
loadStatusBar,
|
||||||
flowGoodsCard
|
flowGoodsCard,
|
||||||
|
CTabbar,
|
||||||
|
// valid
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
scrollLeft: 0,
|
scrollLeft: 0,
|
||||||
dotStyle: true,
|
dotStyle: true,
|
||||||
swiperList: [],
|
swiperList: [],
|
||||||
tabCur: 0,
|
tabCur: 0,
|
||||||
categories: [],
|
categories: [],
|
||||||
subCategories: [],
|
subCategories: [],
|
||||||
hotServCategory: [],
|
hotServCategory: [],
|
||||||
hotFittingsCategory: [],
|
hotFittingsCategory: [],
|
||||||
discountGoods: {},
|
discountGoods: {},
|
||||||
InputBottom: 0,
|
InputBottom: 0,
|
||||||
searchInfo: {},
|
searchInfo: {},
|
||||||
areaList: [],
|
areaList: [],
|
||||||
areaMultiIndex: [0, 0],
|
areaMultiIndex: [0, 0],
|
||||||
productList: [],
|
productList: [],
|
||||||
otherCityProductList: [],
|
otherCityProductList: [],
|
||||||
pageNum: 0,
|
pageNum: 0,
|
||||||
pageSize: 0,
|
pageSize: 0,
|
||||||
otherCityProductPageNum: 0,
|
otherCityProductPageNum: 0,
|
||||||
otherCityProductPageSize: 0,
|
otherCityProductPageSize: 0,
|
||||||
isShowPrivSetting: false
|
isShowPrivSetting: false,
|
||||||
|
initParam: null
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
onLoad(option) {
|
||||||
|
this.initParam = option
|
||||||
|
uni.hideTabBar();
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.bindEvent();
|
this.bindEvent();
|
||||||
|
|
@ -173,31 +197,56 @@
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
this.offBindEvent();
|
this.offBindEvent();
|
||||||
},
|
},
|
||||||
async onReady() {
|
async onReady() {
|
||||||
// await this.$request.authAndGetLocation();
|
// await this.$request.authAndGetLocation();
|
||||||
// 定位当前城市
|
// 定位当前城市
|
||||||
await this.getCurAreaArr();
|
await this.getCurAreaArr();
|
||||||
|
uni.$emit('initValid', this.initParam)
|
||||||
|
},
|
||||||
|
async onShareAppMessage(e) {
|
||||||
|
let shareInfo = null;
|
||||||
|
if (e && e.target && e.target.dataset) {
|
||||||
|
shareInfo = e.target.dataset.shareInfo;
|
||||||
|
}
|
||||||
|
if (!this.curUserInfo) {
|
||||||
|
this.curUserInfo = await this.$request.getCurUserNoCache();
|
||||||
|
if (!this.curUserInfo) {
|
||||||
|
uni.showToast({
|
||||||
|
title: '请前往“我的”完成登录',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!shareInfo) {
|
||||||
|
shareInfo = {
|
||||||
|
title: '家政服务就找工圈子',
|
||||||
|
path: '/pages/index/home?distributor=' + this.curUserInfo.customerId,
|
||||||
|
imageUrl: 'http://gqz.opsoul.com/sys/group-selfie.png'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return shareInfo;
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async loadData() {
|
async loadData() {
|
||||||
this.initBasicData();
|
this.initBasicData();
|
||||||
// 加载区域信息
|
// 加载区域信息
|
||||||
await this.loadRegionList();
|
await this.loadRegionList();
|
||||||
// 加载服务商城热门类目
|
// 加载服务商城热门类目
|
||||||
let hotServCategoryRes = await this.$request.getHotCategory({
|
let hotServCategoryRes = await this.$request.getHotCategory({
|
||||||
type: 1
|
type: 1
|
||||||
});
|
});
|
||||||
this.hotServCategory = hotServCategoryRes.data;
|
this.hotServCategory = hotServCategoryRes.data;
|
||||||
// 加载配件商城热门类目
|
// 加载配件商城热门类目
|
||||||
let hotFittingsCategoryRes = await this.$request.getHotCategory({
|
let hotFittingsCategoryRes = await this.$request.getHotCategory({
|
||||||
type: 2
|
type: 2
|
||||||
});
|
});
|
||||||
this.hotFittingsCategory = hotFittingsCategoryRes.data;
|
this.hotFittingsCategory = hotFittingsCategoryRes.data;
|
||||||
// 加载品类
|
// 加载品类
|
||||||
this.loadCategoryList();
|
this.loadCategoryList();
|
||||||
// 加载当前定位城市的服务列表
|
// 加载当前定位城市的服务列表
|
||||||
this.loadProductPage();
|
this.loadProductPage();
|
||||||
// 加载其他城市的服务列表
|
// 加载其他城市的服务列表
|
||||||
this.loadOtherCityProductPage();
|
this.loadOtherCityProductPage();
|
||||||
|
|
||||||
this.swiperList = await this.$api.data('swiperList');
|
this.swiperList = await this.$api.data('swiperList');
|
||||||
|
|
@ -206,117 +255,123 @@
|
||||||
this.moduleBarInfos = await this.$api.data('moduleBarInfos');
|
this.moduleBarInfos = await this.$api.data('moduleBarInfos');
|
||||||
// this.hotGoods = await this.$api.data('hotGoods');
|
// this.hotGoods = await this.$api.data('hotGoods');
|
||||||
// this.discountGoods = await this.$api.data('discountGoods');
|
// this.discountGoods = await this.$api.data('discountGoods');
|
||||||
},
|
},
|
||||||
|
// authCallback() {
|
||||||
|
// this.$refs.validRef.loadData(this.initParam)
|
||||||
|
// },
|
||||||
bindEvent() {
|
bindEvent() {
|
||||||
uni.$on('clickCard', this.clickHotCategory);
|
uni.$on('clickCard', this.clickHotCategory);
|
||||||
|
// uni.$on('authCallback', this.authCallback);
|
||||||
},
|
},
|
||||||
offBindEvent() {
|
offBindEvent() {
|
||||||
uni.$off('clickCard');
|
uni.$off('clickCard');
|
||||||
},
|
// uni.$off('authCallback');
|
||||||
async authLocationCallback(res) {
|
|
||||||
if (res.detail.authSetting['scope.userLocation']) {
|
|
||||||
this.isShowPrivSetting = false;
|
|
||||||
await this.getCurAreaArr();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
async wxGetLocation() {
|
|
||||||
let _this = this;
|
|
||||||
// 通过 wx.getSetting 先查询一下用户是否授权了authScope
|
|
||||||
let res1 = await wx.getSetting();
|
|
||||||
if (res1) {
|
|
||||||
if (!res1.authSetting['scope.userLocation']) {
|
|
||||||
let res2 = await wx.getLocation({
|
|
||||||
type: 'gcj02',
|
|
||||||
fail: async (result) => {
|
|
||||||
console.log(result)
|
|
||||||
if (result.errno === 103 || result.errMsg === 'getLocation:fail auth deny') {
|
|
||||||
this.isShowPrivSetting = true;
|
|
||||||
} else {
|
|
||||||
// 用户授权
|
|
||||||
uni.showToast({
|
|
||||||
title: '请确认是否开启定位',
|
|
||||||
icon: 'none',
|
|
||||||
duration: 1500
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
success: async (result) => {
|
|
||||||
await _this.$request.storageLocation(result);
|
|
||||||
let areaArr = await _this.getCurAreaArr();
|
|
||||||
if (areaArr) {
|
|
||||||
_this.searchInfo.area = areaArr;
|
|
||||||
await _this.loadData();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
wx.getLocation({
|
|
||||||
type: 'gcj02',
|
|
||||||
fail: async (result) => {
|
|
||||||
console.log(result)
|
|
||||||
if (result.errCode === 2 || result.errCode === 404) {
|
|
||||||
uni.showToast({
|
|
||||||
title: '定位获取失败,请确认是否开启定位',
|
|
||||||
icon: 'none',
|
|
||||||
duration: 2500
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
uni.showToast({
|
|
||||||
title: '定位获取失败,请稍后重试',
|
|
||||||
icon: 'none',
|
|
||||||
duration: 2500
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
success: async (result) => {
|
|
||||||
await _this.$request.storageLocation(result);
|
|
||||||
let areaArr = await _this.getCurAreaArr();
|
|
||||||
if (areaArr) {
|
|
||||||
_this.searchInfo.area = areaArr;
|
|
||||||
await _this.loadData();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
async getCurAreaArr() {
|
|
||||||
let curLocation = uni.getStorageSync('curLocation');
|
|
||||||
if (curLocation && curLocation.updateTimes) {
|
|
||||||
let curTimes = new Date().getTime();
|
|
||||||
let deltaSeconds = curTimes - curLocation.updateTimes;
|
|
||||||
if (deltaSeconds <= 15 * 60 * 1000) {
|
|
||||||
this.searchInfo.area = curLocation.area;
|
|
||||||
this.loadData();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
await this.wxGetLocation();
|
|
||||||
},
|
|
||||||
async loadCategoryList() {
|
|
||||||
let res = await this.$request.getProductCategories();
|
|
||||||
this.categories = res[1].data.data;
|
|
||||||
this.tabSelect(null, this.categories[0]);
|
|
||||||
},
|
},
|
||||||
async loadRegionList() {
|
async authLocationCallback(res) {
|
||||||
|
if (res.detail.authSetting['scope.userLocation']) {
|
||||||
|
this.isShowPrivSetting = false;
|
||||||
|
await this.getCurAreaArr();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async wxGetLocation() {
|
||||||
|
let _this = this;
|
||||||
|
// 通过 wx.getSetting 先查询一下用户是否授权了authScope
|
||||||
|
let res1 = await wx.getSetting();
|
||||||
|
if (res1) {
|
||||||
|
if (!res1.authSetting['scope.userLocation']) {
|
||||||
|
let res2 = await wx.getLocation({
|
||||||
|
type: 'gcj02',
|
||||||
|
fail: async (result) => {
|
||||||
|
console.log(result)
|
||||||
|
if (result.errno === 103 || result.errMsg ===
|
||||||
|
'getLocation:fail auth deny') {
|
||||||
|
this.isShowPrivSetting = true;
|
||||||
|
} else {
|
||||||
|
// 用户授权
|
||||||
|
uni.showToast({
|
||||||
|
title: '请确认是否开启定位',
|
||||||
|
icon: 'none',
|
||||||
|
duration: 1500
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
success: async (result) => {
|
||||||
|
await _this.$request.storageLocation(result);
|
||||||
|
let areaArr = await _this.getCurAreaArr();
|
||||||
|
if (areaArr) {
|
||||||
|
_this.searchInfo.area = areaArr;
|
||||||
|
await _this.loadData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
wx.getLocation({
|
||||||
|
type: 'gcj02',
|
||||||
|
fail: async (result) => {
|
||||||
|
console.log(result)
|
||||||
|
if (result.errCode === 2 || result.errCode === 404) {
|
||||||
|
uni.showToast({
|
||||||
|
title: '定位获取失败,请确认是否开启定位',
|
||||||
|
icon: 'none',
|
||||||
|
duration: 2500
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
uni.showToast({
|
||||||
|
title: '定位获取失败,请稍后重试',
|
||||||
|
icon: 'none',
|
||||||
|
duration: 2500
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
success: async (result) => {
|
||||||
|
await _this.$request.storageLocation(result);
|
||||||
|
let areaArr = await _this.getCurAreaArr();
|
||||||
|
if (areaArr) {
|
||||||
|
_this.searchInfo.area = areaArr;
|
||||||
|
await _this.loadData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async getCurAreaArr() {
|
||||||
|
let curLocation = uni.getStorageSync('curLocation');
|
||||||
|
if (curLocation && curLocation.updateTimes) {
|
||||||
|
let curTimes = new Date().getTime();
|
||||||
|
let deltaSeconds = curTimes - curLocation.updateTimes;
|
||||||
|
if (deltaSeconds <= 15 * 60 * 1000) {
|
||||||
|
this.searchInfo.area = curLocation.area;
|
||||||
|
this.loadData();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await this.wxGetLocation();
|
||||||
|
},
|
||||||
|
async loadCategoryList() {
|
||||||
|
let res = await this.$request.getProductCategories();
|
||||||
|
this.categories = res[1].data.data;
|
||||||
|
this.tabSelect(null, this.categories[0]);
|
||||||
|
},
|
||||||
|
async loadRegionList() {
|
||||||
let area = this.searchInfo.area && this.searchInfo.area.length ? this.searchInfo.area : null
|
let area = this.searchInfo.area && this.searchInfo.area.length ? this.searchInfo.area : null
|
||||||
let regionList = await this.$request.areaListByStep({
|
let regionList = await this.$request.areaListByStep({
|
||||||
areaId: area == null ? null : area[0].areaId
|
areaId: area == null ? null : area[0].areaId
|
||||||
});
|
});
|
||||||
regionList = regionList.data;
|
regionList = regionList.data;
|
||||||
let subRegionList = [];
|
let subRegionList = [];
|
||||||
let subSubRegionList = [];
|
let subSubRegionList = [];
|
||||||
if (regionList && regionList.length > 0) {
|
if (regionList && regionList.length > 0) {
|
||||||
let params = {};
|
let params = {};
|
||||||
if (area != null) {
|
if (area != null) {
|
||||||
params = {
|
params = {
|
||||||
areaId: area[1].areaId,
|
areaId: area[1].areaId,
|
||||||
parentCode: area[0].areaId
|
parentCode: area[0].areaId
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
params = {
|
params = {
|
||||||
parentCode: regionList[0].areaCode
|
parentCode: regionList[0].areaCode
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
subRegionList = await this.$request.areaListByStep(params);
|
subRegionList = await this.$request.areaListByStep(params);
|
||||||
subRegionList = subRegionList.data;
|
subRegionList = subRegionList.data;
|
||||||
|
|
@ -325,23 +380,23 @@
|
||||||
subSubRegionList = await this.$request.areaListByStep({
|
subSubRegionList = await this.$request.areaListByStep({
|
||||||
parentCode: subRegionList[0].areaCode
|
parentCode: subRegionList[0].areaCode
|
||||||
});
|
});
|
||||||
subSubRegionList = subSubRegionList.data;
|
subSubRegionList = subSubRegionList.data;
|
||||||
let allAreaIdsOfSubSubRegionList = [];
|
let allAreaIdsOfSubSubRegionList = [];
|
||||||
subSubRegionList.forEach(region => {
|
subSubRegionList.forEach(region => {
|
||||||
allAreaIdsOfSubSubRegionList.push(region.areaId)
|
allAreaIdsOfSubSubRegionList.push(region.areaId)
|
||||||
})
|
})
|
||||||
let subSubRegionListWithAll = [{
|
let subSubRegionListWithAll = [{
|
||||||
areaIds: allAreaIdsOfSubSubRegionList,
|
areaIds: allAreaIdsOfSubSubRegionList,
|
||||||
areaId: subRegionList[0].areaId,
|
areaId: subRegionList[0].areaId,
|
||||||
isAll: true,
|
isAll: true,
|
||||||
areaName: subRegionList[0].areaName
|
areaName: subRegionList[0].areaName
|
||||||
}].concat(subSubRegionList);
|
}].concat(subSubRegionList);
|
||||||
subSubRegionList = subSubRegionListWithAll;
|
subSubRegionList = subSubRegionListWithAll;
|
||||||
}
|
}
|
||||||
this.areaList = [];
|
this.areaList = [];
|
||||||
// this.areaList.push(regionList);
|
// this.areaList.push(regionList);
|
||||||
this.areaList.push(subRegionList);
|
this.areaList.push(subRegionList);
|
||||||
this.areaList.push(subSubRegionList);
|
this.areaList.push(subSubRegionList);
|
||||||
this.searchInfo.area = [this.areaList[0][0], this.areaList[1][0]];
|
this.searchInfo.area = [this.areaList[0][0], this.areaList[1][0]];
|
||||||
},
|
},
|
||||||
regionChange(e) {
|
regionChange(e) {
|
||||||
|
|
@ -350,7 +405,7 @@
|
||||||
for (let i = 0; i < this.areaList.length; i++) {
|
for (let i = 0; i < this.areaList.length; i++) {
|
||||||
chosenArea.push(this.areaList[i][this.areaMultiIndex[i]]);
|
chosenArea.push(this.areaList[i][this.areaMultiIndex[i]]);
|
||||||
}
|
}
|
||||||
this.searchInfo.area = chosenArea;
|
this.searchInfo.area = chosenArea;
|
||||||
this.reloadProductPage();
|
this.reloadProductPage();
|
||||||
},
|
},
|
||||||
async regionColChange(e) {
|
async regionColChange(e) {
|
||||||
|
|
@ -384,38 +439,38 @@
|
||||||
// this.areaMultiIndex = [this.areaMultiIndex[0], colObj.value, 0];
|
// this.areaMultiIndex = [this.areaMultiIndex[0], colObj.value, 0];
|
||||||
// }
|
// }
|
||||||
},
|
},
|
||||||
async tabSelect(e, item) {
|
async tabSelect(e, item) {
|
||||||
this.tabCur = e == null ? 0 : e.currentTarget.dataset.index;
|
this.tabCur = e == null ? 0 : e.currentTarget.dataset.index;
|
||||||
this.scrollLeft = (this.tabCur - 1) * 60;
|
this.scrollLeft = (this.tabCur - 1) * 60;
|
||||||
|
|
||||||
let subSubTypeList = [];
|
let subSubTypeList = [];
|
||||||
for (let i = 0; i < item.child.length; i++) {
|
for (let i = 0; i < item.child.length; i++) {
|
||||||
let stopFlag = false;
|
let stopFlag = false;
|
||||||
let secondList = item.child[i].child;
|
let secondList = item.child[i].child;
|
||||||
if (secondList && secondList.length) {
|
if (secondList && secondList.length) {
|
||||||
for (let k = 0; k < secondList.length; k++) {
|
for (let k = 0; k < secondList.length; k++) {
|
||||||
let thirdList = secondList[k].child;
|
let thirdList = secondList[k].child;
|
||||||
if (thirdList && thirdList.length) {
|
if (thirdList && thirdList.length) {
|
||||||
for (let j = 0; j < thirdList.length; j++) {
|
for (let j = 0; j < thirdList.length; j++) {
|
||||||
subSubTypeList = subSubTypeList.concat(thirdList[j]);
|
subSubTypeList = subSubTypeList.concat(thirdList[j]);
|
||||||
if (subSubTypeList.length >= 15) {
|
if (subSubTypeList.length >= 15) {
|
||||||
subSubTypeList = subSubTypeList.slice(0, 15);
|
subSubTypeList = subSubTypeList.slice(0, 15);
|
||||||
stopFlag = true;
|
stopFlag = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (stopFlag) break;
|
if (stopFlag) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (stopFlag) break;
|
if (stopFlag) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
let subCategoryOpt = await this.$api.data('subCategories');
|
let subCategoryOpt = await this.$api.data('subCategories');
|
||||||
for(let i = 0; i < subSubTypeList.length; i++) {
|
for (let i = 0; i < subSubTypeList.length; i++) {
|
||||||
subSubTypeList[i]['cuIcon'] = subCategoryOpt[i].cuIcon;
|
subSubTypeList[i]['cuIcon'] = subCategoryOpt[i].cuIcon;
|
||||||
subSubTypeList[i]['color'] = subCategoryOpt[i].color;
|
subSubTypeList[i]['color'] = subCategoryOpt[i].color;
|
||||||
}
|
}
|
||||||
this.subCategories = subSubTypeList;
|
this.subCategories = subSubTypeList;
|
||||||
},
|
},
|
||||||
chooseCategory(item) {
|
chooseCategory(item) {
|
||||||
|
|
@ -433,87 +488,90 @@
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
clickHotCategory(item) {
|
clickHotCategory(item) {
|
||||||
let params = {
|
let params = {
|
||||||
category: item
|
category: item
|
||||||
};
|
};
|
||||||
uni.navigateTo({
|
uni.navigateTo({
|
||||||
url: '/pages/product/filtered-products?params=' + encodeURIComponent(JSON.stringify(params))
|
url: '/pages/product/filtered-products?params=' + encodeURIComponent(JSON.stringify(params))
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
showProductCategories() {
|
showProductCategories() {
|
||||||
uni.navigateTo({
|
uni.navigateTo({
|
||||||
url: '/pages/product/product-category'
|
url: '/pages/product/product-category'
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
/* 底部当前城市服务列表 start */
|
/* 底部当前城市服务列表 start */
|
||||||
initBasicData() {
|
initBasicData() {
|
||||||
this.pageNum = this.$globalData.initPageNum;
|
this.pageNum = this.$globalData.initPageNum;
|
||||||
this.pageSize = this.$globalData.initPageSize;
|
this.pageSize = this.$globalData.initPageSize;
|
||||||
this.otherCityProductPageNum = this.$globalData.initPageNum;
|
this.otherCityProductPageNum = this.$globalData.initPageNum;
|
||||||
this.otherCityProductPageSize = this.$globalData.initPageSize;
|
this.otherCityProductPageSize = this.$globalData.initPageSize;
|
||||||
this.productList = [];
|
this.productList = [];
|
||||||
this.otherCityProductList = [];
|
this.otherCityProductList = [];
|
||||||
},
|
},
|
||||||
showDetails(productItem) {
|
showDetails(productItem) {
|
||||||
let params = {
|
let params = {
|
||||||
goodsId: productItem.goodsId
|
goodsId: productItem.goodsId
|
||||||
}
|
}
|
||||||
uni.navigateTo({
|
uni.navigateTo({
|
||||||
url: '/pages/product/product-detail?params=' + encodeURIComponent(JSON.stringify(params))
|
url: '/pages/product/product-detail?params=' + encodeURIComponent(JSON.stringify(params))
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
async reloadProductPage() {
|
async reloadProductPage() {
|
||||||
this.initBasicData();
|
this.initBasicData();
|
||||||
this.loadProductPage();
|
this.loadProductPage();
|
||||||
this.loadOtherCityProductPage();
|
this.loadOtherCityProductPage();
|
||||||
},
|
},
|
||||||
async loadProductPage(params = {
|
async loadProductPage(params = {
|
||||||
areaId: this.searchInfo.area && this.searchInfo.area.length ? this.searchInfo.area[this.searchInfo.area.length - 1].areaId : null
|
areaId: this.searchInfo.area && this.searchInfo.area.length ? this.searchInfo.area[this.searchInfo
|
||||||
}, loadStatusBarRefName = "loadStatusBar1", resContainer = "productList", pageNumName = "pageNum", pageSizeName = "pageSize") {
|
.area.length - 1].areaId : null
|
||||||
if (!params.exceptParentAreaId && this.searchInfo.area
|
}, loadStatusBarRefName = "loadStatusBar1", resContainer = "productList", pageNumName = "pageNum",
|
||||||
&& this.searchInfo.area.length && this.searchInfo.area[this.searchInfo.area.length - 1].isAll) {
|
pageSizeName = "pageSize") {
|
||||||
params.areaIds = this.searchInfo.area[this.searchInfo.area.length - 1].areaIds;
|
if (!params.exceptParentAreaId && this.searchInfo.area &&
|
||||||
params.areaId = null;
|
this.searchInfo.area.length && this.searchInfo.area[this.searchInfo.area.length - 1].isAll) {
|
||||||
}
|
params.areaIds = this.searchInfo.area[this.searchInfo.area.length - 1].areaIds;
|
||||||
params.pageNum = this[pageNumName];
|
params.areaId = null;
|
||||||
params.pageSize = this[pageSizeName];
|
}
|
||||||
params.status = 0;
|
params.pageNum = this[pageNumName];
|
||||||
this.$refs[loadStatusBarRefName].showLoading();
|
params.pageSize = this[pageSizeName];
|
||||||
try {
|
params.status = 0;
|
||||||
let res = await this.$request.qryProductPage(params);
|
this.$refs[loadStatusBarRefName].showLoading();
|
||||||
let rowsLength = res[1].data.rows.length;
|
try {
|
||||||
if (rowsLength > 0) {
|
let res = await this.$request.qryProductPage(params);
|
||||||
this[resContainer] = this[resContainer].concat(res[1].data.rows);
|
let rowsLength = res[1].data.rows.length;
|
||||||
console.log(this[resContainer])
|
if (rowsLength > 0) {
|
||||||
this[pageNumName]++;
|
this[resContainer] = this[resContainer].concat(res[1].data.rows);
|
||||||
if (rowsLength === this[pageSizeName]) {
|
console.log(this[resContainer])
|
||||||
this.$refs[loadStatusBarRefName].showLoadMore();
|
this[pageNumName]++;
|
||||||
return;
|
if (rowsLength === this[pageSizeName]) {
|
||||||
}
|
this.$refs[loadStatusBarRefName].showLoadMore();
|
||||||
}
|
return;
|
||||||
this.$refs[loadStatusBarRefName].showLoadOver();
|
}
|
||||||
} catch (e) {
|
}
|
||||||
console.error(e)
|
this.$refs[loadStatusBarRefName].showLoadOver();
|
||||||
this.$refs[loadStatusBarRefName].showLoadErr();
|
} catch (e) {
|
||||||
}
|
console.error(e)
|
||||||
},
|
this.$refs[loadStatusBarRefName].showLoadErr();
|
||||||
/* 底部当前城市服务列表 end */
|
}
|
||||||
/* 其他城市服务列表 start */
|
},
|
||||||
loadOtherCityProductPage() {
|
/* 底部当前城市服务列表 end */
|
||||||
this.loadProductPage({
|
/* 其他城市服务列表 start */
|
||||||
exceptParentAreaId: this.searchInfo.area && this.searchInfo.area.length ? this.searchInfo.area[1].areaId : null
|
loadOtherCityProductPage() {
|
||||||
}, "loadStatusBar2", "otherCityProductList", "otherCityProductPageNum", "otherCityProductPageSize")
|
this.loadProductPage({
|
||||||
}
|
exceptParentAreaId: this.searchInfo.area && this.searchInfo.area.length ? this.searchInfo.area[
|
||||||
|
1].areaId : null
|
||||||
|
}, "loadStatusBar2", "otherCityProductList", "otherCityProductPageNum", "otherCityProductPageSize")
|
||||||
|
}
|
||||||
/* 其他城市服务列表 end */
|
/* 其他城市服务列表 end */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.screen-swiper {
|
.screen-swiper {
|
||||||
height: 500rpx;
|
height: 500rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cu-list+.cu-list {
|
.cu-list+.cu-list {
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
}
|
}
|
||||||
|
|
@ -524,27 +582,27 @@
|
||||||
|
|
||||||
.hot-sub-category .cu-item .hot-sub-category-icon {
|
.hot-sub-category .cu-item .hot-sub-category-icon {
|
||||||
font-size: 80rpx;
|
font-size: 80rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.modal-bottom-oper {
|
.modal-bottom-oper {
|
||||||
height: 70rpx;
|
height: 70rpx;
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
|
||||||
|
|
||||||
.waterfall-grid {
|
|
||||||
/* column-count: 2;
|
|
||||||
column-gap: 15rpx; */
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
|
|
||||||
.waterfall-grid-item {
|
|
||||||
/* break-inside: avoid;
|
|
||||||
margin-bottom: 15rpx; */
|
|
||||||
width: 49%;
|
|
||||||
margin-bottom: 15rpx;
|
|
||||||
}
|
}
|
||||||
</style>
|
|
||||||
|
.waterfall-grid {
|
||||||
|
/* column-count: 2;
|
||||||
|
column-gap: 15rpx; */
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.waterfall-grid-item {
|
||||||
|
/* break-inside: avoid;
|
||||||
|
margin-bottom: 15rpx; */
|
||||||
|
width: 49%;
|
||||||
|
margin-bottom: 15rpx;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
|
<c-tabbar :current="3">
|
||||||
<view class="margin-bottom-lg">
|
<view class="margin-bottom-lg">
|
||||||
<!-- 顶部操作条 -->
|
<!-- 顶部操作条 -->
|
||||||
<cu-custom :bgColor="'bg-main-color'">
|
<cu-custom :bgColor="'bg-main-color'">
|
||||||
|
|
@ -6,21 +7,48 @@
|
||||||
</cu-custom>
|
</cu-custom>
|
||||||
<bg-toast :icon="'repair'" :msg="'开发中'"></bg-toast>
|
<bg-toast :icon="'repair'" :msg="'开发中'"></bg-toast>
|
||||||
</view>
|
</view>
|
||||||
|
</c-tabbar>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import bgToast from '@/components/default-toast/bg-toast.vue';
|
import bgToast from '@/components/default-toast/bg-toast.vue';
|
||||||
|
import CTabbar from '@/components/CTabbar.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'msgPage',
|
name: 'msgPage',
|
||||||
components: {
|
components: {
|
||||||
bgToast
|
bgToast,
|
||||||
|
CTabbar
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
async onShareAppMessage(e) {
|
||||||
|
let shareInfo = null;
|
||||||
|
if (e && e.target && e.target.dataset) {
|
||||||
|
shareInfo = e.target.dataset.shareInfo;
|
||||||
|
}
|
||||||
|
if (!this.curUserInfo) {
|
||||||
|
this.curUserInfo = await this.$request.getCurUserNoCache();
|
||||||
|
if (!this.curUserInfo) {
|
||||||
|
uni.showToast({
|
||||||
|
title: '请前往“我的”完成登录',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!shareInfo) {
|
||||||
|
shareInfo = {
|
||||||
|
title: '家政服务就找工圈子',
|
||||||
|
path: '/pages/index/home?distributor=' + this.curUserInfo.customerId,
|
||||||
|
imageUrl: 'http://gqz.opsoul.com/sys/group-selfie.png'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return shareInfo;
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<view>
|
<c-tabbar :current="4">
|
||||||
<!-- 顶部头像栏 -->
|
<!-- 顶部头像栏 -->
|
||||||
<view class="padding bg-gradual-color"
|
<view class="padding bg-gradual-color"
|
||||||
:style="'padding-top: ' + pageContentTop + 'px; padding-bottom: 100rpx;'">
|
:style="'padding-top: ' + pageContentTop + 'px; padding-bottom: 100rpx;'">
|
||||||
|
|
@ -301,17 +301,18 @@
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</c-tabbar>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// import appInviteQrcode from '@/pages/my/app-invite-qrcode.vue';
|
// import appInviteQrcode from '@/pages/my/app-invite-qrcode.vue';
|
||||||
|
import CTabbar from '@/components/CTabbar.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'personal-center',
|
name: 'personal-center',
|
||||||
// components: {
|
components: {
|
||||||
// appInviteQrcode
|
CTabbar
|
||||||
// },
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
pageContentTop: this.CustomBar,
|
pageContentTop: this.CustomBar,
|
||||||
|
|
@ -387,6 +388,30 @@
|
||||||
},
|
},
|
||||||
onReady() {
|
onReady() {
|
||||||
this.loadData();
|
this.loadData();
|
||||||
|
},
|
||||||
|
async onShareAppMessage(e) {
|
||||||
|
let shareInfo = null;
|
||||||
|
if (e && e.target && e.target.dataset) {
|
||||||
|
shareInfo = e.target.dataset.shareInfo;
|
||||||
|
}
|
||||||
|
if (!this.curUserInfo) {
|
||||||
|
this.curUserInfo = await this.$request.getCurUserNoCache();
|
||||||
|
if (!this.curUserInfo) {
|
||||||
|
uni.showToast({
|
||||||
|
title: '请前往“我的”完成登录',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!shareInfo) {
|
||||||
|
shareInfo = {
|
||||||
|
title: '家政服务就找工圈子',
|
||||||
|
path: '/pages/index/home?distributor=' + this.curUserInfo.customerId,
|
||||||
|
imageUrl: 'http://gqz.opsoul.com/sys/group-selfie.png'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return shareInfo;
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async loadData() {
|
async loadData() {
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -179,7 +179,7 @@
|
||||||
<view class="margin-lr-sm margin-top-sm padding bg-white">
|
<view class="margin-lr-sm margin-top-sm padding bg-white">
|
||||||
<view class="flex justify-between align-center">
|
<view class="flex justify-between align-center">
|
||||||
<view class="flex justify-start align-center">
|
<view class="flex justify-start align-center">
|
||||||
<view class="cu-avatar round" :style="'background-image:url(' + shopInfo.workerLogoUrl + ');'"></view>
|
<view class="cu-avatar round" :style="'background-image:url(' + defaultHead(shopInfo.workerLogoUrl) + ');'"></view>
|
||||||
<view class="content flex-sub margin-lr-sm">
|
<view class="content flex-sub margin-lr-sm">
|
||||||
<view class="text-black">{{shopInfo.name}}</view>
|
<view class="text-black">{{shopInfo.name}}</view>
|
||||||
<uni-rate :size="15" :readonly="true" allow-half :value="5" />
|
<uni-rate :size="15" :readonly="true" allow-half :value="5" />
|
||||||
|
|
@ -196,7 +196,7 @@
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<!-- 底部操作条 -->
|
<!-- 底部操作条 -->
|
||||||
<view class="cu-bar bg-white tabbar border shop fixed-bottom-bar">
|
<view class="cu-bar bg-white tabbar border shop fixed-bottom-bar" style="flex-direction: row;">
|
||||||
<view class="action" @click="showIndex">
|
<view class="action" @click="showIndex">
|
||||||
<view class="cuIcon-homefill"></view>
|
<view class="cuIcon-homefill"></view>
|
||||||
首页
|
首页
|
||||||
|
|
@ -443,6 +443,12 @@
|
||||||
uni.navigateTo({
|
uni.navigateTo({
|
||||||
url: '/pages/index/index'
|
url: '/pages/index/index'
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
defaultHead(url) {
|
||||||
|
if(url === 'https://thirdwx.qlogo.cn/mmopen/vi_32/POgEwh4mIHO4nibH0KlMECNjjGxQUq24ZEaGT4poC6icRiccVGKSyXwibcPq4BWmiaIGuG1icwxaQX6grC9VemZoJ8rg/132') {
|
||||||
|
return 'http://gqz.opsoul.com/2741722238771_.pic.jpg'
|
||||||
|
}
|
||||||
|
return url
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
<view class="bg-white padding solid-bottom">
|
<view class="bg-white padding solid-bottom">
|
||||||
<view class="flex justify-start">
|
<view class="flex justify-start">
|
||||||
<view class="cu-avatar round"
|
<view class="cu-avatar round"
|
||||||
:style="'background-image:url(' + shopInfo.workerLogoUrl + '); width: 130rpx; height: 130rpx;'">
|
:style="'background-image:url(' + defaultHead(shopInfo.workerLogoUrl) + '); width: 130rpx; height: 130rpx;'">
|
||||||
</view>
|
</view>
|
||||||
<view class="margin-left-sm flex-column-between text-beside-avatar">
|
<view class="margin-left-sm flex-column-between text-beside-avatar">
|
||||||
<view class="text-black text-xl">{{shopInfo.name}}</view>
|
<view class="text-black text-xl">{{shopInfo.name}}</view>
|
||||||
|
|
@ -286,6 +286,13 @@
|
||||||
},
|
},
|
||||||
showAllArea(index) {
|
showAllArea(index) {
|
||||||
this.isShowAllAreaCurCity = !this.isShowAllAreaCurCity;
|
this.isShowAllAreaCurCity = !this.isShowAllAreaCurCity;
|
||||||
|
},
|
||||||
|
|
||||||
|
defaultHead(url) {
|
||||||
|
if(url === 'https://thirdwx.qlogo.cn/mmopen/vi_32/POgEwh4mIHO4nibH0KlMECNjjGxQUq24ZEaGT4poC6icRiccVGKSyXwibcPq4BWmiaIGuG1icwxaQX6grC9VemZoJ8rg/132') {
|
||||||
|
return 'http://gqz.opsoul.com/2741722238771_.pic.jpg'
|
||||||
|
}
|
||||||
|
return url
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,76 @@
|
||||||
|
## 2.0.0(2023-11-14)
|
||||||
|
1、新增切换拦截返回当前点击index
|
||||||
|
2、新增自动读取主页面配置功能
|
||||||
|
3、优化部分代码结构实现
|
||||||
|
注意:代码重构优化,2.0.0版本不支持老版本兼容
|
||||||
|
## 1.3.3(2023-02-27)
|
||||||
|
修复openType类型为navigateTo时,页面返回,重新点击不响应问题
|
||||||
|
## 1.3.2(2023-02-27)
|
||||||
|
修改占位空间点击事件遮挡问题
|
||||||
|
## 1.3.1(2023-02-27)
|
||||||
|
1、新增页面打开方式,可以自定义每个tabbarItem的点击打开方式
|
||||||
|
2、新增tabbarHeight参数,方便你直接使用参数控制tabbar高度
|
||||||
|
## 1.3.0(2023-02-21)
|
||||||
|
新增ref方法若干,优化使用说明文档
|
||||||
|
## 1.2.9(2023-02-21)
|
||||||
|
修改safe计算,使用原生css,抛弃原始计算耗时能力
|
||||||
|
## 1.2.8(2023-02-20)
|
||||||
|
修正文档使用说明
|
||||||
|
## 1.2.7(2023-02-20)
|
||||||
|
1、新增角标显示
|
||||||
|
2、新增setTabBarBadge,reLoad方法
|
||||||
|
## 1.2.6(2023-02-13)
|
||||||
|
修复判断safebottom底部安全距离数值写死问题
|
||||||
|
## 1.2.5(2023-01-12)
|
||||||
|
1、修复默认初始高度闪烁问题,不在使用计算,直接默认
|
||||||
|
2、修复上个版本遗留current选中问题
|
||||||
|
3、修复safeBottom底部判断错误问题
|
||||||
|
4、更新使用说明文档
|
||||||
|
## 1.2.4(2023-01-09)
|
||||||
|
新增文档说明,增加示例项目页面
|
||||||
|
## 1.2.3(2022-12-14)
|
||||||
|
修复外部不跳转页面修改current,组件不响应bug
|
||||||
|
## 1.2.2(2022-12-14)
|
||||||
|
新增click事件,click事件会优先于任何事件
|
||||||
|
## 1.2.1(2022-12-09)
|
||||||
|
修改文档使用说明,路由拦截有平台兼容性,暂时无法解决,平台原生不支持
|
||||||
|
## 1.2.0(2022-12-09)
|
||||||
|
新增插槽,可以自定义凸起导航,优化文档使用说明
|
||||||
|
## 1.1.9(2022-12-06)
|
||||||
|
修复iconPath图片路径为网络路径判断错误问题
|
||||||
|
## 1.1.7(2022-12-01)
|
||||||
|
优化部分机器计算错误问题
|
||||||
|
## 1.1.6(2022-12-01)
|
||||||
|
修改高度计算错误问题
|
||||||
|
## 1.1.5(2022-12-01)
|
||||||
|
修复各别设备上高度计算有误问题
|
||||||
|
## 1.1.4(2022-11-25)
|
||||||
|
修复vue2版本在微信小程序上不支持:style传入参数bug,优化参数错误逻辑
|
||||||
|
## 1.1.3(2022-11-24)
|
||||||
|
修复native模式borderStyle样式丢失问题
|
||||||
|
## 1.1.2(2022-11-24)
|
||||||
|
修改描述文档说明,修改插件描述信息
|
||||||
|
## 1.1.1(2022-11-24)
|
||||||
|
优化使用说明文档
|
||||||
|
## 1.1.0(2022-11-24)
|
||||||
|
极度简化native模式,页面只需要引入组件即可,任何操作都不需要
|
||||||
|
## 1.0.9(2022-11-24)
|
||||||
|
修复native模式下,fill忘记计算高度.
|
||||||
|
## 1.0.8(2022-11-24)
|
||||||
|
优化native模式,简化参数数量,使用更简单
|
||||||
|
## 1.0.7(2022-11-24)
|
||||||
|
新增native配置,可以兼容原生tabbar,新增beforeChange,可自行根据要求自己兼容路由守卫
|
||||||
|
## 1.0.6(2022-11-23)
|
||||||
|
修改文档描述错误
|
||||||
|
## 1.0.5(2022-11-23)
|
||||||
|
修复fill高度遗漏安全距离问题,文档使用说明优化更新
|
||||||
|
## 1.0.4(2022-11-23)
|
||||||
|
优化配置选项,提取当前选中项,新增fixed配置
|
||||||
|
## 1.0.3(2022-11-14)
|
||||||
|
添加上阴影效果,修复由于去除了上线条,造成如果内容如果是白色,tabbar会和内容高度重合的问题
|
||||||
|
## 1.0.2(2022-11-14)
|
||||||
|
修改说明文档,更加详细备注说明
|
||||||
|
## 1.0.1(2022-11-14)
|
||||||
|
新增当前选中项class名,方便用户直接样式覆盖
|
||||||
|
## 1.0.0(2022-11-14)
|
||||||
|
第一个自定义tabbar版本
|
||||||
|
|
@ -0,0 +1,525 @@
|
||||||
|
<template>
|
||||||
|
<view class="m-tabbar-box" :style="tabbarBoxStyle" v-if="isShowTabBar">
|
||||||
|
<view class="m-tabbar__fill" v-if="fill || native" :class="{'m-tabbar__safe': (safeBottom || native)}"
|
||||||
|
:style="tabbarFillStyle" />
|
||||||
|
<view id="m-tabbar" class="m-tabbar"
|
||||||
|
:class="{'fixed': (fixed || native), 'm-tabbar__safe': (safeBottom || native)}" :style="tabbarStyle">
|
||||||
|
<view class="m-tabbar__border" v-if="borderStyle === 'black'" />
|
||||||
|
<!-- tabbar border -->
|
||||||
|
<view class="m-tabbar__flex">
|
||||||
|
<view class="m-tabbar__item" @tap="_tabChange(index)" v-for="(item, index) in tabbarList" :key="index"
|
||||||
|
:class="{
|
||||||
|
'm-tabbar__item__active': index === currentIndex,
|
||||||
|
}">
|
||||||
|
<slot :name="`tabbar_index_${index}`">
|
||||||
|
<view class="m-tabbar__icon">
|
||||||
|
<view class="m-tabbar__badge" v-if="item.dot">{{item.dot}}</view>
|
||||||
|
<!-- <image :src="currentIndex === index ? item.selectedIconPath : item.iconPath"
|
||||||
|
class="m-tabbar__icon_img" /> -->
|
||||||
|
<text :class="['cuIcon-' + item.cuIcon, currentIndex === index ? 'text-main-color' : 'text-gray']"></text>
|
||||||
|
</view>
|
||||||
|
<view class="m-tabbar__label"
|
||||||
|
:style="{'color': index === currentIndex ? tabbarConfig.selectedColor : tabbarConfig.color }">
|
||||||
|
{{ item.text }}
|
||||||
|
</view>
|
||||||
|
</slot>
|
||||||
|
</view>
|
||||||
|
<!-- tabbar item -->
|
||||||
|
</view>
|
||||||
|
<!-- tabbar item box -->
|
||||||
|
</view>
|
||||||
|
<!-- tabbar block -->
|
||||||
|
</view>
|
||||||
|
<!-- tabbar box -->
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// style转为string
|
||||||
|
const obj2strStyle = (obj) => {
|
||||||
|
let style = ''
|
||||||
|
for (let key in obj) {
|
||||||
|
style += `${key}:${obj[key]};`
|
||||||
|
}
|
||||||
|
return style
|
||||||
|
}
|
||||||
|
|
||||||
|
// 自动填充路径
|
||||||
|
const padFirstSymbol = (str, smb) => {
|
||||||
|
if (str.startsWith(smb) || str.startsWith('http')) {
|
||||||
|
return str
|
||||||
|
}
|
||||||
|
return `/${str}`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 替换原生路径问题
|
||||||
|
const replaceTabbarList = (list) => {
|
||||||
|
if (!list.length > 0) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
return list.map(item => {
|
||||||
|
if (item.iconPath) {
|
||||||
|
item.iconPath = padFirstSymbol(item.iconPath, '/')
|
||||||
|
}
|
||||||
|
if (item.pagePath) {
|
||||||
|
item.pagePath = padFirstSymbol(item.pagePath, '/')
|
||||||
|
}
|
||||||
|
if (item.selectedIconPath) {
|
||||||
|
item.selectedIconPath = padFirstSymbol(item.selectedIconPath, '/')
|
||||||
|
}
|
||||||
|
return item
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置缓存,方便重复调用方法
|
||||||
|
const setTabbarStorage = (key, value, name) => {
|
||||||
|
try {
|
||||||
|
uni.setStorageSync(`mTab_${key}_${name}`, value)
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 读取缓存
|
||||||
|
const getTabbarStorage = (key, name) => {
|
||||||
|
try {
|
||||||
|
const value = uni.getStorageSync(`mTab_${key}_${name}`)
|
||||||
|
if (value) {
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
return ''
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
import PageConfig from '@/pages.json'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
emits: ['change', 'click'],
|
||||||
|
props: {
|
||||||
|
// 使用原生配置自动生成
|
||||||
|
native: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
// 当前选择下标,默认0开始
|
||||||
|
current: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: 0
|
||||||
|
},
|
||||||
|
// tabbar配置项
|
||||||
|
tabbar: {
|
||||||
|
type: Object,
|
||||||
|
default () {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 是否固定在底部
|
||||||
|
fixed: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
// 是否自动填充底部
|
||||||
|
fill: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
// 显示层级
|
||||||
|
zIndex: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: 9999
|
||||||
|
},
|
||||||
|
// 是否自动规避底部安全距离
|
||||||
|
safeBottom: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
// 切换时拦截事件(有兼容性,部分平台不支持)
|
||||||
|
beforeChange: {
|
||||||
|
type: Function,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
// 自定义tabbar高度,单位rpx
|
||||||
|
tabbarHeight: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: 100
|
||||||
|
},
|
||||||
|
// 自定义tabbar的name,方便读取默认tabbar
|
||||||
|
name: {
|
||||||
|
type: String,
|
||||||
|
default: 'custom'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
isShowTabBar: false, //是否显示导航
|
||||||
|
currentIndex: 0, //当前值
|
||||||
|
beforeData: {}, //切换前值
|
||||||
|
initTabbarConfig: {},
|
||||||
|
isReload: false //uni不支持computed的get set,使用reload无感重置刷新
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
current(val) {
|
||||||
|
this.currentIndex = val * 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
tabbarConfig() {
|
||||||
|
const {
|
||||||
|
isReload,
|
||||||
|
native,
|
||||||
|
initTabbarConfig: tabbar
|
||||||
|
} = this
|
||||||
|
if(isReload){}
|
||||||
|
// 如果是native模式,直接读取执行
|
||||||
|
if (native) {
|
||||||
|
if (!tabbar) {
|
||||||
|
console.error('Native mode, Pages.json no tabbar config')
|
||||||
|
return {
|
||||||
|
borderStyle: 'black',
|
||||||
|
list: []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tabbar
|
||||||
|
}
|
||||||
|
// 如果没有配置tabbar,会尝试在缓存读取
|
||||||
|
if (!tabbar.color) {
|
||||||
|
return this._getDefaultTabbar()
|
||||||
|
}
|
||||||
|
return tabbar
|
||||||
|
},
|
||||||
|
tabbarList() {
|
||||||
|
const {
|
||||||
|
isReload,
|
||||||
|
tabbarConfig: {
|
||||||
|
list
|
||||||
|
}
|
||||||
|
} = this
|
||||||
|
if(isReload){}
|
||||||
|
if (!list) {
|
||||||
|
console.error('No tabbar config')
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
return replaceTabbarList(list)
|
||||||
|
},
|
||||||
|
borderStyle() {
|
||||||
|
const {
|
||||||
|
isReload,
|
||||||
|
borderStyle
|
||||||
|
} = this.tabbarConfig
|
||||||
|
if(isReload){}
|
||||||
|
return borderStyle
|
||||||
|
},
|
||||||
|
tabbarBoxStyle() {
|
||||||
|
const {
|
||||||
|
isReload,
|
||||||
|
zIndex
|
||||||
|
} = this
|
||||||
|
if(isReload){}
|
||||||
|
return obj2strStyle({
|
||||||
|
'z-index': zIndex,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
tabbarFillStyle() {
|
||||||
|
const {
|
||||||
|
isReload,
|
||||||
|
tabbarHeight
|
||||||
|
} = this
|
||||||
|
if(isReload){}
|
||||||
|
return obj2strStyle({
|
||||||
|
'height': `${tabbarHeight}rpx`
|
||||||
|
})
|
||||||
|
},
|
||||||
|
tabbarStyle() {
|
||||||
|
const {
|
||||||
|
isReload,
|
||||||
|
tabbarHeight,
|
||||||
|
tabbarConfig: {
|
||||||
|
backgroundColor
|
||||||
|
}
|
||||||
|
} = this
|
||||||
|
if(isReload){}
|
||||||
|
return obj2strStyle({
|
||||||
|
'height': `${tabbarHeight}rpx`,
|
||||||
|
'background-color': backgroundColor || '#fff',
|
||||||
|
})
|
||||||
|
},
|
||||||
|
tabbarItemStyle() {
|
||||||
|
const {
|
||||||
|
isReload,
|
||||||
|
currentIndex,
|
||||||
|
tabbarConfig: {
|
||||||
|
color,
|
||||||
|
selectedColor
|
||||||
|
}
|
||||||
|
} = this
|
||||||
|
if(isReload){}
|
||||||
|
return obj2strStyle({
|
||||||
|
'color': currentIndex ? selectedColor : color
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
const {
|
||||||
|
tabbar,
|
||||||
|
native
|
||||||
|
} = this
|
||||||
|
const pageTabbar = PageConfig.tabBar
|
||||||
|
this.initTabbarConfig = native ? pageTabbar : tabbar
|
||||||
|
console.log(this.name)
|
||||||
|
this._initTabbar()
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
console.log(this.currentIndex);
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
_initTabbar() {
|
||||||
|
const {
|
||||||
|
current,
|
||||||
|
fill,
|
||||||
|
native,
|
||||||
|
tabbarList
|
||||||
|
} = this
|
||||||
|
this.currentIndex = current * 1
|
||||||
|
|
||||||
|
if (native && tabbarList.length > 0) {
|
||||||
|
const currentPage = `/${getCurrentPages()[0].route}`
|
||||||
|
const currentIndex = tabbarList.findIndex(item => item.pagePath === currentPage)
|
||||||
|
this.currentIndex = currentIndex
|
||||||
|
uni.hideTabBar()
|
||||||
|
}
|
||||||
|
setTimeout(() => {
|
||||||
|
this.isShowTabBar = true
|
||||||
|
})
|
||||||
|
this._setTabbarStorage('tabbarConfig')
|
||||||
|
},
|
||||||
|
_setTabbarStorage(key){
|
||||||
|
setTabbarStorage(key, this.tabbarConfig, this.name)
|
||||||
|
this._setReload()
|
||||||
|
},
|
||||||
|
_getDefaultTabbar() {
|
||||||
|
return getTabbarStorage('tabbarConfig', this.name)
|
||||||
|
},
|
||||||
|
_checkMaxIndex(index) {
|
||||||
|
const {
|
||||||
|
tabbarConfig: {
|
||||||
|
list
|
||||||
|
}
|
||||||
|
} = this
|
||||||
|
if (list.length < 1) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (!list[index]) {
|
||||||
|
console.error('Max tabbar index')
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
},
|
||||||
|
_setReload(){
|
||||||
|
this.isReload = true
|
||||||
|
setTimeout(()=>{
|
||||||
|
this.isReload = false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
setTabBarBadge(obj) {
|
||||||
|
const {
|
||||||
|
index,
|
||||||
|
text
|
||||||
|
} = obj
|
||||||
|
if (this._checkMaxIndex(index)) {
|
||||||
|
this.tabbarConfig.list[index].dot = text
|
||||||
|
this._setTabbarStorage('tabbarConfig')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setTabBarItem(obj) {
|
||||||
|
const {
|
||||||
|
index,
|
||||||
|
text,
|
||||||
|
pagePath: newPagePath,
|
||||||
|
iconPath,
|
||||||
|
selectedIconPath
|
||||||
|
} = obj
|
||||||
|
const {
|
||||||
|
pagePath: oldPagePath
|
||||||
|
} = this.tabbarConfig.list[index]
|
||||||
|
if (this._checkMaxIndex(index)) {
|
||||||
|
this.tabbarConfig.list[index] = {
|
||||||
|
pagePath: newPagePath ? newPagePath : oldPagePath,
|
||||||
|
text,
|
||||||
|
iconPath,
|
||||||
|
selectedIconPath
|
||||||
|
}
|
||||||
|
this._setTabbarStorage('tabbarConfig')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
showTabBar() {
|
||||||
|
this.isShowTabBar = true
|
||||||
|
},
|
||||||
|
hideTabBar() {
|
||||||
|
this.isShowTabBar = false
|
||||||
|
},
|
||||||
|
reload(){
|
||||||
|
this.initTabbarConfig = this._getDefaultTabbar()
|
||||||
|
},
|
||||||
|
_tabChange(index) {
|
||||||
|
const {
|
||||||
|
currentIndex
|
||||||
|
} = this
|
||||||
|
this.$emit('click', index)
|
||||||
|
if (index === currentIndex) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.beforeData = {
|
||||||
|
newIndex: index,
|
||||||
|
oldIndex: currentIndex,
|
||||||
|
next: this.jumpPage
|
||||||
|
}
|
||||||
|
if (this.beforeChange) {
|
||||||
|
this.beforeChange(this._jumpPage, index)
|
||||||
|
} else {
|
||||||
|
this._jumpPage()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_jumpPage() {
|
||||||
|
const {
|
||||||
|
native,
|
||||||
|
beforeData: {
|
||||||
|
newIndex: index
|
||||||
|
},
|
||||||
|
tabbarList: list
|
||||||
|
} = this
|
||||||
|
const {
|
||||||
|
pagePath: url,
|
||||||
|
openType
|
||||||
|
} = list[index]
|
||||||
|
if (url) {
|
||||||
|
if (native) {
|
||||||
|
uni.switchTab({
|
||||||
|
url
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
if (openType !== 'navigate') {
|
||||||
|
this.currentIndex = index
|
||||||
|
}
|
||||||
|
switch (openType) {
|
||||||
|
case 'navigate':
|
||||||
|
uni.navigateTo({
|
||||||
|
url
|
||||||
|
})
|
||||||
|
break;
|
||||||
|
case 'redirect':
|
||||||
|
uni.redirectTo({
|
||||||
|
url
|
||||||
|
})
|
||||||
|
break;
|
||||||
|
case 'reLaunch':
|
||||||
|
uni.reLaunch({
|
||||||
|
url
|
||||||
|
})
|
||||||
|
break;
|
||||||
|
case 'switchTab':
|
||||||
|
uni.switchTab({
|
||||||
|
url
|
||||||
|
})
|
||||||
|
break;
|
||||||
|
case 'navigateBack':
|
||||||
|
uni.navigateBack({
|
||||||
|
delta: 1
|
||||||
|
})
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
uni.reLaunch({
|
||||||
|
url
|
||||||
|
})
|
||||||
|
}
|
||||||
|
this._initTabbar()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.$emit('change', index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.m-tabbar-box {
|
||||||
|
position: relative;
|
||||||
|
z-index: 9999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.m-tabbar {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&.fixed {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100vw;
|
||||||
|
z-index: 9999;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__safe {
|
||||||
|
padding-bottom: env(safe-area-inset-bottom);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.m-tabbar__fill {
|
||||||
|
pointer-events: none;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.m-tabbar__flex {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
|
||||||
|
.m-tabbar__border {
|
||||||
|
background-color: rgba(0, 0, 0, 0.33);
|
||||||
|
width: 100%;
|
||||||
|
height: 1rpx;
|
||||||
|
transform: scaleY(0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.m-tabbar__item {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
flex: 1;
|
||||||
|
padding: 4px 0 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.m-tabbar__icon {
|
||||||
|
width: 48rpx;
|
||||||
|
height: 48rpx;
|
||||||
|
// margin-bottom: 6rpx;
|
||||||
|
position: relative;
|
||||||
|
font-size: 40upx;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
&_img {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.m-tabbar__badge {
|
||||||
|
color: #fff;
|
||||||
|
background-color: #f00;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
font-size: 22rpx;
|
||||||
|
position: absolute;
|
||||||
|
right: -25rpx;
|
||||||
|
left: 40rpx;
|
||||||
|
padding: 2rpx 0;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.m-tabbar__label {
|
||||||
|
font-size: 24rpx;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,81 @@
|
||||||
|
{
|
||||||
|
"id": "m-tabbar",
|
||||||
|
"displayName": "自定义tabbar、tabbar路由守卫、零配置tabbar、凸起导航",
|
||||||
|
"version": "2.0.0",
|
||||||
|
"description": "自定义tabbar,超高还原原生配置模式,一行代码自定义导航,自带tabbar路由守卫功能",
|
||||||
|
"keywords": [
|
||||||
|
"自定义tabbar,tabbar,自定义标签栏,tabbar路由守卫,零配置tabbar,路由守卫、凸起导航"
|
||||||
|
],
|
||||||
|
"repository": "",
|
||||||
|
"engines": {
|
||||||
|
"HBuilderX": "^3.5.4"
|
||||||
|
},
|
||||||
|
"dcloudext": {
|
||||||
|
"type": "component-vue",
|
||||||
|
"sale": {
|
||||||
|
"regular": {
|
||||||
|
"price": "0.00"
|
||||||
|
},
|
||||||
|
"sourcecode": {
|
||||||
|
"price": "0.00"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"contact": {
|
||||||
|
"qq": ""
|
||||||
|
},
|
||||||
|
"declaration": {
|
||||||
|
"ads": "无",
|
||||||
|
"data": "无",
|
||||||
|
"permissions": "无"
|
||||||
|
},
|
||||||
|
"npmurl": ""
|
||||||
|
},
|
||||||
|
"uni_modules": {
|
||||||
|
"dependencies": [],
|
||||||
|
"encrypt": [],
|
||||||
|
"platforms": {
|
||||||
|
"cloud": {
|
||||||
|
"tcb": "y",
|
||||||
|
"aliyun": "y"
|
||||||
|
},
|
||||||
|
"client": {
|
||||||
|
"Vue": {
|
||||||
|
"vue2": "y",
|
||||||
|
"vue3": "y"
|
||||||
|
},
|
||||||
|
"App": {
|
||||||
|
"app-vue": "y",
|
||||||
|
"app-nvue": "y"
|
||||||
|
},
|
||||||
|
"H5-mobile": {
|
||||||
|
"Safari": "y",
|
||||||
|
"Android Browser": "y",
|
||||||
|
"微信浏览器(Android)": "y",
|
||||||
|
"QQ浏览器(Android)": "y"
|
||||||
|
},
|
||||||
|
"H5-pc": {
|
||||||
|
"Chrome": "y",
|
||||||
|
"IE": "y",
|
||||||
|
"Edge": "y",
|
||||||
|
"Firefox": "y",
|
||||||
|
"Safari": "y"
|
||||||
|
},
|
||||||
|
"小程序": {
|
||||||
|
"微信": "y",
|
||||||
|
"阿里": "y",
|
||||||
|
"百度": "y",
|
||||||
|
"字节跳动": "y",
|
||||||
|
"QQ": "y",
|
||||||
|
"钉钉": "y",
|
||||||
|
"快手": "y",
|
||||||
|
"飞书": "y",
|
||||||
|
"京东": "y"
|
||||||
|
},
|
||||||
|
"快应用": {
|
||||||
|
"华为": "y",
|
||||||
|
"联盟": "y"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,312 @@
|
||||||
|
# m-tabbar自定义
|
||||||
|
|
||||||
|
|
||||||
|
## 使用说明,注意事项(必看)
|
||||||
|
|
||||||
|
# 我配套上传了一个案例包,强烈建议下载阅读体验使用
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
> 1、自定义tabbar的情况下,不建议在一个页面内通过几个组件,用v-if切换去模拟各个页面,会存在各种不可控bug
|
||||||
|
|
||||||
|
> 闪烁的话,可以使用一个页面,多个组件,如果是`if切换组件`的话,就是一个页面控制多个组件显示隐藏来实现。 如果组件封装的有问题,会出现组件之间的协调问题,请看情况使用。 还有一些原生的交互没有办法达到预期,会影响到原生体验。 比如下拉刷新,滚动加载更多,切换tabbar后滚动位置不能固定等
|
||||||
|
|
||||||
|
>2、在pages.json中正常定义tabbar配置和字段,使用`native`模式,组件会自动加载pages.json配置项,并自动判断当前选中项,并自动隐藏原生的tabbar, 但是有个闪烁问题,暂时无解,如果你有好的方案,欢迎指正
|
||||||
|
|
||||||
|
> 3、如果出现tabbar不显示,但是控制台无任何报错信息,应该就是样式布局影响了,请自行排查
|
||||||
|
|
||||||
|
> 4、因为是自定义导航,所以原生方法是不支持的,只能通过 ref 可以获取到 tabbar 实例并调用插件的实例方法,详细请看页面最下方
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
# 快速使用
|
||||||
|
|
||||||
|
## 方式一、Native模式使用
|
||||||
|
|
||||||
|
```
|
||||||
|
// native模式,无需配置其他项
|
||||||
|
<m-tabbar native></m-tabbar>
|
||||||
|
```
|
||||||
|
在各个tabbar页面引入tabbar组件,传入属性`native`,`native`模式下无需任何配置
|
||||||
|
|
||||||
|
组件会默认自动通过`uni.hideTabBar()`隐藏系统tabbar
|
||||||
|
|
||||||
|
|
||||||
|
## 方式二、页面使用(current默认从0开始)(强烈推荐)
|
||||||
|
|
||||||
|
```
|
||||||
|
// 普通页面模式
|
||||||
|
<m-tabbar fixed fill current="1" :tabbar="tabbar"></m-tabbar>
|
||||||
|
```
|
||||||
|
|
||||||
|
配置选项和`uniapp`的配置完全相同,直接复制过来, 默认传入`pagePath`后,直接使用`reLaunch`跳转
|
||||||
|
插件支持扩展`openType`参数,用户可根据自己情况自行扩展页面打开方式,详细看下方配置
|
||||||
|
|
||||||
|
> 闪烁的话,可以使用一个页面,多个组件,如果是`if切换组件`的话,就是一个页面控制多个组件显示隐藏来实现。 如果组件封装的有问题,会出现组件之间的协调问题,请看情况使用。 还有一些原生的交互没有办法达到预期,会影响到原生体验。 比如下拉刷新,滚动加载更多,切换tabbar后滚动位置不能固定等
|
||||||
|
|
||||||
|
### 1、提取tabbar配置(2.0.0版本支持自动读取配置,主页面配置,内页可以不配置)
|
||||||
|
|
||||||
|
新建文件config/tabbar.js(默认你有config目录,根据自己情况而定)
|
||||||
|
```
|
||||||
|
export default {
|
||||||
|
color: "#161616",
|
||||||
|
selectedColor: "#161616",
|
||||||
|
borderStyle: "black",
|
||||||
|
backgroundColor: "#ffffff",
|
||||||
|
list: [{
|
||||||
|
pagePath: "/pages/index/index",
|
||||||
|
iconPath: "/static/tabbar/index.png",
|
||||||
|
selectedIconPath: "/static/tabbar/index_active.png",
|
||||||
|
text: "首页",
|
||||||
|
openType: 'navigate', //新版本新增,页面被打开方式,默认为reLaunch
|
||||||
|
dot: 1 //新版本新增参数,详细看页面最下方使用说明
|
||||||
|
}, {
|
||||||
|
pagePath: "/pages/shop/index",
|
||||||
|
iconPath: "/static/tabbar/shop.png",
|
||||||
|
selectedIconPath: "/static/tabbar/shop_active.png",
|
||||||
|
text: "门店"
|
||||||
|
}, {
|
||||||
|
pagePath: "/pages/my/index",
|
||||||
|
iconPath: "/static/tabbar/my.png",
|
||||||
|
selectedIconPath: "/static/tabbar/my_active.png",
|
||||||
|
text: "我的"
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2、引入tabbar (2.0.0版本支持自动读取配置,主页面配置,内页可以不引入)
|
||||||
|
#### VUE2引入
|
||||||
|
```
|
||||||
|
import TabbarConfig from '@/config/tabbar.js'
|
||||||
|
export default {
|
||||||
|
data(){
|
||||||
|
return {
|
||||||
|
tabbar: TabbarConfig
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onLoad(){
|
||||||
|
// 没有开启native模式下,使用reLaunch跳转,会存在首页标志,需要隐藏
|
||||||
|
#ifdef MP-JD || MP-WEIXIN
|
||||||
|
uni.hideHomeButton()
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### VUE3 setup引入
|
||||||
|
```
|
||||||
|
import TabbarConfig from '@/config/tabbar.js'
|
||||||
|
import { reactive } from 'vue'
|
||||||
|
|
||||||
|
// 没有开启native模式下,使用reLaunch跳转,会存在首页标志,需要隐藏
|
||||||
|
#ifdef MP-JD || MP-WEIXIN
|
||||||
|
uni.hideHomeButton()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const tabbar = reactive(TabbarConfig)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3、页面使用
|
||||||
|
```
|
||||||
|
<m-tabbar fixed fill current="1" :tabbar="tabbar"></m-tabbar>
|
||||||
|
```
|
||||||
|
|
||||||
|
## 高级用法(beforeChange)(路由守卫)
|
||||||
|
|
||||||
|
有些特殊需求,我们在点击一个tabbar其他一项的时候,可能需要判断权限是否可以进入,那么我们在切换前做一下路由拦截`beforeChange`,如果达到自己的预期,就进行跳转
|
||||||
|
|
||||||
|
> uniapp 微信小程序不支持$listeners,只能使用prop方式传入, 部分平台不支持prop传入方法,有平台限制,详细请看(问题解答)[https://ask.dcloud.net.cn/question/70659]
|
||||||
|
|
||||||
|
### 页面使用传入beforeChange
|
||||||
|
|
||||||
|
```
|
||||||
|
// native模式,无需传入 fixed fill
|
||||||
|
<m-tabbar native :beforeChange="onBeforeChange"></m-tabbar>
|
||||||
|
|
||||||
|
// 普通页面模式
|
||||||
|
<m-tabbar fixed fill current="1" :tabbar="tabbar" :beforeChange="onBeforeChange"></m-tabbar>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 进行事件判断监听
|
||||||
|
|
||||||
|
函数必选参数 next,当判断逻辑执行完毕后,满足条件的情况下执行 `next()`
|
||||||
|
|
||||||
|
```
|
||||||
|
methods: {
|
||||||
|
onBeforeChange(next, index){
|
||||||
|
//index为当前点击的是第几项,0开始
|
||||||
|
console.log('before page2 switch')
|
||||||
|
setTimeout(()=>{
|
||||||
|
console.log('switch page2 end')
|
||||||
|
next()
|
||||||
|
}, 1000)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 自定义凸起导航(插槽使用)
|
||||||
|
|
||||||
|
```
|
||||||
|
<m-tabbar native>
|
||||||
|
<template v-slot:tabbar_index_1> //插槽详细看文档,样式你自己写
|
||||||
|
<view class="custom_style">
|
||||||
|
<view class="custom_style_icon">+</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
</m-tabbar>
|
||||||
|
<style lang="scss">
|
||||||
|
.custom_style{
|
||||||
|
color: #fff;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 24rpx;
|
||||||
|
&_icon{
|
||||||
|
background-color: #15357A;
|
||||||
|
font-size: 80rpx;
|
||||||
|
width: 120rpx;
|
||||||
|
height: 120rpx;
|
||||||
|
border-radius: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
margin-top: -40rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 属性说明(Native模式)
|
||||||
|
|
||||||
|
| 属性名 | 类型 | 默认值 | 必填 | 说明 |
|
||||||
|
| ------------ | ------------- | ------ | ---- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
|
| zIndex | Number,String | 999 | 否 | 当前处于z-index层级 |
|
||||||
|
| native | Boolean | false | 否 | native模式,当前页面是系统原生tabbar页面(pages.json里面配置了tabBar) |
|
||||||
|
| beforeChange | Function | null | 否 | 导航切换前事件hooks,用于判断点击tabbar的时候,可以先执行自己定义的事件,达到预期后在跳转(类似router的路由守卫),方法需要调用next参数回调,部分平台不支持,存在兼容性 |
|
||||||
|
| tabbarHeight | Number,String | 100 | 否 | 默认tabbar高度,有些时候你可能想控制tabbar高度(没啥用,如果非要更改,布局有影响,请使用样式覆盖) |
|
||||||
|
| name | string | custom | 否 | 用于内部调用页面时,自动读取前一个页面的配置,无需二次配置 |
|
||||||
|
|
||||||
|
### 属性说明(普通模式)
|
||||||
|
|
||||||
|
| 属性名 | 类型 | 默认值 | 必填 | 说明 |
|
||||||
|
| ------------ | ------------- | ------ | ---- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
|
| current | Number,String | 0 | 是 | 默认选中第几项,0开始 |
|
||||||
|
| tabbar | Object | {} | 是 | tabbar配置项(新增dot参数,详细看下方使用说明) |
|
||||||
|
| fixed | Boolean | false | 否 | 是否定位在底部 |
|
||||||
|
| fill | Boolean | false | 否 | 是否填充底部高度(如果开启fixed后,会出现tabbar遮盖内容问题,开启此属性,会自动填充高度,可单独使用) |
|
||||||
|
| safeBottom | Boolean | true | 否 | 是否自动规避iphoneX\XR等底部安全距离 |
|
||||||
|
| zIndex | Number,String | 999 | 否 | 当前处于z-index层级 |
|
||||||
|
| beforeChange | Function | null | 否 | 导航切换前事件hooks,用于判断点击tabbar的时候,可以先执行自己定义的事件,达到预期后在跳转(类似router的路由守卫),方法需要调用next参数回调,部分平台不支持,存在兼容性 |
|
||||||
|
| tabbarHeight | Number,String | 100 | 否 | 默认tabbar高度,有些时候你可能想控制tabbar高度(没啥用,如果非要更改,布局有影响,请使用样式覆盖) |
|
||||||
|
| name | string | custom | 否 | 用于内部调用页面时,自动读取前一个页面的配置,无需二次配置 |
|
||||||
|
|
||||||
|
### openType对应值(默认reLaunch跳转)
|
||||||
|
|
||||||
|
| 方法名 | 返回值说明 |
|
||||||
|
| ------- | ------- |
|
||||||
|
| navigate | [对应navigateTo](https://uniapp.dcloud.io/api/router?id=navigateto) |
|
||||||
|
| redirect | [对应redirectTo](https://uniapp.dcloud.io/api/router?id=redirectto) |
|
||||||
|
| reLaunch | [对应reLaunch](https://uniapp.dcloud.io/api/router?id=relaunch) |
|
||||||
|
| switchTab | [对应switchTab](https://uniapp.dcloud.io/api/router?id=switchtab) 注意此方法需要你有原生tabbar,比如内页使用了自定义导航,想回tabbar的指定页面 |
|
||||||
|
| navigateBack | [对应navigateBack](https://uniapp.dcloud.io/api/router?id=navigateback) 只能后退一步 |
|
||||||
|
|
||||||
|
### 方法说明
|
||||||
|
|
||||||
|
| 方法名 | 返回值说明 |
|
||||||
|
| ------- | ------- |
|
||||||
|
| click | 当前选中index,无论什么情况下都会先触发click事件,方便自由定制更多方法 |
|
||||||
|
| change | 当前选中index(beforeChange会在change之前执行,只有执行next才会返回) |
|
||||||
|
|
||||||
|
### 插槽 (注意Vue3存在跨断不兼容问题)
|
||||||
|
|
||||||
|
| 插槽名 | 返回值说明 |
|
||||||
|
| ------- | ------- |
|
||||||
|
| tabbar_index_{index} | 插槽名字为tabbar_index_你要变化的index, 可以做到任意控制自己的导航,比如中心凸起,比如你想让第一个变化,index就是0,比如你tabbarList里面有5个item,你想让中间的凸起,那么index就是2,取下标 |
|
||||||
|
|
||||||
|
### 方法 (通过 ref 可以获取到 tabbar 实例并调用实例方法)
|
||||||
|
|
||||||
|
> 注意,由于是使用了自定义,所以原生的方法是不能使用的,只能通过 ref 可以获取到 tabbar 实例并调用实例方法,目前只有下面4个方法,而且方法是没有`success,fail,complete`回掉的,考虑到跨平台型,如果原生方法有平台差异,插件也是不考虑支持的
|
||||||
|
|
||||||
|
| 事件名 | 参数 | 参数说明|
|
||||||
|
| ------- | ------- | ------- |
|
||||||
|
| setTabBarBadge | object | [为 tabBar 某一项的右上角添加文本](https://uniapp.dcloud.io/api/ui/tabbar?id=settabbarbadge) |
|
||||||
|
| setTabBarItem | object | [动态设置 tabBar 某一项的内容](https://uniapp.dcloud.io/api/ui/tabbar?id=settabbaritem) |
|
||||||
|
| reload | 无 | 有特殊情况下,你可能需要调用重新载入tabbar配置,比如在内页进行了配置更新,返回前一个页面,自动读取前一个页面的配置 |
|
||||||
|
| showTabBar | 无 | 显示tabbar,默认显示,无动画效果 |
|
||||||
|
| hideTabBar | 无 | 隐藏tabbar,无动画效果 |
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
//页面调用组件添加ref
|
||||||
|
<m-tabbar ref="tabbar" native></m-tabbar>
|
||||||
|
// setTabBarBadge ,为 tabBar 某一项的右上角添加文本
|
||||||
|
this.$refs.tabbar.setTabBarBadge({
|
||||||
|
index: 0,
|
||||||
|
text: '10'
|
||||||
|
})
|
||||||
|
|
||||||
|
//setTabBarItem 动态设置 tabBar 某一项的内容
|
||||||
|
this.$refs.tabbar.setTabBarBadge({
|
||||||
|
index: 0,
|
||||||
|
text: 'text',
|
||||||
|
pagePath: 'newPagePath',
|
||||||
|
//插件新增pagePath,注意native模式下,如果更改了pagePath,可能存在选中项自动选中失败问题
|
||||||
|
iconPath: '/path/to/iconPath',
|
||||||
|
selectedIconPath: '/path/to/selectedIconPath'
|
||||||
|
})
|
||||||
|
|
||||||
|
//如果直接在onload或者onshow等组件还在加载中的特殊情况下,由于加载比较慢,
|
||||||
|
// 方法可能会失效,建议放在nextTick函数里面
|
||||||
|
this.$nextTick(()=>{
|
||||||
|
this.$refs.tabbar.setTabBarBadge({
|
||||||
|
index: 0,
|
||||||
|
text: '10'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
//reload重载整个组件
|
||||||
|
this.$nextTick(()=>{
|
||||||
|
this.$refs.tabbar.reload()
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
tabbarConfig参数新增dot配置项,可以单独配置每一项的右上角角标,可传入任意类型,不显示为空即可或者不填写, 默认为红色,如果想更改样式,请使用样式覆盖`m-tabbar__badge`
|
||||||
|
```
|
||||||
|
list: [{
|
||||||
|
pagePath: "/pages/index/index",
|
||||||
|
iconPath: "/static/tabbar/index.png",
|
||||||
|
selectedIconPath: "/static/tabbar/index_active.png",
|
||||||
|
text: "首页",
|
||||||
|
dot: 1
|
||||||
|
}, {
|
||||||
|
pagePath: "/pages/shop/index",
|
||||||
|
iconPath: "/static/tabbar/shop.png",
|
||||||
|
selectedIconPath: "/static/tabbar/shop_active.png",
|
||||||
|
text: "门店",
|
||||||
|
dot: ''
|
||||||
|
}, {
|
||||||
|
pagePath: "/pages/my/index",
|
||||||
|
iconPath: "/static/tabbar/my.png",
|
||||||
|
selectedIconPath: "/static/tabbar/my_active.png",
|
||||||
|
text: "我的",
|
||||||
|
dot: ''
|
||||||
|
}]
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### 目前已知问题
|
||||||
|
|
||||||
|
- 1、在全局加样式 filter: grayscale(1) 后,tabbar组件的fixed样式失效,排版在页面最底部(无法修复)
|
||||||
|
- 2、微信小程序native模式首次进入的时候,底部tabbar会闪动一下(无法修复) 建议全局页面做一个延迟加载效果,等全部加载完成后,在显示
|
||||||
|
|
||||||
|
|
||||||
|
### 插件写的时候,没办法照顾到所有平台,欢迎点评指正,如有问题欢迎给我留言
|
||||||
|
|
||||||
|
#### 例如:
|
||||||
|
```
|
||||||
|
设备:iphone13
|
||||||
|
系统: ios13
|
||||||
|
使用环境平台: 微信小程序、app
|
||||||
|
使用vue版本 :vue3
|
||||||
|
问题描述: 提示什么什么错误
|
||||||
|
```
|
||||||
Loading…
Reference in New Issue