mirror of
				https://gitee.com/lab1024/smart-admin.git
				synced 2025-11-04 18:33:43 +08:00 
			
		
		
		
	【smart-app更新】1、版本更新记录;2、复杂表单‘3、引入tabs组件
This commit is contained in:
		@@ -14,4 +14,11 @@ export const changeLogApi = {
 | 
				
			|||||||
  queryPage: (param) => {
 | 
					  queryPage: (param) => {
 | 
				
			||||||
    return postRequest('/support/changeLog/queryPage', param);
 | 
					    return postRequest('/support/changeLog/queryPage', param);
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * 详情  @author  卓大
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  getDetail: (changeLogId) => {
 | 
				
			||||||
 | 
					    return getRequest(`/support/changeLog/getDetail/${changeLogId}`);
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,8 @@
 | 
				
			|||||||
	"easycom": {
 | 
						"easycom": {
 | 
				
			||||||
		"autoscan": true,
 | 
							"autoscan": true,
 | 
				
			||||||
		"custom": {
 | 
							"custom": {
 | 
				
			||||||
			"^uni-(.*)": "@dcloudio/uni-ui/lib/uni-$1/uni-$1.vue"
 | 
								"^uni-(.*)": "@dcloudio/uni-ui/lib/uni-$1/uni-$1.vue",
 | 
				
			||||||
 | 
								"^y-(.*)": "@/uni_modules/y-$1/components/y-$1.vue"
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	"pages": [
 | 
						"pages": [
 | 
				
			||||||
@@ -69,7 +70,7 @@
 | 
				
			|||||||
			"path" : "pages/notice/notice-detail",
 | 
								"path" : "pages/notice/notice-detail",
 | 
				
			||||||
			"style" :
 | 
								"style" :
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				"navigationBarTitleText" : "通知公告",
 | 
									"navigationBarTitleText" : "公告内容",
 | 
				
			||||||
				"enablePullDownRefresh" : false,
 | 
									"enablePullDownRefresh" : false,
 | 
				
			||||||
				"navigationBarBackgroundColor": "#fff"
 | 
									"navigationBarBackgroundColor": "#fff"
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@@ -92,6 +93,15 @@
 | 
				
			|||||||
				"navigationBarBackgroundColor": "#fff"
 | 
									"navigationBarBackgroundColor": "#fff"
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								"path" : "pages/support/change-log/change-log-detail",
 | 
				
			||||||
 | 
								"style" :
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									"navigationBarTitleText" : "版本更新内容",
 | 
				
			||||||
 | 
									"enablePullDownRefresh" : false,
 | 
				
			||||||
 | 
									"navigationBarBackgroundColor": "#fff"
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"path" : "pages/list/list",
 | 
								"path" : "pages/list/list",
 | 
				
			||||||
			"style" :
 | 
								"style" :
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,49 +0,0 @@
 | 
				
			|||||||
<template>
 | 
					 | 
				
			||||||
	<view class="font-item-box">
 | 
					 | 
				
			||||||
		<text :class="modelValue==0?'active':''" @click="modelValue=0">标准</text>
 | 
					 | 
				
			||||||
		<view></view>
 | 
					 | 
				
			||||||
		<text :class="modelValue==1?'active':''" @click="modelValue=1">大号</text>
 | 
					 | 
				
			||||||
		<view></view>
 | 
					 | 
				
			||||||
		<text :class="modelValue==2?'active':''" @click="modelValue=2">小号</text>
 | 
					 | 
				
			||||||
	</view>
 | 
					 | 
				
			||||||
</template>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<script setup>
 | 
					 | 
				
			||||||
import { watch } from 'vue';
 | 
					 | 
				
			||||||
const emits = defineEmits(['update:modelValue'])
 | 
					 | 
				
			||||||
const props = defineProps({
 | 
					 | 
				
			||||||
	modelValue:{
 | 
					 | 
				
			||||||
		type:Number,
 | 
					 | 
				
			||||||
		default:0
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
watch(()=>props.modelValue,(newValue,oldValue)=>{
 | 
					 | 
				
			||||||
	emits('update:modelValue',newValue)
 | 
					 | 
				
			||||||
})
 | 
					 | 
				
			||||||
</script>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<style lang="scss" scoped>
 | 
					 | 
				
			||||||
	.font-item-box {
 | 
					 | 
				
			||||||
		width: 100%;
 | 
					 | 
				
			||||||
		display: flex;
 | 
					 | 
				
			||||||
		justify-content: flex-end;
 | 
					 | 
				
			||||||
		align-items: center;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		text {
 | 
					 | 
				
			||||||
			font-size: 30rpx;
 | 
					 | 
				
			||||||
			color: #cccccc;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			&.active {
 | 
					 | 
				
			||||||
				color: #1A9AFF;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		view {
 | 
					 | 
				
			||||||
			width: 4rpx;
 | 
					 | 
				
			||||||
			height: 16rpx;
 | 
					 | 
				
			||||||
			background-color: #e6e6e6;
 | 
					 | 
				
			||||||
			margin: 0 42rpx;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
</style>
 | 
					 | 
				
			||||||
@@ -1,59 +0,0 @@
 | 
				
			|||||||
<template>
 | 
					 | 
				
			||||||
	<view class="card-content">
 | 
					 | 
				
			||||||
		<view @click="modelValue = index" :class="modelValue == index?'active':''"
 | 
					 | 
				
			||||||
			v-for="(item,index) in list" :key="index">
 | 
					 | 
				
			||||||
			{{item}}
 | 
					 | 
				
			||||||
		</view>
 | 
					 | 
				
			||||||
	</view>
 | 
					 | 
				
			||||||
</template>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<script setup>
 | 
					 | 
				
			||||||
import { watch } from 'vue';
 | 
					 | 
				
			||||||
const emits = defineEmits(['update:modelValue'])
 | 
					 | 
				
			||||||
const props = defineProps({
 | 
					 | 
				
			||||||
	modelValue:{
 | 
					 | 
				
			||||||
		type:Number,
 | 
					 | 
				
			||||||
		default:0
 | 
					 | 
				
			||||||
	},
 | 
					 | 
				
			||||||
	list:{
 | 
					 | 
				
			||||||
		type:Array,
 | 
					 | 
				
			||||||
		default:[]
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
watch(()=>props.modelValue,(newValue,oldValue)=>{
 | 
					 | 
				
			||||||
	emits('update:modelValue',newValue)
 | 
					 | 
				
			||||||
})
 | 
					 | 
				
			||||||
</script>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<style lang="scss" scoped>
 | 
					 | 
				
			||||||
	.card-content {
 | 
					 | 
				
			||||||
		padding: 0 30rpx 24rpx;
 | 
					 | 
				
			||||||
		display: flex;
 | 
					 | 
				
			||||||
		flex-wrap: wrap;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		view {
 | 
					 | 
				
			||||||
			box-sizing: border-box;
 | 
					 | 
				
			||||||
			width: 197rpx;
 | 
					 | 
				
			||||||
			height: 72rpx;
 | 
					 | 
				
			||||||
			background: #f7f8f9;
 | 
					 | 
				
			||||||
			border-radius: 8rpx;
 | 
					 | 
				
			||||||
			text-align: center;
 | 
					 | 
				
			||||||
			line-height: 72rpx;
 | 
					 | 
				
			||||||
			margin-right: 24rpx;
 | 
					 | 
				
			||||||
			margin-top: 24rpx;
 | 
					 | 
				
			||||||
			font-size: 30rpx;
 | 
					 | 
				
			||||||
			color: #323333;
 | 
					 | 
				
			||||||
			border: 2rpx solid #f7f8f9;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			&:nth-child(3n) {
 | 
					 | 
				
			||||||
				margin-right: 0;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		.active {
 | 
					 | 
				
			||||||
			background: #eff8ff;
 | 
					 | 
				
			||||||
			border: 2rpx solid #2291f9;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
</style>
 | 
					 | 
				
			||||||
@@ -1,60 +0,0 @@
 | 
				
			|||||||
<template>
 | 
					 | 
				
			||||||
	<view class="sex-box">
 | 
					 | 
				
			||||||
		<view class="sex-item" :class="modelValue?'active':''" @click="modelValue=true">
 | 
					 | 
				
			||||||
			<uni-icons type="circle" v-if="!modelValue" color="#ccc" size="30"></uni-icons>
 | 
					 | 
				
			||||||
			<uni-icons v-else type="checkbox-filled" color="#1A9AFF" size="30"></uni-icons>
 | 
					 | 
				
			||||||
			<view>
 | 
					 | 
				
			||||||
				男
 | 
					 | 
				
			||||||
			</view>
 | 
					 | 
				
			||||||
		</view>
 | 
					 | 
				
			||||||
		<view class="sex-item" :class="!modelValue?'active':''" @click="modelValue=false">
 | 
					 | 
				
			||||||
			<uni-icons type="circle" v-if="modelValue" color="#ccc" size="30"></uni-icons>
 | 
					 | 
				
			||||||
			<uni-icons v-else type="checkbox-filled" color="#1A9AFF" size="30"></uni-icons>
 | 
					 | 
				
			||||||
			<view>
 | 
					 | 
				
			||||||
				女
 | 
					 | 
				
			||||||
			</view>
 | 
					 | 
				
			||||||
		</view>
 | 
					 | 
				
			||||||
	</view>
 | 
					 | 
				
			||||||
</template>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<script setup>
 | 
					 | 
				
			||||||
import { watch } from 'vue';
 | 
					 | 
				
			||||||
const emits = defineEmits(['update:modelValue'])
 | 
					 | 
				
			||||||
const props = defineProps({
 | 
					 | 
				
			||||||
	modelValue:{
 | 
					 | 
				
			||||||
		type:Boolean,
 | 
					 | 
				
			||||||
		default:true
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
watch(()=>props.modelValue,(newValue,oldValue)=>{
 | 
					 | 
				
			||||||
	emits('update:modelValue',newValue)
 | 
					 | 
				
			||||||
})
 | 
					 | 
				
			||||||
</script>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<style lang="scss" scoped>
 | 
					 | 
				
			||||||
.sex-box {
 | 
					 | 
				
			||||||
	width: 100%;
 | 
					 | 
				
			||||||
	display: flex;
 | 
					 | 
				
			||||||
	justify-content: flex-end;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	.sex-item {
 | 
					 | 
				
			||||||
		display: flex;
 | 
					 | 
				
			||||||
		width: 112rpx;
 | 
					 | 
				
			||||||
		height: 64rpx;
 | 
					 | 
				
			||||||
		background-color: #f3f3f3;
 | 
					 | 
				
			||||||
		border: 1rpx solid #ededed;
 | 
					 | 
				
			||||||
		align-items: center;
 | 
					 | 
				
			||||||
		margin-left: 40rpx;
 | 
					 | 
				
			||||||
		justify-content: center;
 | 
					 | 
				
			||||||
		border-radius: 8rpx;
 | 
					 | 
				
			||||||
		font-size: 32rpx;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	.active {
 | 
					 | 
				
			||||||
		background: #f1f9ff;
 | 
					 | 
				
			||||||
		border: 1rpx solid #1a9aff;
 | 
					 | 
				
			||||||
		color: #1A9AFF;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
</style>
 | 
					 | 
				
			||||||
@@ -1,199 +1,94 @@
 | 
				
			|||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <view class="">
 | 
					  <view class="smart-form">
 | 
				
			||||||
    <view class="form-card">
 | 
					    <uni-forms :label-width="100" :modelValue="formData" label-position="left">
 | 
				
			||||||
      <view class="title"> 常用功能 </view>
 | 
					      <view class="smart-form-group">
 | 
				
			||||||
      <view class="content">
 | 
					        <view class="smart-form-group-title"> 常用功能 </view>
 | 
				
			||||||
        <uni-forms :label-width="100" :modelValue="formData" label-position="left">
 | 
					        <view class="smart-form-group-content">
 | 
				
			||||||
          <uni-forms-item class="uni-forms-item" label="姓名" name="name">
 | 
					          <uni-forms-item class="smart-form-item" label="姓名" name="name" required>
 | 
				
			||||||
            <input class="input" type="text" v-model="formData.name" placeholder="请输入姓名" />
 | 
					            <uni-easyinput trim="all" v-model="formData.name" placeholder="请输入姓名" />
 | 
				
			||||||
          </uni-forms-item>
 | 
					          </uni-forms-item>
 | 
				
			||||||
          <uni-forms-item class="uni-forms-item" label="手机号码" name="name">
 | 
					          <uni-forms-item class="smart-form-item" label="手机号码" name="name" required>
 | 
				
			||||||
            <input class="input" type="text" v-model="formData.name" placeholder="请输入手机号码" />
 | 
					            <uni-easyinput trim="all" v-model="formData.name" placeholder="请输入手机号码" />
 | 
				
			||||||
          </uni-forms-item>
 | 
					          </uni-forms-item>
 | 
				
			||||||
          <uni-forms-item class="uni-forms-item" label="邮箱地址" name="name">
 | 
					          <uni-forms-item class="smart-form-item" label="邮箱地址" name="name">
 | 
				
			||||||
            <input class="input" type="text" v-model="formData.name" placeholder="请输入邮箱地址" />
 | 
					            <uni-easyinput trim="all" v-model="formData.name" placeholder="请输入邮箱地址" />
 | 
				
			||||||
          </uni-forms-item>
 | 
					          </uni-forms-item>
 | 
				
			||||||
          <uni-forms-item class="uni-forms-item" label="性别" name="name">
 | 
					          <uni-forms-item class="smart-form-item" label="性别" required>
 | 
				
			||||||
            <RadioSex v-model="formData.sex"></RadioSex>
 | 
					            <uni-data-checkbox v-model="formData.sex" :localdata="sexs" />
 | 
				
			||||||
          </uni-forms-item>
 | 
					          </uni-forms-item>
 | 
				
			||||||
          <uni-forms-item class="uni-forms-item" label="出生日期" name="name">
 | 
					          <uni-forms-item class="smart-form-item" label="出生日期" name="name">
 | 
				
			||||||
            <view class="item-box">
 | 
					            <uni-datetime-picker type="date" return-type="timestamp" v-model="formData.datetimesingle" />
 | 
				
			||||||
              <picker ref="datePickerRef" mode="date" @change="bindDateChange">
 | 
					 | 
				
			||||||
                <input ref="dateInputRef" class="input" type="text" v-model="date" placeholder="点击选择时间" />
 | 
					 | 
				
			||||||
              </picker>
 | 
					 | 
				
			||||||
            </view>
 | 
					 | 
				
			||||||
          </uni-forms-item>
 | 
					          </uni-forms-item>
 | 
				
			||||||
          <uni-forms-item class="uni-forms-item" label="所在地" name="name">
 | 
					        </view>
 | 
				
			||||||
            <input class="input" disabled type="text" v-model="formData.name" placeholder="点击选择所在地" />
 | 
					 | 
				
			||||||
          </uni-forms-item>
 | 
					 | 
				
			||||||
        </uni-forms>
 | 
					 | 
				
			||||||
      </view>
 | 
					      </view>
 | 
				
			||||||
    </view>
 | 
					      <view class="smart-form-group">
 | 
				
			||||||
    <view class="form-card">
 | 
					        <view class="smart-form-group-title"> 兴趣爱好 </view>
 | 
				
			||||||
      <view class="title"> 推送用户 </view>
 | 
					        <view class="smart-form-group-content">
 | 
				
			||||||
      <view class="content">
 | 
					          <uni-forms-item class="smart-form-item" label="兴趣爱好" name="interest">
 | 
				
			||||||
        <uni-forms :label-width="100" :modelValue="formData" label-position="left">
 | 
					            <uni-data-checkbox mode="button" multiple v-model="formData.interest" :localdata="interestList"></uni-data-checkbox>
 | 
				
			||||||
          <uni-forms-item class="uni-forms-item" label="选择用户" name="name">
 | 
					 | 
				
			||||||
            <view class="item-box" @click="openSelectPeople">
 | 
					 | 
				
			||||||
              <image class="user-select-image" src="/src/static/images/form/add.png" mode=""></image>
 | 
					 | 
				
			||||||
            </view>
 | 
					 | 
				
			||||||
          </uni-forms-item>
 | 
					          </uni-forms-item>
 | 
				
			||||||
        </uni-forms>
 | 
					        </view>
 | 
				
			||||||
      </view>
 | 
					      </view>
 | 
				
			||||||
    </view>
 | 
					      <view class="smart-form-group">
 | 
				
			||||||
    <view class="form-card">
 | 
					        <view class="smart-form-group-title"> 屏幕设置 </view>
 | 
				
			||||||
      <view class="title"> 兴趣爱好 </view>
 | 
					        <view class="smart-form-group-content">
 | 
				
			||||||
      <Interest v-model="formData.interest" :list="interestList"></Interest>
 | 
					          <uni-forms-item class="smart-form-item" label="亮度调整" name="name">
 | 
				
			||||||
    </view>
 | 
					            <slider style="width: 100%" value="50" activeColor="#2291F9" backgroundColor="#f5f6f8" block-color="#2291F9" block-size="20" />
 | 
				
			||||||
    <view class="form-card">
 | 
					 | 
				
			||||||
      <view class="title"> 推送用户 </view>
 | 
					 | 
				
			||||||
      <view class="content">
 | 
					 | 
				
			||||||
        <uni-forms :label-width="100" :modelValue="formData" label-position="left">
 | 
					 | 
				
			||||||
          <uni-forms-item class="uni-forms-item" label="亮度调整" name="name">
 | 
					 | 
				
			||||||
            <view class="item-box">
 | 
					 | 
				
			||||||
              <slider style="width: 100%" value="50" activeColor="#2291F9" backgroundColor="#f5f6f8" block-color="#2291F9" block-size="20" />
 | 
					 | 
				
			||||||
            </view>
 | 
					 | 
				
			||||||
          </uni-forms-item>
 | 
					          </uni-forms-item>
 | 
				
			||||||
          <uni-forms-item class="uni-forms-item" label="字体大小" name="name">
 | 
					        </view>
 | 
				
			||||||
            <FontSizeSelece v-model="formData.fontType"></FontSizeSelece>
 | 
					      </view>
 | 
				
			||||||
 | 
					      <view class="smart-form-group">
 | 
				
			||||||
 | 
					        <view class="smart-form-group-title"> 自我介绍 </view>
 | 
				
			||||||
 | 
					        <view class="smart-form-group-content">
 | 
				
			||||||
 | 
					          <uni-forms-item class="smart-form-item" label="兴趣爱好" name="interest">
 | 
				
			||||||
 | 
					            <uni-easyinput type="textarea" autoHeight v-model="value" placeholder="请输入自我介绍" />
 | 
				
			||||||
          </uni-forms-item>
 | 
					          </uni-forms-item>
 | 
				
			||||||
        </uni-forms>
 | 
					
 | 
				
			||||||
      </view>
 | 
					          <uni-forms-item class="smart-form-item" label="上传图片" name="interest">
 | 
				
			||||||
    </view>
 | 
					            <uni-file-picker limit="9" title="最多选择9张图片" />
 | 
				
			||||||
    <view class="form-card">
 | 
					          </uni-forms-item>
 | 
				
			||||||
      <view class="title"> 自我介绍 </view>
 | 
					        </view>
 | 
				
			||||||
      <view class="content">
 | 
					 | 
				
			||||||
        <uni-forms :modelValue="formData" label-position="left">
 | 
					 | 
				
			||||||
          <view class="textarea">
 | 
					 | 
				
			||||||
            <textarea auto-height style="font-size: 30rpx" placeholder="请输入自我介绍" placeholder-class="textarea-placeholder" />
 | 
					 | 
				
			||||||
          </view>
 | 
					 | 
				
			||||||
          <view class="example-body">
 | 
					 | 
				
			||||||
            <uni-file-picker limit="9" title="上传图片">
 | 
					 | 
				
			||||||
              <image style="width: 100%; height: 100%" src="/static/images/form/add-image.png" mode=""></image>
 | 
					 | 
				
			||||||
            </uni-file-picker>
 | 
					 | 
				
			||||||
          </view>
 | 
					 | 
				
			||||||
        </uni-forms>
 | 
					 | 
				
			||||||
      </view>
 | 
					      </view>
 | 
				
			||||||
 | 
					    </uni-forms>
 | 
				
			||||||
 | 
					    <view class="smart-form-submit fixed-bottom-button">
 | 
				
			||||||
 | 
					      <button class="smart-form-submit-btn smart-margin-right20" type="default">取消</button>
 | 
				
			||||||
 | 
					      <button class="smart-form-submit-btn" type="warn">重置</button>
 | 
				
			||||||
 | 
					      <button class="smart-form-submit-btn" type="primary">确定</button>
 | 
				
			||||||
    </view>
 | 
					    </view>
 | 
				
			||||||
  </view>
 | 
					  </view>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script setup>
 | 
					<script setup>
 | 
				
			||||||
  import RadioSex from './components/radio-sex.vue';
 | 
					  import { reactive } from 'vue';
 | 
				
			||||||
  import Interest from './components/interest.vue';
 | 
					 | 
				
			||||||
  import FontSizeSelece from './components/font-size-select.vue';
 | 
					 | 
				
			||||||
  import { reactive, ref } from 'vue';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const interestList = ['唱歌', '跳舞', 'RAP', '篮球', '音乐', '唱歌', '跳舞', 'RAP', '篮球'];
 | 
					  const sexs = [
 | 
				
			||||||
  const formData = reactive({
 | 
					    {
 | 
				
			||||||
    interest: 4,
 | 
					      text: '男',
 | 
				
			||||||
    fontType: 0,
 | 
					      value: 0,
 | 
				
			||||||
  });
 | 
					    },
 | 
				
			||||||
  const hobby = ref('');
 | 
					    {
 | 
				
			||||||
  const date = ref();
 | 
					      text: '女',
 | 
				
			||||||
  const bindDateChange = (e) => {
 | 
					      value: 1,
 | 
				
			||||||
    date.value = e.detail.value;
 | 
					    },
 | 
				
			||||||
  };
 | 
					    {
 | 
				
			||||||
 | 
					      text: '你懂的',
 | 
				
			||||||
 | 
					      value: 2,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					  ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const openSelectPeople = () => {
 | 
					  const interestList = [
 | 
				
			||||||
    uni.navigateTo({
 | 
					    { text: '唱歌', value: 1 },
 | 
				
			||||||
      url: '/pages/select-people/select-people',
 | 
					    { text: '足球', value: 2 },
 | 
				
			||||||
    });
 | 
					    { text: '篮球', value: 3 },
 | 
				
			||||||
  };
 | 
					    { text: '跑步', value: 4 },
 | 
				
			||||||
 | 
					    { text: '写字', value: 5 },
 | 
				
			||||||
 | 
					    { text: '美术', value: 6 },
 | 
				
			||||||
 | 
					    { text: '射击', value: 7 },
 | 
				
			||||||
 | 
					    { text: '健身', value: 8 },
 | 
				
			||||||
 | 
					    { text: '马术', value: 9 },
 | 
				
			||||||
 | 
					    { text: '美食', value: 10 },
 | 
				
			||||||
 | 
					  ];
 | 
				
			||||||
 | 
					  const formData = reactive({});
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<style lang="scss" scoped>
 | 
					<style lang="scss" scoped></style>
 | 
				
			||||||
  page {
 | 
					 | 
				
			||||||
    background: #f5f6f8;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  ::v-deep .uni-forms-item__content {
 | 
					 | 
				
			||||||
    display: flex;
 | 
					 | 
				
			||||||
    align-items: center;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  ::v-deep .uni-forms-item__label {
 | 
					 | 
				
			||||||
    font-size: 32rpx;
 | 
					 | 
				
			||||||
    color: #000000;
 | 
					 | 
				
			||||||
    padding-top: 28rpx;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  ::v-deep .uni-forms-item {
 | 
					 | 
				
			||||||
    margin-bottom: 0 !important;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  ::v-deep .uni-slider-thumb {
 | 
					 | 
				
			||||||
    background: #fff !important;
 | 
					 | 
				
			||||||
    border: 10rpx solid #1a9aff;
 | 
					 | 
				
			||||||
    box-sizing: border-box;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  .uni-forms-item {
 | 
					 | 
				
			||||||
    height: 100rpx;
 | 
					 | 
				
			||||||
    border-bottom: 1rpx solid #ededed;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    &:last-child {
 | 
					 | 
				
			||||||
      border: none;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  .form-card {
 | 
					 | 
				
			||||||
    box-sizing: border-box;
 | 
					 | 
				
			||||||
    width: 700rpx;
 | 
					 | 
				
			||||||
    margin: 20rpx auto 0;
 | 
					 | 
				
			||||||
    background: #fff;
 | 
					 | 
				
			||||||
    border-radius: 16rpx;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .title {
 | 
					 | 
				
			||||||
      width: 100%;
 | 
					 | 
				
			||||||
      height: 84rpx;
 | 
					 | 
				
			||||||
      background-image: url('/static/images/list/form-list.png');
 | 
					 | 
				
			||||||
      background-size: 100% 84rpx;
 | 
					 | 
				
			||||||
      line-height: 84rpx;
 | 
					 | 
				
			||||||
      text-indent: 30rpx;
 | 
					 | 
				
			||||||
      font-size: 32rpx;
 | 
					 | 
				
			||||||
      color: #323333;
 | 
					 | 
				
			||||||
      font-weight: bold;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .content {
 | 
					 | 
				
			||||||
      padding: 0 30rpx;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .input {
 | 
					 | 
				
			||||||
      font-size: 30rpx;
 | 
					 | 
				
			||||||
      text-align: right;
 | 
					 | 
				
			||||||
      width: 100%;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  .item-box {
 | 
					 | 
				
			||||||
    width: 100%;
 | 
					 | 
				
			||||||
    display: flex;
 | 
					 | 
				
			||||||
    justify-content: flex-end;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  .user-select-image {
 | 
					 | 
				
			||||||
    width: 40rpx;
 | 
					 | 
				
			||||||
    height: 40rpx;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  .textarea {
 | 
					 | 
				
			||||||
    background: #fcfcfc;
 | 
					 | 
				
			||||||
    border: 0.5px solid #ededed;
 | 
					 | 
				
			||||||
    border-radius: 4px;
 | 
					 | 
				
			||||||
    width: 100%;
 | 
					 | 
				
			||||||
    height: 320rpx;
 | 
					 | 
				
			||||||
    margin-top: 24rpx;
 | 
					 | 
				
			||||||
    padding: 24rpx 30rpx;
 | 
					 | 
				
			||||||
    box-sizing: border-box;
 | 
					 | 
				
			||||||
    .textarea-placeholder {
 | 
					 | 
				
			||||||
      color: #cccccc;
 | 
					 | 
				
			||||||
      font-size: 30rpx;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  .example-body {
 | 
					 | 
				
			||||||
    padding-bottom: 24rpx;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
</style>
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -38,10 +38,15 @@
 | 
				
			|||||||
      <uni-grid-item class="menu-grid">
 | 
					      <uni-grid-item class="menu-grid">
 | 
				
			||||||
        <view class="menu-item" @click="navigateTo('/pages/form/form')">
 | 
					        <view class="menu-item" @click="navigateTo('/pages/form/form')">
 | 
				
			||||||
          <image class="item-image" src="/@/static/images/index/ic_home_menu6.png"></image>
 | 
					          <image class="item-image" src="/@/static/images/index/ic_home_menu6.png"></image>
 | 
				
			||||||
          <view class="item-text"> 表单 </view>
 | 
					          <view class="item-text"> 复杂表单 </view>
 | 
				
			||||||
 | 
					        </view>
 | 
				
			||||||
 | 
					      </uni-grid-item>
 | 
				
			||||||
 | 
					      <uni-grid-item class="menu-grid">
 | 
				
			||||||
 | 
					        <view class="menu-item" @click="switchTab('/pages/list/list')">
 | 
				
			||||||
 | 
					          <image class="item-image" src="/@/static/images/index/ic_home_menu9.png"></image>
 | 
				
			||||||
 | 
					          <view class="item-text"> 常见列表 </view>
 | 
				
			||||||
        </view>
 | 
					        </view>
 | 
				
			||||||
      </uni-grid-item>
 | 
					      </uni-grid-item>
 | 
				
			||||||
 | 
					 | 
				
			||||||
      <uni-grid-item class="menu-grid">
 | 
					      <uni-grid-item class="menu-grid">
 | 
				
			||||||
        <view class="menu-item" @click="navigateTo('/pages/order-detail/order-detail')">
 | 
					        <view class="menu-item" @click="navigateTo('/pages/order-detail/order-detail')">
 | 
				
			||||||
          <image class="item-image" src="/@/static/images/index/ic_home_menu7.png"></image>
 | 
					          <image class="item-image" src="/@/static/images/index/ic_home_menu7.png"></image>
 | 
				
			||||||
@@ -54,12 +59,6 @@
 | 
				
			|||||||
          <view class="item-text"> 优惠券 </view>
 | 
					          <view class="item-text"> 优惠券 </view>
 | 
				
			||||||
        </view>
 | 
					        </view>
 | 
				
			||||||
      </uni-grid-item>
 | 
					      </uni-grid-item>
 | 
				
			||||||
      <uni-grid-item class="menu-grid">
 | 
					 | 
				
			||||||
        <view class="menu-item" @click="navigateTo('/pages/list/list')">
 | 
					 | 
				
			||||||
          <image class="item-image" src="/@/static/images/index/ic_home_menu9.png"></image>
 | 
					 | 
				
			||||||
          <view class="item-text"> 精品课程 </view>
 | 
					 | 
				
			||||||
        </view>
 | 
					 | 
				
			||||||
      </uni-grid-item>
 | 
					 | 
				
			||||||
      <uni-grid-item class="menu-grid">
 | 
					      <uni-grid-item class="menu-grid">
 | 
				
			||||||
        <view class="menu-item" @click="navigateTo('/pages/change-log/change-log-list')">
 | 
					        <view class="menu-item" @click="navigateTo('/pages/change-log/change-log-list')">
 | 
				
			||||||
          <image class="item-image" src="/@/static/images/index/ic_home_menu10.png"></image>
 | 
					          <image class="item-image" src="/@/static/images/index/ic_home_menu10.png"></image>
 | 
				
			||||||
@@ -82,6 +81,11 @@
 | 
				
			|||||||
      url,
 | 
					      url,
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  function switchTab(url) {
 | 
				
			||||||
 | 
					    uni.switchTab({
 | 
				
			||||||
 | 
					      url,
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<style lang="scss" scoped>
 | 
					<style lang="scss" scoped>
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										79
									
								
								smart-app/src/pages/support/change-log/change-log-detail.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								smart-app/src/pages/support/change-log/change-log-detail.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,79 @@
 | 
				
			|||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <view class="container">
 | 
				
			||||||
 | 
					    <view class="title">
 | 
				
			||||||
 | 
					      <uni-title type="h1" align="center" :title="detail.title"></uni-title>
 | 
				
			||||||
 | 
					      <uni-title type="h4" align="center" color="#999999" :title="detail.subTitle"></uni-title>
 | 
				
			||||||
 | 
					    </view>
 | 
				
			||||||
 | 
					    <view class="content">
 | 
				
			||||||
 | 
					      <rich-text :nodes="detail.content" />
 | 
				
			||||||
 | 
					    </view>
 | 
				
			||||||
 | 
					  </view>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script setup>
 | 
				
			||||||
 | 
					  import { inject, reactive } from 'vue';
 | 
				
			||||||
 | 
					  import { changeLogApi } from '/@/api/support/change-log-api';
 | 
				
			||||||
 | 
					  import { onLoad } from '@dcloudio/uni-app';
 | 
				
			||||||
 | 
					  import { smartSentry } from '/@/lib/smart-sentry';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const smartEnumPlugin = inject('smartEnumPlugin');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const detail = reactive({
 | 
				
			||||||
 | 
					    title: '',
 | 
				
			||||||
 | 
					    subTitle: '',
 | 
				
			||||||
 | 
					    content: '',
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async function getDetail(changeLogId) {
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					      uni.showLoading({ title: '加载中' });
 | 
				
			||||||
 | 
					      let res = await changeLogApi.getDetail(changeLogId);
 | 
				
			||||||
 | 
					      detail.title = res.data.version + '版本' + smartEnumPlugin.getDescByValue('CHANGE_LOG_TYPE_ENUM', res.data.type);
 | 
				
			||||||
 | 
					      detail.content =
 | 
				
			||||||
 | 
					        '<pre style="' +
 | 
				
			||||||
 | 
					        'line-height: 18px;\n' +
 | 
				
			||||||
 | 
					        'font-size: 14px;\n' +
 | 
				
			||||||
 | 
					        'white-space: pre-wrap;\n' +
 | 
				
			||||||
 | 
					        '  white-space: -moz-pre-wrap;\n' +
 | 
				
			||||||
 | 
					        '  white-space: -pre-wrap;\n' +
 | 
				
			||||||
 | 
					        '  white-space: -o-pre-wrap;\n' +
 | 
				
			||||||
 | 
					        '  word-wrap: break-word;">' +
 | 
				
			||||||
 | 
					        res.data.content +
 | 
				
			||||||
 | 
					        '</pre>';
 | 
				
			||||||
 | 
					      let subTitleArray = [];
 | 
				
			||||||
 | 
					      if (res.data.publishAuthor) {
 | 
				
			||||||
 | 
					        subTitleArray.push(res.data.publishAuthor);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      if (res.data.publicDate) {
 | 
				
			||||||
 | 
					        subTitleArray.push(res.data.publicDate);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      detail.subTitle = subTitleArray.join(' | ');
 | 
				
			||||||
 | 
					    } catch (e) {
 | 
				
			||||||
 | 
					      smartSentry.captureError(e);
 | 
				
			||||||
 | 
					    } finally {
 | 
				
			||||||
 | 
					      uni.hideLoading();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  onLoad((option) => {
 | 
				
			||||||
 | 
					    uni.pageScrollTo({
 | 
				
			||||||
 | 
					      scrollTop: 0,
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    getDetail(option.changeLogId);
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style lang="scss" scoped>
 | 
				
			||||||
 | 
					  .container {
 | 
				
			||||||
 | 
					    height: 100vh;
 | 
				
			||||||
 | 
					    padding: 20rpx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .content {
 | 
				
			||||||
 | 
					      border-top: #cccccc 1px solid;
 | 
				
			||||||
 | 
					      margin-top: 50rpx;
 | 
				
			||||||
 | 
					      padding: 50rpx 16rpx 50rpx 16rpx;
 | 
				
			||||||
 | 
					      line-height: 30px;
 | 
				
			||||||
 | 
					      color: #333333;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
@@ -25,23 +25,20 @@
 | 
				
			|||||||
      <view class="list-container">
 | 
					      <view class="list-container">
 | 
				
			||||||
        <view class="list-item" @click="gotoDetail(item.changeLogId)" v-for="item in listData" :key="item.changeLogId">
 | 
					        <view class="list-item" @click="gotoDetail(item.changeLogId)" v-for="item in listData" :key="item.changeLogId">
 | 
				
			||||||
          <view class="list-item-row">
 | 
					          <view class="list-item-row">
 | 
				
			||||||
            <view class="list-item-content bolder">{{ item.version }}</view>
 | 
					            <view class="list-item-content bolder"
 | 
				
			||||||
 | 
					              >{{ item.version }}版本{{ $smartEnumPlugin.getDescByValue('CHANGE_LOG_TYPE_ENUM', item.type) }}</view
 | 
				
			||||||
 | 
					            >
 | 
				
			||||||
            <uni-tag
 | 
					            <uni-tag
 | 
				
			||||||
              :text="$smartEnumPlugin.getDescByValue('CHANGE_LOG_TYPE_ENUM', item.type)"
 | 
					              :text="$smartEnumPlugin.getDescByValue('CHANGE_LOG_TYPE_ENUM', item.type)"
 | 
				
			||||||
              :type="$smartEnumPlugin.getObjectByValue('CHANGE_LOG_TYPE_ENUM', item.type).type"
 | 
					              :type="$smartEnumPlugin.getObjectByValue('CHANGE_LOG_TYPE_ENUM', item.type).type"
 | 
				
			||||||
            />
 | 
					            />
 | 
				
			||||||
          </view>
 | 
					          </view>
 | 
				
			||||||
          <view class="list-item-row">
 | 
					          <view class="list-item-row">
 | 
				
			||||||
            <view class="list-item-label">发布日期:{{ item.publicDate }} - {{ item.publishAuthor }}</view>
 | 
					            <view class="list-item-label">发布日期:{{ item.publicDate }}</view>
 | 
				
			||||||
          </view>
 | 
					 | 
				
			||||||
          <view class="list-item-row">
 | 
					 | 
				
			||||||
            <view class="list-item-label">{{ item.content }}</view>
 | 
					 | 
				
			||||||
          </view>
 | 
					          </view>
 | 
				
			||||||
        </view>
 | 
					        </view>
 | 
				
			||||||
      </view>
 | 
					      </view>
 | 
				
			||||||
    </mescroll-body>
 | 
					    </mescroll-body>
 | 
				
			||||||
 | 
					 | 
				
			||||||
    <uni-fab ref="fab" :pattern="fabPattern" horizontal="right" @fabClick="gotoAdd" />
 | 
					 | 
				
			||||||
  </view>
 | 
					  </view>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -121,7 +118,7 @@
 | 
				
			|||||||
  // --------------------------- 详情 ---------------------------------
 | 
					  // --------------------------- 详情 ---------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function gotoDetail(id) {
 | 
					  function gotoDetail(id) {
 | 
				
			||||||
    uni.navigateTo({ url: '/pages/enterprise/enterprise-detail?enterpriseId=' + id });
 | 
					    uni.navigateTo({ url: '/pages/support/change-log/change-log-detail?changeLogId=' + id });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -172,9 +169,10 @@
 | 
				
			|||||||
          font-size: 30rpx;
 | 
					          font-size: 30rpx;
 | 
				
			||||||
          font-weight: 400;
 | 
					          font-weight: 400;
 | 
				
			||||||
          text-align: left;
 | 
					          text-align: left;
 | 
				
			||||||
 | 
					          color: $uni-text-color-grey;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        .bolder {
 | 
					        .bolder {
 | 
				
			||||||
          font-weight: 600 !important;
 | 
					          font-weight: 500 !important;
 | 
				
			||||||
          font-size: 34rpx !important;
 | 
					          font-size: 34rpx !important;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        .list-item-content {
 | 
					        .list-item-content {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -136,9 +136,9 @@
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  .smart-form-item {
 | 
					  .smart-form-item {
 | 
				
			||||||
    height: 100rpx;
 | 
					    min-height: 100rpx;
 | 
				
			||||||
 | 
					    height: auto;
 | 
				
			||||||
    padding-bottom: 24rpx;
 | 
					    padding-bottom: 24rpx;
 | 
				
			||||||
    //border-bottom: 1rpx solid #ededed;
 | 
					 | 
				
			||||||
    align-items: center;
 | 
					    align-items: center;
 | 
				
			||||||
    &:last-child {
 | 
					    &:last-child {
 | 
				
			||||||
      border: none;
 | 
					      border: none;
 | 
				
			||||||
@@ -191,4 +191,9 @@
 | 
				
			|||||||
      flex: 1;
 | 
					      flex: 1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  .fixed-bottom-button {
 | 
				
			||||||
 | 
					    position: fixed;
 | 
				
			||||||
 | 
					    bottom: 0;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										464
									
								
								smart-app/src/uni_modules/y-tabs/components/css/index.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										464
									
								
								smart-app/src/uni_modules/y-tabs/components/css/index.scss
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,464 @@
 | 
				
			|||||||
 | 
					.y-tabs {
 | 
				
			||||||
 | 
						position: relative;
 | 
				
			||||||
 | 
						display: block;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 标签栏垂直方位下的根容器样式
 | 
				
			||||||
 | 
						&.is-vertical {
 | 
				
			||||||
 | 
							display: flex;
 | 
				
			||||||
 | 
							flex-wrap: nowrap;
 | 
				
			||||||
 | 
							flex-direction: row;
 | 
				
			||||||
 | 
							justify-content: flex-end;
 | 
				
			||||||
 | 
							flex: 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// 垂直时标签栏scroll-view的子项垂直排列
 | 
				
			||||||
 | 
							.y-tabs__scroll {
 | 
				
			||||||
 | 
								flex-direction: column;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 区域滚动下的滚动导航
 | 
				
			||||||
 | 
						&.is-areaScroll.is-scrollNav {
 | 
				
			||||||
 | 
							display: flex;
 | 
				
			||||||
 | 
							height: 100vh;
 | 
				
			||||||
 | 
							flex-direction: column;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// 标签栏不收缩
 | 
				
			||||||
 | 
							.y-tabs__wrap {
 | 
				
			||||||
 | 
								flex-shrink: 0;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							.y-tabs__track,
 | 
				
			||||||
 | 
							.y-tabs__content-scrollview {
 | 
				
			||||||
 | 
								height: 100%;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 区域滚动下的侧边栏导航
 | 
				
			||||||
 | 
						&.is-areaScroll.is-sidebarNav {
 | 
				
			||||||
 | 
							display: flex;
 | 
				
			||||||
 | 
							height: 100vh;
 | 
				
			||||||
 | 
							flex-direction: row;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							.y-tabs__scroll {
 | 
				
			||||||
 | 
								height: 100%;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// 标签栏不收缩
 | 
				
			||||||
 | 
							.y-tabs__wrap {
 | 
				
			||||||
 | 
								flex-shrink: 0;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							.y-tabs__track,
 | 
				
			||||||
 | 
							.y-tabs__content-scrollview {
 | 
				
			||||||
 | 
								height: 100%;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 依赖元素
 | 
				
			||||||
 | 
					.y-tabs__depend {
 | 
				
			||||||
 | 
						position: absolute;
 | 
				
			||||||
 | 
						top: 0;
 | 
				
			||||||
 | 
						left: 0;
 | 
				
			||||||
 | 
						height: 1px; //必须保证有高度,否则observer无效
 | 
				
			||||||
 | 
						width: 100%;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 透明标签栏所需的依赖元素
 | 
				
			||||||
 | 
					.y-tabs__depend--transparent {
 | 
				
			||||||
 | 
						position: absolute;
 | 
				
			||||||
 | 
						top: 0;
 | 
				
			||||||
 | 
						left: 0;
 | 
				
			||||||
 | 
						height: 1px; //必须保证有高度,否则observer无效
 | 
				
			||||||
 | 
						width: 1px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 模拟标签栏吸顶时设置offset时距屏幕顶部的元素
 | 
				
			||||||
 | 
					.y-tabs__depend--offset {
 | 
				
			||||||
 | 
						position: fixed;
 | 
				
			||||||
 | 
						top: 0;
 | 
				
			||||||
 | 
						left: 0;
 | 
				
			||||||
 | 
						z-index: -1;
 | 
				
			||||||
 | 
						height: 1px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 标签栏占位元素
 | 
				
			||||||
 | 
					.y-tabs__placeholder {
 | 
				
			||||||
 | 
						position: relative;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 标签垂直展示且吸顶时,标签栏占位元素不伸缩
 | 
				
			||||||
 | 
					.y-tabs.is-fixed.is-vertical .y-tabs__placeholder {
 | 
				
			||||||
 | 
						flex-shrink: 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 文字省略
 | 
				
			||||||
 | 
					.y-tabs__ellipsis {
 | 
				
			||||||
 | 
						overflow: hidden;
 | 
				
			||||||
 | 
						text-overflow: ellipsis;
 | 
				
			||||||
 | 
						white-space: nowrap;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 导航区域包裹层
 | 
				
			||||||
 | 
					.y-tabs__wrap {
 | 
				
			||||||
 | 
						position: relative;
 | 
				
			||||||
 | 
						display: flex;
 | 
				
			||||||
 | 
						align-items: center;
 | 
				
			||||||
 | 
						overflow: hidden;
 | 
				
			||||||
 | 
						visibility: visible;
 | 
				
			||||||
 | 
						background: #fff;
 | 
				
			||||||
 | 
						touch-action: none;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 标签栏垂直展示时包裹层样式
 | 
				
			||||||
 | 
						&.is-vertical {
 | 
				
			||||||
 | 
							width: 100px;
 | 
				
			||||||
 | 
							display: flex;
 | 
				
			||||||
 | 
							flex-direction: column;
 | 
				
			||||||
 | 
							flex-shrink: 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 粘性定位布局下的导航区域包裹层
 | 
				
			||||||
 | 
						&.is-fixed {
 | 
				
			||||||
 | 
							position: fixed;
 | 
				
			||||||
 | 
							top: 0;
 | 
				
			||||||
 | 
							right: 0;
 | 
				
			||||||
 | 
							left: 0;
 | 
				
			||||||
 | 
							z-index: 99;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 标签垂直展示且吸顶时,给定bottom,否则scroll-view不会滚动
 | 
				
			||||||
 | 
						&.is-fixed.is-vertical {
 | 
				
			||||||
 | 
							bottom: 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 透明的导航区域包裹层
 | 
				
			||||||
 | 
						&.is-transparent {
 | 
				
			||||||
 | 
							background: rgba(255, 255, 255, 0);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 标签栏水平时按钮风格的包裹层
 | 
				
			||||||
 | 
						&.is-button:not(.is-vertical),
 | 
				
			||||||
 | 
						&.is-line-button:not(.is-vertical) {
 | 
				
			||||||
 | 
							padding: 0 8px;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// scroll-view组件样式
 | 
				
			||||||
 | 
					.y-tabs__scroll {
 | 
				
			||||||
 | 
						position: relative;
 | 
				
			||||||
 | 
						width: 100%;
 | 
				
			||||||
 | 
						white-space: nowrap; // 使用横向滚动时,需要给<scroll-view>添加white-space: nowrap;样式
 | 
				
			||||||
 | 
						flex-direction: row;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 条件编译不放在样式中,vue3无效
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// H5、APP端去滚动条
 | 
				
			||||||
 | 
					// 小程序端会报:Some selectors are not allowed in component wxss, including tag name selectors, ID selectors, and attribute selectors.
 | 
				
			||||||
 | 
					/* #ifdef H5 || APP */
 | 
				
			||||||
 | 
					.y-tabs__scroll ::-webkit-scrollbar {
 | 
				
			||||||
 | 
						display: none;
 | 
				
			||||||
 | 
						width: 0;
 | 
				
			||||||
 | 
						height: 0;
 | 
				
			||||||
 | 
						-webkit-appearance: none;
 | 
				
			||||||
 | 
						background: transparent;
 | 
				
			||||||
 | 
						color: transparent;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					/* #endif */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// IOS 13 以下的系统,当滚动区域设置了-webkit-overflow-scrolling: touch;时(必须设置,否者几乎无法滚动),::-webkit-scrollbar 相关属性会失效,iOS 13 已经修复了此Bug。
 | 
				
			||||||
 | 
					// 小程序端: 去除 scroll-view 组件的滚动条
 | 
				
			||||||
 | 
					/* #ifndef H5 || APP  */
 | 
				
			||||||
 | 
					::-webkit-scrollbar {
 | 
				
			||||||
 | 
						display: none;
 | 
				
			||||||
 | 
						width: 0;
 | 
				
			||||||
 | 
						height: 0;
 | 
				
			||||||
 | 
						-webkit-appearance: none;
 | 
				
			||||||
 | 
						background: transparent;
 | 
				
			||||||
 | 
						color: transparent;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					/* #endif */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 导航区域
 | 
				
			||||||
 | 
					.y-tabs__nav {
 | 
				
			||||||
 | 
						position: relative;
 | 
				
			||||||
 | 
						box-sizing: border-box;
 | 
				
			||||||
 | 
						user-select: none;
 | 
				
			||||||
 | 
						flex: 1;
 | 
				
			||||||
 | 
						display: flex;
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						&.is-shrink{
 | 
				
			||||||
 | 
							display: inline-flex;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						// 卡片风格
 | 
				
			||||||
 | 
						&.is-card {
 | 
				
			||||||
 | 
							margin: 6px 16px;
 | 
				
			||||||
 | 
							border-radius: 4px;
 | 
				
			||||||
 | 
							box-sizing: border-box;
 | 
				
			||||||
 | 
							border: 1px solid #0022ab;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 标签栏垂直时导航区域样式
 | 
				
			||||||
 | 
						&.is-vertical {
 | 
				
			||||||
 | 
							flex-direction: column;
 | 
				
			||||||
 | 
							height: auto;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							.y-tab {
 | 
				
			||||||
 | 
								flex: unset;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 标签左侧、右侧的补充区域
 | 
				
			||||||
 | 
						&-left,
 | 
				
			||||||
 | 
						&-right {
 | 
				
			||||||
 | 
							position: relative;
 | 
				
			||||||
 | 
							display: inline-flex;
 | 
				
			||||||
 | 
							white-space: nowrap;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 导航标签
 | 
				
			||||||
 | 
					.y-tab {
 | 
				
			||||||
 | 
						position: relative;
 | 
				
			||||||
 | 
						display: inline-flex;
 | 
				
			||||||
 | 
						align-items: center;
 | 
				
			||||||
 | 
						justify-content: center;
 | 
				
			||||||
 | 
						box-sizing: border-box;
 | 
				
			||||||
 | 
						height: 40px;
 | 
				
			||||||
 | 
						font-size: 28rpx;
 | 
				
			||||||
 | 
						color: #646566;
 | 
				
			||||||
 | 
						text-align: center;
 | 
				
			||||||
 | 
						padding: 0 4px;
 | 
				
			||||||
 | 
						flex: 1;
 | 
				
			||||||
 | 
						cursor: pointer;
 | 
				
			||||||
 | 
						// webkit的css扩展:1、-webkit-tap-highlight-color:这个属性是用于设定元素在移动设备(如Adnroid、iOS)上被触发点击事件时,响应的背景框的颜色。有事件监听的元素被点击的时候会被高亮显示,比如我的android上表现为一个蓝框加上半透明的背景
 | 
				
			||||||
 | 
						-webkit-tap-highlight-color: transparent;
 | 
				
			||||||
 | 
						// transition-duration: 0.2s;
 | 
				
			||||||
 | 
						// transition-property: background;
 | 
				
			||||||
 | 
						flex-shrink: 0;
 | 
				
			||||||
 | 
						z-index: 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 选中状态
 | 
				
			||||||
 | 
						&.is-active {
 | 
				
			||||||
 | 
							color: #323233;
 | 
				
			||||||
 | 
							font-weight: 500;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 禁用状态
 | 
				
			||||||
 | 
						&.is-disabled {
 | 
				
			||||||
 | 
							color: #c8c9cc !important;
 | 
				
			||||||
 | 
							cursor: not-allowed;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 收缩布局
 | 
				
			||||||
 | 
						&.is-shrink {
 | 
				
			||||||
 | 
							flex: none;
 | 
				
			||||||
 | 
							padding: 0 8px;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//卡片风格
 | 
				
			||||||
 | 
						&.is-card {
 | 
				
			||||||
 | 
							height: 28px;
 | 
				
			||||||
 | 
							line-height: 28px;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 标题区域
 | 
				
			||||||
 | 
					.y-tab__title {
 | 
				
			||||||
 | 
						overflow: hidden;
 | 
				
			||||||
 | 
						display: flex;
 | 
				
			||||||
 | 
						align-items: center;
 | 
				
			||||||
 | 
						height: inherit;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 标题区域垂直排列
 | 
				
			||||||
 | 
					.y-tab__title--top,
 | 
				
			||||||
 | 
					.y-tab__title--bottom {
 | 
				
			||||||
 | 
						flex-direction: column;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 标题文字
 | 
				
			||||||
 | 
					.y-tab__text {
 | 
				
			||||||
 | 
						position: relative;
 | 
				
			||||||
 | 
						display: block;
 | 
				
			||||||
 | 
						line-height: 1.2;
 | 
				
			||||||
 | 
						order: 2;
 | 
				
			||||||
 | 
						white-space: nowrap; //字节会设置white-space:normal
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 标签垂直展示时,未达到文字超出隐藏的条件时
 | 
				
			||||||
 | 
					.y-tabs__nav.is-vertical .y-tab__text:not(.y-tabs__ellipsis) {
 | 
				
			||||||
 | 
						white-space: normal;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 使用order排序
 | 
				
			||||||
 | 
					.y-tab__text--left,
 | 
				
			||||||
 | 
					.y-tab__text--top {
 | 
				
			||||||
 | 
						order: 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 标题图标/图片包裹层
 | 
				
			||||||
 | 
					.y-tab__icons {
 | 
				
			||||||
 | 
						display: flex;
 | 
				
			||||||
 | 
						align-items: center;
 | 
				
			||||||
 | 
						order: 1;
 | 
				
			||||||
 | 
						z-index: 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//标题图片
 | 
				
			||||||
 | 
					.y-tab__image {
 | 
				
			||||||
 | 
						width: 20px;
 | 
				
			||||||
 | 
						height: 20px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 右上角信息区域
 | 
				
			||||||
 | 
					.y-tab__info {
 | 
				
			||||||
 | 
						display: inline-flex;
 | 
				
			||||||
 | 
						position: relative;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						&--dot,
 | 
				
			||||||
 | 
						&--badge {
 | 
				
			||||||
 | 
							display: inline-block;
 | 
				
			||||||
 | 
							position: absolute;
 | 
				
			||||||
 | 
							top: 0;
 | 
				
			||||||
 | 
							left: 0;
 | 
				
			||||||
 | 
							box-sizing: border-box;
 | 
				
			||||||
 | 
							background-color: #e53935;
 | 
				
			||||||
 | 
							transform-origin: 100%;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 小红点
 | 
				
			||||||
 | 
						&--dot {
 | 
				
			||||||
 | 
							width: 6px;
 | 
				
			||||||
 | 
							height: 6px;
 | 
				
			||||||
 | 
							border-radius: 100%;
 | 
				
			||||||
 | 
							transform: translate(0%, -180%);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 徽标
 | 
				
			||||||
 | 
						&--badge {
 | 
				
			||||||
 | 
							line-height: 13px;
 | 
				
			||||||
 | 
							min-width: 18px;
 | 
				
			||||||
 | 
							border-radius: 18px;
 | 
				
			||||||
 | 
							padding: 0 2px;
 | 
				
			||||||
 | 
							transform: translate(0%, -120%);
 | 
				
			||||||
 | 
							font-size: 18rpx;
 | 
				
			||||||
 | 
							font-weight: 500;
 | 
				
			||||||
 | 
							text-align: center;
 | 
				
			||||||
 | 
							color: #fff;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 底部条滑块
 | 
				
			||||||
 | 
					.y-tabs__bar {
 | 
				
			||||||
 | 
						position: absolute;
 | 
				
			||||||
 | 
						display: inline-flex;
 | 
				
			||||||
 | 
						left: 0;
 | 
				
			||||||
 | 
						z-index: 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						width: 20px;
 | 
				
			||||||
 | 
						height: 3px;
 | 
				
			||||||
 | 
						border-radius: 3px;
 | 
				
			||||||
 | 
						background-color: #0022ab;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// line风格的滑块
 | 
				
			||||||
 | 
						&.is-line {
 | 
				
			||||||
 | 
							z-index: 2; //z-index与y-tab一样,避免被遮挡
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// 标签水平展示时
 | 
				
			||||||
 | 
							&:not(.is-vertical) {
 | 
				
			||||||
 | 
								bottom: 3px;
 | 
				
			||||||
 | 
								width: 20px;
 | 
				
			||||||
 | 
								height: 3px;
 | 
				
			||||||
 | 
								border-radius: 3px;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// 标签垂直展示时
 | 
				
			||||||
 | 
							&.is-vertical {
 | 
				
			||||||
 | 
								top: 0;
 | 
				
			||||||
 | 
								left: 3px;
 | 
				
			||||||
 | 
								width: 3px;
 | 
				
			||||||
 | 
								height: 20px;
 | 
				
			||||||
 | 
								border-radius: 3px;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// button、line-button风格的滑块
 | 
				
			||||||
 | 
						&.is-button,
 | 
				
			||||||
 | 
						&.is-line-button {
 | 
				
			||||||
 | 
							// top: 0;
 | 
				
			||||||
 | 
							justify-content: center;
 | 
				
			||||||
 | 
							align-items: center;
 | 
				
			||||||
 | 
							border-radius: 26px;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// 标签水平展示时
 | 
				
			||||||
 | 
							&:not(.is-vertical) {
 | 
				
			||||||
 | 
								height: calc(100% - 8px);
 | 
				
			||||||
 | 
								bottom: 4px;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// 标签垂直展示时
 | 
				
			||||||
 | 
							&.is-vertical {
 | 
				
			||||||
 | 
								width: calc(100% - 8px);
 | 
				
			||||||
 | 
								height: calc(100% - 8px);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 线性按钮风格的滑块
 | 
				
			||||||
 | 
						&.is-line-button {
 | 
				
			||||||
 | 
							background-color: transparent;
 | 
				
			||||||
 | 
							border: 2rpx solid transparent;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 标签内容
 | 
				
			||||||
 | 
					.y-tabs__content {
 | 
				
			||||||
 | 
						display: block;
 | 
				
			||||||
 | 
						position: relative;
 | 
				
			||||||
 | 
						overflow: hidden; //会导致uni-data-select无法撑开显示下拉选项,最好给pane中的内容设置一个高度(如果包裹select的父元素都没有设置relative,则不会裁剪absolute属性的元素)
 | 
				
			||||||
 | 
						// 标签栏垂直展示,内容减去标签栏默认宽度
 | 
				
			||||||
 | 
						&.is-vertical {
 | 
				
			||||||
 | 
							width: 100%;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					// 标签内容的滑动轨道容器
 | 
				
			||||||
 | 
					.y-tabs__track {
 | 
				
			||||||
 | 
						position: relative;
 | 
				
			||||||
 | 
						display: flex;
 | 
				
			||||||
 | 
						width: 100%;
 | 
				
			||||||
 | 
						will-change: left;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 滚动导航模式下内容卡片垂直排列
 | 
				
			||||||
 | 
						&.is-scrollspy {
 | 
				
			||||||
 | 
							flex-direction: column;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 标签内容卡片
 | 
				
			||||||
 | 
					.y-tab__pane {
 | 
				
			||||||
 | 
						flex-shrink: 0;
 | 
				
			||||||
 | 
						box-sizing: border-box;
 | 
				
			||||||
 | 
						width: 100%;
 | 
				
			||||||
 | 
						height: 0;
 | 
				
			||||||
 | 
						position: relative;
 | 
				
			||||||
 | 
						flex-direction: row;
 | 
				
			||||||
 | 
						display: block;
 | 
				
			||||||
 | 
						visibility: visible;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 选中时
 | 
				
			||||||
 | 
						&.is-active {
 | 
				
			||||||
 | 
							height: auto;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// 滚动导航
 | 
				
			||||||
 | 
						&.is-scrollspy {
 | 
				
			||||||
 | 
							height: auto;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.y-tab__pane--wrap {
 | 
				
			||||||
 | 
						position: relative;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					// 区域滚动下的标签内容scroll-view
 | 
				
			||||||
 | 
					.y-tabs__content-scrollview {
 | 
				
			||||||
 | 
						flex-direction: column;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										194
									
								
								smart-app/src/uni_modules/y-tabs/components/js/const.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										194
									
								
								smart-app/src/uni_modules/y-tabs/components/js/const.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,194 @@
 | 
				
			|||||||
 | 
					// styleIsolation:组件样式隔离方式,具体配置选项参见:微信小程序自定义组件的样式
 | 
				
			||||||
 | 
					// 自定义组件 JSON 中的 styleIsolation 选项从基础库版本 2.10.1 开始支持。它支持以下取值:
 | 
				
			||||||
 | 
					// isolated 表示启用样式隔离,在自定义组件内外,使用 class 指定的样式将不会相互影响(一般情况下的默认值);
 | 
				
			||||||
 | 
					// apply-shared 表示页面 wxss 样式将影响到自定义组件,但自定义组件 wxss 中指定的样式不会影响页面;
 | 
				
			||||||
 | 
					// shared 表示页面 wxss 样式将影响到自定义组件,自定义组件 wxss 中指定的样式也会影响页面和其他设置了 apply-shared 或 shared 的自定义组件。(这个选项在插件中不可用。)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const options = {
 | 
				
			||||||
 | 
						styleIsolation: 'shared',
 | 
				
			||||||
 | 
						virtualHost: true // [微信小程序、支付宝小程序(默认值为 true)] 将自定义节点设置成虚拟的,更加接近Vue组件的表现。我们不希望自定义组件的这个节点本身可以设置样式、响应 flex 布局等,而是希望自定义组件内部的第一层节点能够响应 flex 布局或者样式由自定义组件本身完全决定
 | 
				
			||||||
 | 
						// 微信(可以使用virtualHost配置)/QQ/百度/字节跳动这四家小程序,自定义组件在渲染时会比App/H5端多一级节点,导致flex无效,是否考虑在组件上增加class控制
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const emits = [
 | 
				
			||||||
 | 
						"input",
 | 
				
			||||||
 | 
						'update:modelValue', // 更新v-model绑定的变量
 | 
				
			||||||
 | 
						'click', //点击标签时触发 回调参数:name:标识符,title:标题
 | 
				
			||||||
 | 
						'change', //当前激活的标签改变时触发 回调参数:name:标识符,title:标题
 | 
				
			||||||
 | 
						'disabled', //点击被禁用的标签时触发 回调参数:name:标识符,title:标题
 | 
				
			||||||
 | 
						'rendered', //标签内容首次渲染时触发(仅在开启延迟渲染后触发) 回调参数:name:标识符,title:标题
 | 
				
			||||||
 | 
						'sticky-change', //吸顶时触发,仅在 sticky 模式下生效 回调参数:name:标识符,title:标题
 | 
				
			||||||
 | 
						'loaded', //组件内部初始化完成后调用 回调参数:{ isFixed: 是否吸顶 }
 | 
				
			||||||
 | 
						'slide-change', //内容页滑动时触发(仅barAnimateMode为linear、worm、worm-ease时有效) 回调参数:{ dx:滑动距离; rate:当前滑动长度占滑动区域的比例;targetIndex:目标下标;}
 | 
				
			||||||
 | 
						'slide-end' //内容页滑动结束时触发(仅barAnimateMode为linear、worm、worm-ease时有效) 回调参数:{ targetIndex:目标下标;}
 | 
				
			||||||
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const props = {
 | 
				
			||||||
 | 
						// v-model绑定属性,绑定当前选中标签的标识符(标签的下标)
 | 
				
			||||||
 | 
						value: {
 | 
				
			||||||
 | 
							type: [Number, String],
 | 
				
			||||||
 | 
							default: 0,
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						modelValue: {
 | 
				
			||||||
 | 
							type: [Number, String],
 | 
				
			||||||
 | 
							default: 0,
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						// 样式风格类型,可选值为 text、card、button、line-button
 | 
				
			||||||
 | 
						type: {
 | 
				
			||||||
 | 
							type: String,
 | 
				
			||||||
 | 
							default: "line",
 | 
				
			||||||
 | 
							validator(value) {
 | 
				
			||||||
 | 
								return ['line', 'text', 'card', 'button', 'line-button'].includes(value)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						color: {
 | 
				
			||||||
 | 
							type: [String, null],
 | 
				
			||||||
 | 
							default: "#0022AB"
 | 
				
			||||||
 | 
						}, //标签主题色, 默认值为"#0022AB"
 | 
				
			||||||
 | 
						background: {
 | 
				
			||||||
 | 
							type: [String, null],
 | 
				
			||||||
 | 
							// default: "#fff"
 | 
				
			||||||
 | 
						}, //标签栏背景色,默认值为"#fff"
 | 
				
			||||||
 | 
						// 标签栏样式
 | 
				
			||||||
 | 
						wrapStyle: {
 | 
				
			||||||
 | 
							type: [Object, null],
 | 
				
			||||||
 | 
							default: () => {}
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						// 标签栏的展示方位,可选值:vertical。
 | 
				
			||||||
 | 
						direction: {
 | 
				
			||||||
 | 
							type: String,
 | 
				
			||||||
 | 
							default: "horizontal",
 | 
				
			||||||
 | 
							validator(value) {
 | 
				
			||||||
 | 
								return ['horizontal', 'vertical'].includes(value)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						titleActiveColor: String, //标题选中态颜色
 | 
				
			||||||
 | 
						titleInactiveColor: String, //标题默认态颜色
 | 
				
			||||||
 | 
						// 是否开启左侧收缩布局,开启后,所有的标签会向左侧收缩对齐。
 | 
				
			||||||
 | 
						shrink: {
 | 
				
			||||||
 | 
							type: Boolean,
 | 
				
			||||||
 | 
							default: false
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 动画时间,单位秒,默认为0.3s。仅支持type为line、button、line-button的滑块切换动画,切换标签内容时的转场动画、滚动导航下的内容定位动画。
 | 
				
			||||||
 | 
						duration: {
 | 
				
			||||||
 | 
							type: [Number, String],
 | 
				
			||||||
 | 
							default: 0.2,
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						// 滑块宽度,默认单位为px, 支持数字、rpx、vh、vw等单位及calc() 函数。 仅支持type为line、button、line-button。
 | 
				
			||||||
 | 
						// 标签栏水平/垂直展示时,type为line,宽度默认为20px/3px, 而type为button、line-button时,宽度默认为选中标签宽度-8px。 
 | 
				
			||||||
 | 
						barWidth: [Number, String], //inherit:继承tab的宽高
 | 
				
			||||||
 | 
						// 滑块高度,默认单位为px, 支持数字、rpx、vh、vw等单位及calc() 函数。 仅支持type为line、button、line-button。
 | 
				
			||||||
 | 
						// 标签栏水平/垂直展示时,type为line,高度默认为3px/20px, 而type为button、line-button时,宽度默认为选中标签高度-8px。 
 | 
				
			||||||
 | 
						barHeight: [Number, String],
 | 
				
			||||||
 | 
						//滑块样式,仅支持type为line、button、line-button。
 | 
				
			||||||
 | 
						barStyle: Object,
 | 
				
			||||||
 | 
						// 滑动切换tab内容时滑块的动画模式,默认值为line,即切换tab时滑块宽度保持不变,线性运动。可选值为worm(毛毛虫效果)、worm-ease(毛毛虫缓动)、none(不设置)。
 | 
				
			||||||
 | 
						// 可结合swiper组件使用,滑动效果更好。
 | 
				
			||||||
 | 
						// 仅支持type为line。
 | 
				
			||||||
 | 
						barAnimateMode: {
 | 
				
			||||||
 | 
							type: String,
 | 
				
			||||||
 | 
							default: "linear",
 | 
				
			||||||
 | 
							validator(value) {
 | 
				
			||||||
 | 
								return ['none', 'linear', 'worm', 'worm-ease'].includes(value);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						// 标签宽高是否动态变化
 | 
				
			||||||
 | 
						// 表示标签切换了选中状态后宽高是否有变化,有则需要开启该属性,否则会导致滑块错位
 | 
				
			||||||
 | 
						isDynamic: {
 | 
				
			||||||
 | 
							type: Boolean,
 | 
				
			||||||
 | 
							default: false,
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						// 是否省略过长的标题文字。标签栏水平展示时,如果标签数量未超过滚动阈值则生效,垂直展示不限制。
 | 
				
			||||||
 | 
						ellipsis: {
 | 
				
			||||||
 | 
							type: Boolean,
 | 
				
			||||||
 | 
							default: true,
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						// 滚动阈值,标签数量超过阈值且总宽度超过标签栏宽度时开始横向滚动
 | 
				
			||||||
 | 
						scrollThreshold: {
 | 
				
			||||||
 | 
							type: [Number, String],
 | 
				
			||||||
 | 
							default: 5
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						// 标签栏滚动时当前标签居中
 | 
				
			||||||
 | 
						scrollToCenter: {
 | 
				
			||||||
 | 
							type: Boolean,
 | 
				
			||||||
 | 
							default: true,
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						// 切换标签前的回调函数,返回 false 可阻止切换,支持返回 Promise
 | 
				
			||||||
 | 
						beforeChange: Function,
 | 
				
			||||||
 | 
						// 是否开启延迟渲染(首次切换到标签时才触发内容渲染)
 | 
				
			||||||
 | 
						isLazyRender: Boolean,
 | 
				
			||||||
 | 
						// 是否开启切换动画
 | 
				
			||||||
 | 
						// 用于标签栏滚动动画、切换标签内容时的转场动画、滚动导航下的内容定位动画
 | 
				
			||||||
 | 
						animated: {
 | 
				
			||||||
 | 
							type: Boolean,
 | 
				
			||||||
 | 
							default: true
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						// 在滚动导航模式下,滚动到最后一个标签内容但其顶部未超过可视区域时,是否激活对应的标签项
 | 
				
			||||||
 | 
						activeLast: {
 | 
				
			||||||
 | 
							type: Boolean,
 | 
				
			||||||
 | 
							default: false,
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						// ---------------------------------- 用于内容区域左右滑动的配置 ----------------------------------------
 | 
				
			||||||
 | 
						// 是否开启手势滑动切换
 | 
				
			||||||
 | 
						swipeable: {
 | 
				
			||||||
 | 
							type: Boolean,
 | 
				
			||||||
 | 
							default: false,
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						// 是否开启标签内容滑动时的拖动动画
 | 
				
			||||||
 | 
						// swipeable为true时有效,建议设置is-lazy-render=false。(该属性开启时考虑给包裹内容的容器增加一个min-height,因为其他未显示的标签内容会沿用当前显示的高度,拖动切换后由于高度不一致会有回弹)
 | 
				
			||||||
 | 
						swipeAnimated: {
 | 
				
			||||||
 | 
							type: Boolean,
 | 
				
			||||||
 | 
							default: true,
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						// 滑动切换的滑动距离阈值,单位为px;表示开启手势滑动时,横向滑动多少px切换标签内容(快速滑动时不受限制)
 | 
				
			||||||
 | 
						swipeThreshold: {
 | 
				
			||||||
 | 
							type: [Number, String],
 | 
				
			||||||
 | 
							default: 120,
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						// ---------------------------------- 用于滚动吸顶的配置 ----------------------------------------
 | 
				
			||||||
 | 
						// 是否使用粘性定位布局进行滚动吸顶
 | 
				
			||||||
 | 
						sticky: Boolean,
 | 
				
			||||||
 | 
						// 粘性布局下与顶部的最小距离,单位为px
 | 
				
			||||||
 | 
						offsetTop: {
 | 
				
			||||||
 | 
							type: Number,
 | 
				
			||||||
 | 
							default: 0
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						// 粘性布局下标签栏的z-index值
 | 
				
			||||||
 | 
						zIndex: {
 | 
				
			||||||
 | 
							type: Number,
 | 
				
			||||||
 | 
							default: 99
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						// 粘性布局的判断阈值:表示在页面滚动过程中,标签栏距屏幕顶部多少px时,触发吸顶函数进行吸顶判断
 | 
				
			||||||
 | 
						stickyThreshold: {
 | 
				
			||||||
 | 
							type: Number,
 | 
				
			||||||
 | 
							default: 0
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						// 页面滚动过程中,标题栏背景色是否透明渐变
 | 
				
			||||||
 | 
						// background属性值必须为rgba格式
 | 
				
			||||||
 | 
						transparent: {
 | 
				
			||||||
 | 
							type: Boolean,
 | 
				
			||||||
 | 
							default: false
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						// 标题栏背景色透明渐变的滚动距离
 | 
				
			||||||
 | 
						transparentOffset: {
 | 
				
			||||||
 | 
							type: Number,
 | 
				
			||||||
 | 
							default: 100
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						// 是否开启滚动导航;该模式下,内容将会平铺展示
 | 
				
			||||||
 | 
						// 如果标签栏垂直展示,且内容平铺展示,就为侧边栏模式
 | 
				
			||||||
 | 
						scrollspy: Boolean,
 | 
				
			||||||
 | 
						// 滚动导航模式下,内容区域是否跟随页面滚动
 | 
				
			||||||
 | 
						// 为true时,整体区域跟随页面而滚动,为false时,内容区域是放在scroll-view中实现的局部滚动
 | 
				
			||||||
 | 
						pageScroll: {
 | 
				
			||||||
 | 
							type: Boolean,
 | 
				
			||||||
 | 
							default: true
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					export {
 | 
				
			||||||
 | 
						options,
 | 
				
			||||||
 | 
						emits,
 | 
				
			||||||
 | 
						props,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										75
									
								
								smart-app/src/uni_modules/y-tabs/components/js/touchMixin.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								smart-app/src/uni_modules/y-tabs/components/js/touchMixin.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,75 @@
 | 
				
			|||||||
 | 
					import { getDirection, now } from "./uitls"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const touchMixin = {
 | 
				
			||||||
 | 
						data() {
 | 
				
			||||||
 | 
							return {
 | 
				
			||||||
 | 
								direction: '', //滑动方向
 | 
				
			||||||
 | 
								startX: '', //开始滑动的x坐标
 | 
				
			||||||
 | 
								startY: '', //开始滑动的y坐标
 | 
				
			||||||
 | 
								nextIndex: -1, //下一个切换的标签下标
 | 
				
			||||||
 | 
								moved: false, //是否为一次水平滑动
 | 
				
			||||||
 | 
								startTimestamp: 0,
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						methods: {
 | 
				
			||||||
 | 
							touchStart(event) {
 | 
				
			||||||
 | 
								if (!this.parent.swipeable) return;
 | 
				
			||||||
 | 
								this.resetTouchStatus();
 | 
				
			||||||
 | 
								this.startX = event.touches[0].clientX;
 | 
				
			||||||
 | 
								this.startY = event.touches[0].clientY;
 | 
				
			||||||
 | 
								this.startTimestamp = now();
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							touchMove(event) {
 | 
				
			||||||
 | 
								if (!this.parent.swipeable) return;
 | 
				
			||||||
 | 
								const touch = event.touches[0];
 | 
				
			||||||
 | 
								this.deltaX = touch.clientX < 0 ? 0 : this.startX - touch.clientX;
 | 
				
			||||||
 | 
								this.deltaY = this.startY - touch.clientY;
 | 
				
			||||||
 | 
								const offsetX = Math.abs(this.deltaX);
 | 
				
			||||||
 | 
								const offsetY = Math.abs(this.deltaY);
 | 
				
			||||||
 | 
								// 当距离大于某个值时锁定方向
 | 
				
			||||||
 | 
								if (!this.direction || (offsetX < 10 && offsetY < 10)) this.direction = getDirection(offsetX, offsetY);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (this.direction === "horizontal") { //水平滑动
 | 
				
			||||||
 | 
									const { dataLen, contentWidth, currentIndex, tabs, swipeAnimated } = this.parent;
 | 
				
			||||||
 | 
									const isRight = this.deltaX < 0; //判断是否向右滑动
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									// 如果为第一页,则不允许向右滑;为最后一页,则不允许左滑
 | 
				
			||||||
 | 
									if ((isRight && currentIndex === 0) || (!isRight && currentIndex === dataLen - 1)) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									this.nextIndex = currentIndex + (isRight ? -1 : 1); //下一个标签
 | 
				
			||||||
 | 
									if (tabs[this.nextIndex]?.disabled) return; //禁用的标签不允许滑动
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									this.moved = true; //标记为一次水平滑动
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									// 改变标签内容滑动轨道样式,模拟拖动动画效果
 | 
				
			||||||
 | 
									if (swipeAnimated) {
 | 
				
			||||||
 | 
										const offsetWidth = contentWidth * currentIndex * -1 + offsetX * (isRight ? 1 : -1);
 | 
				
			||||||
 | 
										this.parent.changeTrackStyle(true, 0, offsetWidth);
 | 
				
			||||||
 | 
										this.parent.setDx(this.deltaX, false);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							touchEnd() {
 | 
				
			||||||
 | 
								if (this.moved) {
 | 
				
			||||||
 | 
									// 何时可切换标签,当横向滑动距离大于设定阈值,或快速滑动(300ms内)切滑动距离大于18px时
 | 
				
			||||||
 | 
									const deltaTime = now() - this.startTimestamp;
 | 
				
			||||||
 | 
									const distance = Math.abs(this.deltaX);
 | 
				
			||||||
 | 
									const speed = (distance / deltaTime).toFixed(4);
 | 
				
			||||||
 | 
									const isChange = speed > 0.25 || distance >= this.parent.swipeThreshold;//是否切换
 | 
				
			||||||
 | 
									const currIndex = this.parent.currentIndex; //当前选中下标
 | 
				
			||||||
 | 
									const targetIndex = isChange ? this.nextIndex : currIndex; //目标标签的下标
 | 
				
			||||||
 | 
									this.parent.touchEndForPane(this.deltaX, currIndex, targetIndex, isChange);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							// 重置触摸状态
 | 
				
			||||||
 | 
							resetTouchStatus() {
 | 
				
			||||||
 | 
								this.direction = '';
 | 
				
			||||||
 | 
								this.deltaX = 0;
 | 
				
			||||||
 | 
								this.deltaY = 0;
 | 
				
			||||||
 | 
								this.nextIndex = -1;
 | 
				
			||||||
 | 
								this.moved = false;
 | 
				
			||||||
 | 
								this.startTimestamp = 0;
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										177
									
								
								smart-app/src/uni_modules/y-tabs/components/js/uitls.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										177
									
								
								smart-app/src/uni_modules/y-tabs/components/js/uitls.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,177 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 判断传入的值是否为空
 | 
				
			||||||
 | 
					 * @param {*} val 
 | 
				
			||||||
 | 
					 * @returns 
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					export function isNull(val) {
 | 
				
			||||||
 | 
						if (typeof val == "boolean") {
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (typeof val == "number") {
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (val instanceof Array) {
 | 
				
			||||||
 | 
							if (val.length == 0) return true;
 | 
				
			||||||
 | 
						} else if (val instanceof Object) {
 | 
				
			||||||
 | 
							if (JSON.stringify(val) === "{}") return true;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							if (
 | 
				
			||||||
 | 
								val == "null" ||
 | 
				
			||||||
 | 
								val == null ||
 | 
				
			||||||
 | 
								val == "undefined" ||
 | 
				
			||||||
 | 
								val == undefined ||
 | 
				
			||||||
 | 
								val == ""
 | 
				
			||||||
 | 
							)
 | 
				
			||||||
 | 
								return true;
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 不为空
 | 
				
			||||||
 | 
					export function isDef(val) {
 | 
				
			||||||
 | 
						return val !== undefined && val !== null;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 是否是一个数字
 | 
				
			||||||
 | 
					export function isNumeric(val) {
 | 
				
			||||||
 | 
						return /^\d+(\.\d+)?$/.test(val);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 是一个对象
 | 
				
			||||||
 | 
					export function isObject(val) {
 | 
				
			||||||
 | 
						return val !== null && typeof val === 'object';
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					// 是一个字符串
 | 
				
			||||||
 | 
					export function isString(val) {
 | 
				
			||||||
 | 
						return Object.prototype.toString.call(val) === "[object String]"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 空操作
 | 
				
			||||||
 | 
					export function noop() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 是一个函数
 | 
				
			||||||
 | 
					export function isFunction(val) {
 | 
				
			||||||
 | 
						return typeof val === 'function';
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 是一个promise对象
 | 
				
			||||||
 | 
					export function isPromise(val) {
 | 
				
			||||||
 | 
						return isObject(val) && isFunction(val.then) && isFunction(val.catch);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 添加单位
 | 
				
			||||||
 | 
					export function addUnit(value) {
 | 
				
			||||||
 | 
						if (!isDef(value)) {
 | 
				
			||||||
 | 
							return undefined;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						value = String(value);
 | 
				
			||||||
 | 
						return isNumeric(value) ? `${value}px` : value;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 调用拦截器
 | 
				
			||||||
 | 
					export function callInterceptor(options) {
 | 
				
			||||||
 | 
						const {
 | 
				
			||||||
 | 
							interceptor,
 | 
				
			||||||
 | 
							args,
 | 
				
			||||||
 | 
							done
 | 
				
			||||||
 | 
						} = options;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (interceptor) {
 | 
				
			||||||
 | 
							const returnVal = interceptor(...args);
 | 
				
			||||||
 | 
							if (isPromise(returnVal)) {
 | 
				
			||||||
 | 
								returnVal.then((value) => {
 | 
				
			||||||
 | 
									if (value) done();
 | 
				
			||||||
 | 
								}).catch(noop);
 | 
				
			||||||
 | 
							} else if (returnVal) {
 | 
				
			||||||
 | 
								done();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							done();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const rgbaRegex = /^rgba\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3}),\s*(\d*(?:\.\d+)?)\)$/;
 | 
				
			||||||
 | 
					export const getColor = function(colorStr) {
 | 
				
			||||||
 | 
						const matches = colorStr.match(rgbaRegex);
 | 
				
			||||||
 | 
						if (matches && matches.length === 5) {
 | 
				
			||||||
 | 
							return [
 | 
				
			||||||
 | 
								matches[1],
 | 
				
			||||||
 | 
								matches[2],
 | 
				
			||||||
 | 
								matches[3],
 | 
				
			||||||
 | 
								matches[4]
 | 
				
			||||||
 | 
							];
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return [];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function toClass(classObj, ...classArray) {
 | 
				
			||||||
 | 
						const arr = Object.keys(classObj || {}).filter(key => classObj[key])
 | 
				
			||||||
 | 
						arr.push(...classArray)
 | 
				
			||||||
 | 
						return arr.join(" ")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 判断是水平滑动还是垂直滑动
 | 
				
			||||||
 | 
					export function getDirection(x, y) {
 | 
				
			||||||
 | 
						if (x > y) return 'horizontal';
 | 
				
			||||||
 | 
						if (y > x) return 'vertical';
 | 
				
			||||||
 | 
						return '';
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 缓动函数
 | 
				
			||||||
 | 
					function easingFunction(time, duration, type = "linear") {
 | 
				
			||||||
 | 
						let pos = time / duration;
 | 
				
			||||||
 | 
						let value = 0;
 | 
				
			||||||
 | 
						switch (type) {
 | 
				
			||||||
 | 
							case "easeOutCubic":
 | 
				
			||||||
 | 
								value = (Math.pow((pos - 1), 3) + 1)
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case "easeInOutCubic":
 | 
				
			||||||
 | 
								if ((pos /= 0.5) < 1) value = 0.5 * Math.pow(pos, 3);
 | 
				
			||||||
 | 
								else value = 0.5 * (Math.pow((pos - 2), 3) + 2);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							default: //linear
 | 
				
			||||||
 | 
								value = pos;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return value;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 进度函数
 | 
				
			||||||
 | 
					 * @param {Object} time 当前已经运动的时间
 | 
				
			||||||
 | 
					 * @param {Object} begin 距离的初始值
 | 
				
			||||||
 | 
					 * @param {Object} end 距离的结束值
 | 
				
			||||||
 | 
					 * @param {Object} duration 运动时长
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					export function progress(time, begin, end, duration, type) {
 | 
				
			||||||
 | 
						return begin + (end - begin) * easingFunction(time, duration, type);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let uid = 0;
 | 
				
			||||||
 | 
					export function getUid() {
 | 
				
			||||||
 | 
						return uid++
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const hasOwnProperty = Object.prototype.hasOwnProperty
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 检查对象是否具有该属性
 | 
				
			||||||
 | 
					 * @param {*} obj 对象
 | 
				
			||||||
 | 
					 * @param {*} key 对象属性名
 | 
				
			||||||
 | 
					 * @returns 
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					export function hasOwn(obj, key) {
 | 
				
			||||||
 | 
						return hasOwnProperty.call(obj, key)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const now = Date.now || function() {
 | 
				
			||||||
 | 
						return +new Date();
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
@@ -0,0 +1,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					export const utilMixin = function() {
 | 
				
			||||||
 | 
						return {
 | 
				
			||||||
 | 
							methods: {
 | 
				
			||||||
 | 
								 
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										238
									
								
								smart-app/src/uni_modules/y-tabs/components/y-tab/y-tab.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										238
									
								
								smart-app/src/uni_modules/y-tabs/components/y-tab/y-tab.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,238 @@
 | 
				
			|||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <view
 | 
				
			||||||
 | 
					    class="y-tab__pane"
 | 
				
			||||||
 | 
					    :data-index="index"
 | 
				
			||||||
 | 
					    :class="[uniquePaneClass, paneClass]"
 | 
				
			||||||
 | 
					    :style="[paneStyle]"
 | 
				
			||||||
 | 
					    @touchstart="touchStart"
 | 
				
			||||||
 | 
					    @touchmove="touchMove"
 | 
				
			||||||
 | 
					    @touchend="touchEnd"
 | 
				
			||||||
 | 
					  >
 | 
				
			||||||
 | 
					    <!-- 渲染过的则不再渲染,未渲染的根据激活状态进行渲染 -->
 | 
				
			||||||
 | 
					    <view class="y-tab__pane--wrap" v-if="rendered ? true : active">
 | 
				
			||||||
 | 
					      <slot></slot>
 | 
				
			||||||
 | 
					    </view>
 | 
				
			||||||
 | 
					  </view>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script>
 | 
				
			||||||
 | 
					  import { isNull, toClass, getUid } from '../js/uitls';
 | 
				
			||||||
 | 
					  import { touchMixin } from '../js/touchMixin';
 | 
				
			||||||
 | 
					  import { options } from '../js/const';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  export default {
 | 
				
			||||||
 | 
					    name: 'yTab',
 | 
				
			||||||
 | 
					    mixins: [touchMixin],
 | 
				
			||||||
 | 
					    options,
 | 
				
			||||||
 | 
					    props: {
 | 
				
			||||||
 | 
					      title: String, // 标题
 | 
				
			||||||
 | 
					      disabled: Boolean, // 是否禁用标签
 | 
				
			||||||
 | 
					      dot: Boolean, // 是否在标题右上角显示小红点
 | 
				
			||||||
 | 
					      badge: {
 | 
				
			||||||
 | 
					        type: [Number, String],
 | 
				
			||||||
 | 
					        default: '',
 | 
				
			||||||
 | 
					      }, // 图标右上角徽标的内容
 | 
				
			||||||
 | 
					      // 徽标数最大数字限制,超过这个数字将变成badgeMaxCount+,如果传空字符串则不设置
 | 
				
			||||||
 | 
					      badgeMaxCount: {
 | 
				
			||||||
 | 
					        type: [Number, String],
 | 
				
			||||||
 | 
					        default: 99,
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      name: [Number, String], // 标签名称,作为匹配的标识符
 | 
				
			||||||
 | 
					      titleStyle: Object, //	自定义标题样式
 | 
				
			||||||
 | 
					      titleClass: String, //	自定义标题类名
 | 
				
			||||||
 | 
					      iconType: String, //图标图案,为uniapp扩展组件(uni-ui)下的uni-icons的type值,customPrefix用法等同
 | 
				
			||||||
 | 
					      iconSize: {
 | 
				
			||||||
 | 
					        type: [Number, String],
 | 
				
			||||||
 | 
					        default: 16,
 | 
				
			||||||
 | 
					      }, //图标大小
 | 
				
			||||||
 | 
					      customPrefix: String, //自定义图标
 | 
				
			||||||
 | 
					      imageSrc: String, //图片路径
 | 
				
			||||||
 | 
					      imageMode: {
 | 
				
			||||||
 | 
					        type: String,
 | 
				
			||||||
 | 
					        default: 'scaleToFill',
 | 
				
			||||||
 | 
					        validator(value) {
 | 
				
			||||||
 | 
					          return [
 | 
				
			||||||
 | 
					            'scaleToFill',
 | 
				
			||||||
 | 
					            'aspectFit',
 | 
				
			||||||
 | 
					            'aspectFill',
 | 
				
			||||||
 | 
					            'widthFix',
 | 
				
			||||||
 | 
					            'heightFix',
 | 
				
			||||||
 | 
					            'top',
 | 
				
			||||||
 | 
					            'bottom',
 | 
				
			||||||
 | 
					            'center',
 | 
				
			||||||
 | 
					            'left',
 | 
				
			||||||
 | 
					            'right',
 | 
				
			||||||
 | 
					            'top left',
 | 
				
			||||||
 | 
					            'top right',
 | 
				
			||||||
 | 
					            'bottom left',
 | 
				
			||||||
 | 
					            'bottom right',
 | 
				
			||||||
 | 
					          ].includes(value);
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					      }, //图片裁剪、缩放的模式,为uniapp内置组件->媒体组件—>image下的mode值
 | 
				
			||||||
 | 
					      position: {
 | 
				
			||||||
 | 
					        type: String,
 | 
				
			||||||
 | 
					        default: 'right',
 | 
				
			||||||
 | 
					        validator(value) {
 | 
				
			||||||
 | 
					          return ['top', 'bottom', 'left', 'right'].includes(value);
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					      }, //如果存在图片或图标,标题围绕它们的位置
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    data() {
 | 
				
			||||||
 | 
					      return {
 | 
				
			||||||
 | 
					        isUnmounted: false,
 | 
				
			||||||
 | 
					        index: -1, //内容卡片对应的下标
 | 
				
			||||||
 | 
					        parent: null, //父元素实例
 | 
				
			||||||
 | 
					        active: false, //是否为激活状态
 | 
				
			||||||
 | 
					        rendered: false, //是否渲染过
 | 
				
			||||||
 | 
					        swipeable: false, //是否开启手势滑动切换
 | 
				
			||||||
 | 
					        paneStyle: null, //内容样式
 | 
				
			||||||
 | 
					        scrollspy: false, //是否为滚动导航模式
 | 
				
			||||||
 | 
					        paneObserver: null, //pane交叉观察器
 | 
				
			||||||
 | 
					        isDisjoint: false, //当前pane是否与参照节点布局区域相离
 | 
				
			||||||
 | 
					        isActiveLast: false, // 最后一个pane在滚动导航模式下是否激活对应的标签项
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    computed: {
 | 
				
			||||||
 | 
					      computedName() {
 | 
				
			||||||
 | 
					        return !isNull(this.name) ? this.name : this.index;
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      unqieKey() {
 | 
				
			||||||
 | 
					        return getUid();
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      // 保证唯一的样式
 | 
				
			||||||
 | 
					      uniquePaneClass() {
 | 
				
			||||||
 | 
					        return 'y-tab__pane' + this.unqieKey;
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      // 内容class
 | 
				
			||||||
 | 
					      paneClass() {
 | 
				
			||||||
 | 
					        return toClass({ 'is-active': this.active, 'is-scrollspy': this.scrollspy });
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    watch: {
 | 
				
			||||||
 | 
					      $props: {
 | 
				
			||||||
 | 
					        deep: true,
 | 
				
			||||||
 | 
					        // immediate: true,
 | 
				
			||||||
 | 
					        handler(newValue, oldValue) {
 | 
				
			||||||
 | 
					          // 更新tab
 | 
				
			||||||
 | 
					          if (this.parent) {
 | 
				
			||||||
 | 
					            this.parent.updateTab({
 | 
				
			||||||
 | 
					              newValue: { ...newValue, badge: this.formatBadge() },
 | 
				
			||||||
 | 
					              oldValue: oldValue && { ...oldValue },
 | 
				
			||||||
 | 
					              index: this.index,
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    created() {
 | 
				
			||||||
 | 
					      this.parent = this.getParent();
 | 
				
			||||||
 | 
					      if (this.parent) {
 | 
				
			||||||
 | 
					        this.parent.children.push(this);
 | 
				
			||||||
 | 
					        this.parent.putTab({ newValue: { ...this.$props, key: this.unqieKey, badge: this.formatBadge() } });
 | 
				
			||||||
 | 
					        this.scrollspy = this.parent.scrollspy;
 | 
				
			||||||
 | 
					        this.rendered = !this.parent.isLazyRender || this.parent.scrollspy; //标记是否渲染过,非懒加载与滚动导航模式下默认渲染
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    // #ifndef VUE3
 | 
				
			||||||
 | 
					    destroyed() {
 | 
				
			||||||
 | 
					      if (this.isUnmounted) return;
 | 
				
			||||||
 | 
					      this.unInit();
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    // #endif
 | 
				
			||||||
 | 
					    // #ifdef VUE3
 | 
				
			||||||
 | 
					    unmounted() {
 | 
				
			||||||
 | 
					      this.isUnmounted = true;
 | 
				
			||||||
 | 
					      this.unInit();
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    // #endif
 | 
				
			||||||
 | 
					    methods: {
 | 
				
			||||||
 | 
					      // 徽标格式化
 | 
				
			||||||
 | 
					      formatBadge() {
 | 
				
			||||||
 | 
					        if (!isNull(this.badge) && !isNull(this.badgeMaxCount) && this.badge > this.badgeMaxCount) {
 | 
				
			||||||
 | 
					          return this.badgeMaxCount + '+';
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					          return this.badge;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      // 获取查询节点信息的对象
 | 
				
			||||||
 | 
					      getSelectorQuery() {
 | 
				
			||||||
 | 
					        let query = null;
 | 
				
			||||||
 | 
					        // #ifdef MP-ALIPAY
 | 
				
			||||||
 | 
					        query = uni.createSelectorQuery();
 | 
				
			||||||
 | 
					        // #endif
 | 
				
			||||||
 | 
					        // #ifndef MP-ALIPAY
 | 
				
			||||||
 | 
					        query = uni.createSelectorQuery().in(this);
 | 
				
			||||||
 | 
					        // #endif
 | 
				
			||||||
 | 
					        return query;
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      // 获取元素位置信息
 | 
				
			||||||
 | 
					      getRect(selector) {
 | 
				
			||||||
 | 
					        return new Promise((resolve, reject) => {
 | 
				
			||||||
 | 
					          selector = `.${this.uniquePaneClass}` + (!isNull(selector) ? ' ' + selector : '');
 | 
				
			||||||
 | 
					          this.getSelectorQuery()
 | 
				
			||||||
 | 
					            .select(selector)
 | 
				
			||||||
 | 
					            .boundingClientRect()
 | 
				
			||||||
 | 
					            .exec((rect) => {
 | 
				
			||||||
 | 
					              resolve(rect[0] || {});
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      // 卸载组件的处理
 | 
				
			||||||
 | 
					      unInit() {
 | 
				
			||||||
 | 
					        this.disconnectObserver(); //销毁观察器
 | 
				
			||||||
 | 
					        if (this.parent) {
 | 
				
			||||||
 | 
					          const index = this.parent.children.findIndex((item) => item === this);
 | 
				
			||||||
 | 
					          this.parent.children.splice(index, 1);
 | 
				
			||||||
 | 
					          this.parent.tabs.splice(index, 1);
 | 
				
			||||||
 | 
					          this.parent.tabRects.splice(index, 1);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      //获取父元素实例
 | 
				
			||||||
 | 
					      getParent(name = 'yTabs') {
 | 
				
			||||||
 | 
					        let parent = this.$parent;
 | 
				
			||||||
 | 
					        let parentName = parent.$options.name;
 | 
				
			||||||
 | 
					        while (parentName !== name) {
 | 
				
			||||||
 | 
					          parent = parent.$parent;
 | 
				
			||||||
 | 
					          if (!parent) return false;
 | 
				
			||||||
 | 
					          parentName = parent.$options.name;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return parent;
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      // 断掉观察,释放资源
 | 
				
			||||||
 | 
					      disconnectObserver() {
 | 
				
			||||||
 | 
					        this.paneObserver && this.paneObserver?.disconnect();
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      // 观察 - 标签内容滚动时定位标签项
 | 
				
			||||||
 | 
					      async observePane(top) {
 | 
				
			||||||
 | 
					        this.disconnectObserver();
 | 
				
			||||||
 | 
					        const paneObserver = uni.createIntersectionObserver(this, { thresholds: [0, 0.01, 0.99, 1] });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // 注意:如果y-tabs使用的区域滚动,整个页面的布局跟随页面滚动,当pane跟随页面移动了之后,
 | 
				
			||||||
 | 
					        //      那么y-tabs__content的top就会变化,导致交互区域位置不准确,可以在onPageScroll使用定时器实现滚动结束的处理重新resize一下组件创建pane的监听
 | 
				
			||||||
 | 
					        // 如果pane内容超过页面的可视区域,最好舍弃这种交互布局,uniapp未实现Android的嵌套滑动机制,页面滑动到底后无法将事件分发给scroll-view,使scroll-view继承滑动
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        paneObserver.relativeToViewport({ top: -top }); // 到屏幕顶部的高度时触发
 | 
				
			||||||
 | 
					        // 不能观察根节点 unk-vendors.js:14596 [system] Node .y-tab__pane9 is not found. Intersection observer will not trigger.
 | 
				
			||||||
 | 
					        paneObserver.observe(`.${this.uniquePaneClass} .y-tab__pane--wrap`, (res) => {
 | 
				
			||||||
 | 
					          // console.log('res:', this.title, res);
 | 
				
			||||||
 | 
					          if (!this.isActiveLast) {
 | 
				
			||||||
 | 
					            // 如果目标节点布局区域的top小于参照节点的top,则说明目标节点在参照节点布局区域之上,intersectionRatio不大于0则说明两者不相交
 | 
				
			||||||
 | 
					            this.isDisjoint = res.intersectionRatio <= 0 && res.boundingClientRect.top < res.relativeRect.top;
 | 
				
			||||||
 | 
					          } else {
 | 
				
			||||||
 | 
					            // 滚动导航模式下,最后一个pane完成显示但未超出可视范围顶部时,是否设置相离而激活最后一个标签项
 | 
				
			||||||
 | 
					            this.isDisjoint = res.intersectionRatio > 0 && res.boundingClientRect.bottom <= res.relativeRect.bottom;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          // 保证组件初始化完成时执行,避免创建时触发一次监听器的回调函数,导致执行顺序先于tabs的init方法,使底部条错位:
 | 
				
			||||||
 | 
					          // 标签栏点击时触发的滚动不允许设置激活下标
 | 
				
			||||||
 | 
					          if (this.parent.isLoaded && !this.parent.lockedScrollspy) this.parent.setActivedIndexToScroll();
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        this.paneObserver = paneObserver;
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style lang="scss" scoped>
 | 
				
			||||||
 | 
					  @import '../css/index';
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
							
								
								
									
										1363
									
								
								smart-app/src/uni_modules/y-tabs/components/y-tabs/y-tabs.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1363
									
								
								smart-app/src/uni_modules/y-tabs/components/y-tabs/y-tabs.vue
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Reference in New Issue
	
	Block a user