增加other分包页面

我的页面里增加跳转other分包跳转(仅在ios不是浏览器审核时展示)
This commit is contained in:
2024-12-20 18:01:37 +08:00
parent 908205200b
commit b2fd3ba347
154 changed files with 43228 additions and 84 deletions

View File

@@ -0,0 +1,94 @@
<template>
<view class="demo-title">
<view>
<view v-if="type === 'first'" class="main_title">
<view v-if="leftIcon" class="main_title__icon main_title__icon--left" :class="[`tn-icon-${leftIcon}`]"></view>
<view class="main_title__content">{{ title }}</view>
<view v-if="rightIcon" class="main_title__icon main_title__icon--right" :class="[`tn-icon-${rightIcon}`]"></view>
</view>
<view v-if="type === 'second'" class="second_title">
<view class="second_title__content">{{ title }}</view>
</view>
</view>
<view class="content" :class="[{
'content--padding': contentPadding
}]">
<slot></slot>
</view>
</view>
</template>
<script>
export default {
name: 'demo-title',
options: {
// 在微信小程序中将组件节点渲染为虚拟节点更加接近Vue组件的表现(不会出现shadow节点下再去创建元素)
virtualHost: true
},
props: {
// 标题类型
type: {
type: String,
default: 'first'
},
// 标题
title: {
type: String,
default: ''
},
// 左图标
leftIcon: {
type: String,
default: 'star'
},
// 右图标
rightIcon: {
type: String,
default: 'star'
},
// 内容容器是否有两边边距
contentPadding: {
type: Boolean,
default: true
}
}
}
</script>
<style lang="scss" scoped>
.main_title {
display: flex;
align-items: center;
justify-content: center;
margin-top: 50rpx;
font-size: 36rpx;
font-weight: bold;
&__content {
padding: 0 18rpx;
}
&__icon {
font-size: 34rpx;
}
}
.second_title {
margin: 24rpx 0;
margin-left: 30rpx;
&__content {
font-size: 32rpx;
font-weight: bold;
}
}
.content {
margin-top: 30rpx;
&--padding {
margin-left: 30rpx;
margin-right: 30rpx;
}
}
</style>

View File

@@ -0,0 +1,689 @@
<template>
<view class="dynamic-demo">
<!-- 效果预览窗口 -->
<view v-if="!noDemo" class="demo-container" :class="{'demo-container--full': full}">
<view class="demo">
<slot></slot>
</view>
<!-- 提示信息 -->
<view v-if="haveTips">
<view class="demo__tips__icon" @click="demoTipsClick">
<view class="icon tn-icon-help"></view>
</view>
<view class="demo__tips__content"
:class="[showContentTips ? 'demo__tips__content--show' : 'demo__tips__content--hide']">
<view v-for="(item,index) in tipsData" :key="index" class="demo__tips__content--item">{{ item }}</view>
</view>
</view>
</view>
<!-- 模式切换 -->
<view v-if="multiMode" class="mode-switch">
<view class="mode-switch__container">
<view v-for="(item, index) in sectionModeListInfos" :key="index" class="mode-switch__item"
:class="[`mode-switch-item-${index}`,{'mode-switch__item--active': modeIndex === index}]"
@click="switchMode(index)">{{ item.name }}</view>
<!-- 滑块样式 -->
<view class="mode-switch__slider" :style="[modeSwitchSliderStyle]"></view>
</view>
</view>
<!-- 组件对应可选项容器 -->
<view class="section-container">
<scroll-view
class="section__scroll-view"
:class="{'section__scroll-view--auto': sectionScrollViewStyle.height === 'auto'}"
:style="[sectionScrollViewStyle]"
:scroll-y="sectionScrollViewStyle.height !== 'auto'"
>
<block v-for="(item,index) in btnsList" :key="index">
<view class="section__content" :class="{'section__content--visible': item.show}">
<view class="section__content__title">
<view class="section__content__title__left-line" :class="[`tn-main-gradient-${tuniaoColorList[index]}`]"></view>
<view class="section__content__title--text tn-text-ellipsis" :class="[`tn-main-gradient-${tuniaoColorList[index]}`]">{{ item.title }}</view>
<view class="section__content__title__right-line" :class="[`tn-main-gradient-${tuniaoColorList[index]}`]"></view>
</view>
<view class="section__content__btns">
<view v-for="(section_btn,section_index) in item.optional" :key="section_index"
class="section__content__btns__item" :class="[`tn-main-gradient-${tuniaoColorList[index]}--light`]" @click="sectionBtnClick(index, section_index)">
<view class="section__content__btns__item__bg"
:class="[`tn-main-gradient-${tuniaoColorList[index]}`, {'section__content__btns__item__bg--active':sectionIndex[modeIndex][index]['value'] === section_index}]"></view>
<view class="section__content__btns__item--text tn-text-ellipsis"
:class="[sectionIndex[modeIndex][index]['value'] === section_index ? 'section__content__btns__item--text--active' : `tn-color-${tuniaoColorList[index]}`]">{{ section_btn }}</view>
</view>
</view>
</view>
</block>
</scroll-view>
</view>
</view>
</template>
<script>
export default {
name: 'dynamic-demo-template',
props: {
// 可选项列表数据
sectionList: {
type: Array,
default() {
return []
}
},
// 提示信息
tips: {
type: [String, Array],
default: ''
},
// 演示框的内容是否为铺满
full: {
type: Boolean,
default: false
},
// 是否使用了自定义顶部导航栏
customBar: {
type: Boolean,
default: true
},
// 是否全屏滚动
fullWindowsScroll: {
type: Boolean,
default: false
},
// 没有演示内容
noDemo: {
type: Boolean,
default: false
}
},
computed: {
tipsData() {
if (typeof this.tips === 'string') {
return [this.tips]
}
return this.tips
},
haveTips() {
return this.tips && this.tips.length > 0
},
multiMode() {
return this.sectionList.length > 1
},
sectionModeList() {
return this.sectionList.map((item) => {
return item.name
})
}
},
data() {
return {
// 图鸟颜色列表
tuniaoColorList: this.$t.color.getTuniaoColorList(),
// 保存选项列表信息由于prop中的数据时不能被修改的
_sectionList: [],
// 模式列表信息
sectionModeListInfos: [],
// 所选模式的序号
modeIndex: 0,
// 模式选择滑块样式
modeSwitchSliderStyle: {
width: 0,
left: 0
},
// 显示组件相关提示信息
showContentTips: false,
// 可选项滚动容器样式
sectionScrollViewStyle: {
height: 0
},
// 按钮列表信息
btnsList: [],
// 标记当前所选按钮
sectionIndex: [],
// 标记选项按钮是否可以滑动使用scroll-view进行包裹
sectionScrollFlag: true
}
},
watch: {
sectionList: {
handler(value) {
// 如果sectionList发生改变重新初始化选项列表信息
this.initSectionBtns()
},
deep: true
},
sectionScrollFlag(value) {
if (!value) {
this.sectionScrollViewStyle.height = 'auto'
}
},
fullWindowsScroll: {
handler(value) {
if (value) {
this.sectionScrollViewStyle.height = 'auto'
}
},
immediate: true
}
},
created() {
// 初始化可选项模式列表
this.sectionModeListInfos = this.sectionModeList.map((item) => {
return {
name: item
}
})
// 初始化选项按钮默认信息
this.initSectionBtns()
},
mounted() {
// 等待加载组件完成
// setTimeout(() => {
// // 计算出底部scroll-view的高度
// this.initSectionScrollView()
// if (this.multiMode) {
// // 获取模式切换标签的信息
// this.getModeTabsInfo()
// }
// }, 10)
this.$nextTick(() => {
// 计算出底部scroll-view的高度
this.initSectionScrollView()
if (this.multiMode) {
// 获取模式切换标签的信息
this.getModeTabsInfo()
}
})
},
methods: {
// 初始化选项滑动窗口的高度
initSectionScrollView() {
// 全屏滚动时不进行任何的操作
if (this.fullWindowsScroll) {
return
}
// 获取屏幕的高度
uni.getSystemInfo({
success: (systemInfo) => {
// 通过当前屏幕的安全高度减去上一个元素的底部和距离上一个元素的外边距,然后减获取到的值减去标题栏的高度即可
const navBarHeight = this.customBar ? 0 : this.vuex_custom_bar_height
if (this.multiMode) {
uni.createSelectorQuery().in(this).select('.mode-switch').boundingClientRect(data => {
if (data.bottom >= systemInfo.safeArea.height) {
this.sectionScrollFlag = false
} else {
this.sectionScrollFlag = true
const containerBaseHeight = systemInfo.safeArea.height - data.bottom
this.sectionScrollViewStyle.height = (containerBaseHeight - navBarHeight) + systemInfo.statusBarHeight - uni.upx2px(75) + 'px'
}
}).exec()
} else {
if (!this.noDemo) {
uni.createSelectorQuery().in(this).select('.demo-container').boundingClientRect(data => {
if (data.bottom >= systemInfo.safeArea.height) {
this.sectionScrollFlag = false
} else {
this.sectionScrollFlag = true
const containerBaseHeight = systemInfo.safeArea.height - data.bottom
this.sectionScrollViewStyle.height = (containerBaseHeight - navBarHeight) + systemInfo.statusBarHeight - uni.upx2px(75) + 'px'
}
}).exec()
} else {
this.sectionScrollFlag = false
}
}
}
})
},
// 更新选项滑动容器的高度
updateSectionScrollView() {
this.$nextTick(() => {
this.initSectionScrollView()
})
},
// 获取各个模式tab的节点信息
getModeTabsInfo() {
let view = uni.createSelectorQuery().in(this)
for (let i = 0; i < this.sectionModeListInfos.length; i++) {
view.select('.mode-switch-item-' + i).boundingClientRect()
}
view.exec(res => {
// 如果没有获取到,则重新获取
if (!res.length) {
setTimeout(() => {
this.getModeTabsInfo()
}, 10)
return
}
// 将每个模式的宽度放入list中
res.map((item, index) => {
this.sectionModeListInfos[index].width = item.width
})
// 初始化滑块的宽度
this.modeSwitchSliderStyle.width = this.sectionModeListInfos[0].width + 'px'
// 初始化滑块的位置
this.modeSliderPosition()
})
},
// 设置模式滑块的位置
modeSliderPosition() {
let left = 0
// 计算当前所选模式选项到组件左边的距离
this.sectionModeListInfos.map((item, index) => {
if (index < this.modeIndex) left += item.width
})
this.modeSwitchSliderStyle.left = left + 'px'
},
// 切换模式
switchMode(index) {
// 不允许点击当前激活的选项
if (index === this.modeIndex) return
this.modeIndex = index
this.modeSliderPosition()
this.updateSectionBtns()
this.$emit('modeClick', {
index: index
})
},
// 点击内容提示信息
demoTipsClick() {
this.showContentTips = !this.showContentTips
},
// 初始化被选中选项按钮
initSectionBtns() {
this.sectionIndex = []
this.sectionIndex = this.sectionList.map((item) => {
if (item.hasOwnProperty('section') && item.section.length > 0) {
return Array(item.section.length).fill({
value: 0,
change: false
})
} else {
return []
}
})
this._sectionList = this.$t.deepClone(this.sectionList)
// 给本地选项按钮列表给默认show属性
this._sectionList.map((item) => {
const section = item.section.map((section_item) => {
if (!section_item.hasOwnProperty('show')) {
section_item.show = true
}
return section_item
})
item.section = section
return item
})
// 更新按钮信息
this.updateSectionBtns()
},
// 跟新选项按钮信息
updateSectionBtns(sectionIndex = -1, showState = true) {
let sectionOptional = this._sectionList[this.modeIndex]['section']
this.btnsList = sectionOptional.map((item, index) => {
// 判断是否已经修改了对应的值
let changeValue = this.sectionIndex[this.modeIndex][index]['change'] || false
let currentSectionIndexValue = this.sectionIndex[this.modeIndex][index]['value'] || 0
// 取出默认值(如果是已经修改过的选项,则使用之前的选项信息)
let indexValue = changeValue ? currentSectionIndexValue : item.hasOwnProperty('current') ? item.current : 0
// 取出是否显示当前选项
let show = (sectionIndex !== -1 && sectionIndex === index) ? showState : item.hasOwnProperty('show') ? item.show : true
// 处理最大最小值
if (indexValue < 0) {
indexValue = 0
}
if (indexValue >= item.optional.length) {
indexValue = item.optional.length
}
// this.sectionIndex[this.modeIndex][index]['value'] = indexValue
this.$set(this.sectionIndex[this.modeIndex], index, {value: indexValue, change: changeValue})
item.show = show
return item
})
},
// 更新选项按钮状态信息
updateSectionBtnsState(sectionIndex = -1, showState = true) {
// 判断sectionIndex是否为数组
if (this.$t.array.isArray(sectionIndex)) {
if (sectionIndex.length === 0) {
return
}
sectionIndex = sectionIndex.filter((item) => item >= 0 && item < this.sectionList[this.modeIndex]['section'].length)
sectionIndex.map((item) => {
this.btnsList[item]['show'] = showState
this._sectionList[this.modeIndex]['section'][item]['show'] = showState
})
} else {
if (sectionIndex < 0 || sectionIndex >= this.sectionList[this.modeIndex]['section'].length) {
return
}
// 将按键的对应显示状态设置为对应的状态
this.btnsList[sectionIndex]['show'] = showState
this._sectionList[this.modeIndex]['section'][sectionIndex]['show'] = showState
}
},
// 更新选项按钮选中信息
updateSectionBtnsValue(modeIndex = 0, sectionIndex = -1, value = 0) {
if (sectionIndex < 0 || sectionIndex >= this.sectionList[modeIndex]['section'].length) {
return
}
// 如果showState为false则移除对应的选项按钮否则往对应的位置添加上对应的选项按钮
this.sectionIndex[modeIndex][sectionIndex] = {
value,
change: true
}
},
// 选项按钮点击事件
sectionBtnClick(index, sectionIndex) {
// if (this.sectionIndex[this.modeIndex][index] === sectionIndex) {
// return
// }
this.$set(this.sectionIndex[this.modeIndex], index, {value: sectionIndex, change: true})
this.$emit('click', {
methods: this.btnsList[index]['methods'],
index: sectionIndex,
name: this.btnsList[index]['optional'][sectionIndex]
})
}
}
}
</script>
<style lang="scss" scoped>
.dynamic-demo {
padding-top: 78rpx;
/* 顶部模式切换start */
.mode-switch {
width: 100%;
display: flex;
align-items: center;
justify-content: center;
margin-top: 75rpx;
padding: 0 30rpx;
&__container {
position: relative;
display: flex;
flex-direction: row;
align-items: center;
width: 476rpx;
height: 62rpx;
background-color: #FFFFFF;
box-shadow: 0rpx 10rpx 50rpx 0rpx rgba(0, 3, 72, 0.1);
border-radius: 31rpx;
}
&__item {
flex: 1;
height: 62rpx;
width: 100%;
line-height: 62rpx;
text-align: center;
font-size: 28rpx;
color: $tn-font-sub-color;
z-index: 2;
transition: all 0.3s;
&--active {
color: #FFFFFF;
font-weight: bold;
}
}
&__slider {
position: absolute;
height: 62rpx;
border-radius: 31rpx;
// background-image: linear-gradient(-86deg, #FF8359 0%, #FFDF40 100%);
background-image: linear-gradient(-86deg, #00C3FF 0%, #58FFF5 100%);
box-shadow: 1rpx 10rpx 24rpx 0rpx #00C3FF77;
z-index: 1;
transition: all 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55);
}
}
/* 顶部模式切换end */
/* 演示内容展示start */
.demo-container {
min-height: 327rpx;
width: calc(100% - 60rpx);
background-color: #FFFFFF;
box-shadow: 0rpx 10rpx 50rpx 0rpx rgba(0, 3, 72, 0.1);
margin: 0 30rpx 5rpx 30rpx;
border-radius: 20rpx;
position: relative;
display: flex;
justify-content: center;
align-items: center;
&--full {
display: inline-block;
padding-bottom: 20rpx;
min-height: 0rpx;
padding: 10rpx 20rpx 30rpx;
}
.demo {
padding-top: 70rpx;
&__tips {
&__icon {
position: absolute;
top: 20rpx;
right: 16rpx;
width: 39rpx;
height: 39rpx;
line-height: 39rpx;
font-size: 39rpx;
.icon {
background: linear-gradient(-45deg, #FF8359 0%, #FFDF40 100%);
-webkit-background-clip: text;
color: transparent;
text-shadow: 0rpx 10rpx 10rpx rgba(255, 156, 82, 0.2);
}
}
&__content {
position: absolute;
top: 65rpx;
right: 16rpx;
font-size: 20rpx;
margin-left: 20rpx;
word-wrap: normal;
display: flex;
flex-direction: column;
background-color: #E6E6E6;
padding: 20rpx;
border-radius: 10rpx;
transition: transform 0.3s cubic-bezier(0.68, -0.55, 0.265, 1);
transform-origin: 0 0;
z-index: 999999;
&--hide {
transform: scaleY(0);
}
&--show {
transform: scaleY(100%);
&::after {
content: "";
width: 0px;
height: 0px;
border-width: 4px;
border-style: solid;
border-color: transparent transparent rgba(149, 149, 149, 0.1) transparent;
position: absolute;
top: -8px;
right: 6px;
}
}
}
}
}
}
/* 演示内容展示end */
/* 可选项start */
.section-container {
width: 100%;
height: auto;
margin-top: 70rpx;
.section {
&__content {
margin-top: 70rpx;
display: none;
&--visible {
display: block;
&:last-child {
padding-bottom: calc(70rpx + env(safe-area-inset-bottom));
}
}
&:nth-child(1) {
margin-top: 0rpx;
}
&__title {
display: flex;
justify-content: center;
align-items: center;
margin: 0 30rpx;
text-align: center;
&__left-line,
&__right-line {
width: 100rpx;
height: 2rpx;
position: relative;
}
&__left-line {
&::after {
content: '';
background: inherit;
width: 12rpx;
height: 12rpx;
position: absolute;
top: -12rpx;
right: 0rpx;
border-radius: 50%;
transform: translateY(50%);
}
}
&__right-line {
&::after {
content: '';
background: inherit;
width: 12rpx;
height: 12rpx;
position: absolute;
top: -12rpx;
left: 0rpx;
border-radius: 50%;
transform: translateY(50%);
}
}
&--text {
-webkit-background-clip: text;
color: transparent;
min-width: 124rpx;
height: 30rpx;
font-size: 32rpx;
line-height: 1;
margin: 0 35rpx;
}
}
&__btns {
width: calc(100% - 60rpx);
margin: 0 30rpx;
margin-top: 29rpx;
padding: 50rpx 30rpx 0rpx 0rpx;
background-color: #FFFFFF;
box-shadow: 0rpx 10rpx 50rpx 0rpx rgba(0, 3, 72, 0.1);
border-radius: 20rpx;
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
flex-wrap: wrap;
&__item {
max-width: 30%;
padding: 17rpx 36rpx;
border-radius: 10rpx;
margin-bottom: 40rpx;
margin-left: 40rpx;
position: relative;
z-index: 1;
// &::before {
// content: " ";
// position: absolute;
// top: 10rpx;
// left: 1rpx;
// width: 100%;
// height: 100%;
// background: inherit;
// filter: blur(24rpx);
// opacity: 1;
// z-index: -1;
// }
&__bg {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border-radius: inherit;
z-index: -1;
opacity: 0;
transform: scale(0);
transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
&--active {
opacity: 1;
transform: scale(1);
}
}
&--text {
font-size: 24rpx;
line-height: 1.2em;
transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
&--active {
color: #FFFFFF;
}
}
}
}
}
}
}
/* 可选项end */
}
</style>

View File

@@ -0,0 +1,147 @@
<template>
<view class="multiple-options">
<view class="list">
<block v-for="(item, index) in listData" :key="index">
<view
class="list__item"
:class="[`tn-main-gradient-${tuniaoColorList[item.bgColorIndex]}--light`]"
@tap="navOptionsPage(item.url)"
>
<view class="list__content">
<view class="list__content__title">{{ item.title }}</view>
<view class="list__content__desc">{{ item.desc }}</view>
</view>
<view class="list__icon">
<view class="list__icon__main" :class="[`tn-icon-${item.mainIcon}`, `tn-main-gradient-${tuniaoColorList[item.bgColorIndex]}`]"></view>
<view class="list__icon__sub" :class="[`tn-icon-${item.subIcon}`, `tn-main-gradient-${tuniaoColorList[item.bgColorIndex]}`]"></view>
</view>
</view>
</block>
</view>
</view>
</template>
<script>
export default {
name: 'multiple-options-demo',
props: {
// 显示的列表数据
list: {
type: Array,
default() {
return []
}
}
},
data() {
return {
// 图鸟颜色列表
tuniaoColorList: [
'red',
'purplered',
'purple',
'bluepurple',
'aquablue',
'blue',
'indigo',
'cyan',
'teal',
'green',
'orange',
'orangered'
],
listData: []
}
},
watch: {
list(val) {
this.initList()
}
},
created() {
this.initList()
},
methods: {
// 初始化列表数据
initList() {
// 给列表添加背景颜色数据
this.listData = this.list.map((item, index) => {
item.bgColorIndex = this.getBgNum()
item.mainIcon = item?.mainIcon || 'computer-fill'
item.subIcon = item?.subIcon || 'share'
return item
})
},
// 跳转到对应的选项页面
navOptionsPage(url) {
uni.navigateTo({
url: url
})
},
// 获取酷炫背景随机数
getBgNum() {
return Math.floor((Math.random() * this.tuniaoColorList.length))
}
}
}
</script>
<style lang="scss" scoped>
.list {
&__item {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
width: calc(100% - 60rpx);
margin: 108rpx 30rpx 0rpx 30rpx;
box-shadow: 0rpx 10rpx 50rpx 0rpx rgba(0, 3, 72, 0.1);
border-radius: 20rpx;
}
&__content {
flex: 1;
// color: $tn-font-color;
margin: 34rpx 0rpx 27rpx 37rpx;
&__title {
font-size: 36rpx;
font-weight: bold;
margin-bottom: 12rpx;
}
&__desc {
font-size: 28rpx;
}
}
&__icon {
flex: 1;
margin-right: 26rpx;
position: relative;
&__main, &__sub {
-webkit-background-clip: text;
color: transparent;
position: absolute;
transition: transform 0.25s ease;
}
&__main {
font-size: 200rpx;
width: 190rpx;
line-height: 200rpx;
top: 0;
right: 0rpx;
transform: translateY(-60%);
}
&__sub {
font-size: 70rpx;
top: 0;
right: 175rpx;
transform: translateY(-5rpx);
}
}
}
</style>

View File

@@ -0,0 +1,169 @@
<template>
<view class="nav-index-button" :style="{bottom: `${bottom}rpx`, right: `${right}rpx`}" @tap.stop="navIndex">
<view class="nav-index-button__content">
<view class="nav-index-button__content--icon tn-flex tn-flex-row-center tn-flex-col-center tn-shadow-blur tn-cool-bg-color-5">
<view class="tn-icon-home-fill"></view>
</view>
</view>
<view class="nav-index-button__meteor">
<view class="nav-index-button__meteor__wrapper">
<view v-for="(item,index) in 6" :key="index" class="nav-index-button__meteor__item" :style="{transform: `rotateX(${-60 + (30 * index)}deg) rotateZ(${-60 + (30 * index)}deg)`}">
<view class="nav-index-button__meteor__item--pic"></view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
name: 'nav-index-button',
props: {
// 距离底部的距离
bottom: {
type: [Number, String],
default: 300
},
// 距离右边的距离
right: {
type: [Number, String],
default: 75
},
// 首页地址
indexPath: {
type: String,
default: '/pages/index'
}
},
methods: {
// 跳转回首页
navIndex() {
// 通过判断当前页面的页面栈信息,是否有上一页进行返回,如果没有则跳转到首页
const pages = getCurrentPages()
if (pages && pages.length > 0) {
const indexPath = this.indexPath || '/pages/index'
const firstPage = pages[0]
if (pages.length == 1 && (!firstPage.route || firstPage.route != indexPath.substring(1, indexPath.length))) {
uni.reLaunch({
url: indexPath
})
} else {
uni.navigateBack({
delta: 1
})
}
} else {
uni.reLaunch({
url: indexPath
})
}
}
}
}
</script>
<style lang="scss" scoped>
.nav-index-button {
position: fixed;
animation: suspension 3s ease-in-out infinite;
z-index: 999999;
&__content {
position: absolute;
width: 100rpx;
height: 100rpx;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
&--icon {
width: 100rpx;
height: 100rpx;
font-size: 60rpx;
border-radius: 50%;
margin-bottom: 18rpx;
position: relative;
z-index: 1;
transform: scale(0.85);
&::after {
content: " ";
position: absolute;
z-index: -1;
width: 100%;
height: 100%;
left: 0;
bottom: 0;
border-radius: inherit;
opacity: 1;
transform: scale(1, 1);
background-size: 100% 100%;
background-image: url(https://resource.tuniaokj.com/images/cool_bg_image/icon_bg6.png);
}
}
}
&__meteor {
position: absolute;
top: 50%;
left: 50%;
width: 100rpx;
height: 100rpx;
transform-style: preserve-3d;
transform: translate(-50%, -50%) rotateY(75deg) rotateZ(10deg);
&__wrapper {
width: 100rpx;
height: 100rpx;
transform-style: preserve-3d;
animation: spin 20s linear infinite;
}
&__item {
position: absolute;
width: 100rpx;
height: 100rpx;
border-radius: 1000rpx;
left: 0;
top: 0;
&--pic {
display: block;
width: 100%;
height: 100%;
background: url(https://resource.tuniaokj.com/images/cool_bg_image/arc3.png) no-repeat center center;
background-size: 100% 100%;
animation: arc 4s linear infinite;
}
}
}
}
@keyframes suspension {
0%, 100% {
transform: translateY(0);
}
50% {
transform: translateY(-0.8rem);
}
}
@keyframes spin {
0% {
transform: rotateX(0deg);
}
100% {
transform: rotateX(-360deg);
}
}
@keyframes arc {
to {
transform: rotate(360deg);
}
}
</style>

View File

@@ -0,0 +1,52 @@
/**
* 动态参数演示mixin
*/
module.exports = {
data() {
return {
// 效果显示框top的值
contentContainerTop: '0px',
contentContainerIsTop: false,
// 参数显示框top的值
sectionContainerTop: '0px'
}
},
onReady() {
this.updateSectionContainerTop()
},
methods: {
// 处理演示效果框的位置
async _handleContentConatinerPosition() {
// 获取效果演示框的节点信息
const contentContainer = await this._tGetRect('#content_container')
// 获取参数框的节点信息
this._tGetRect('#section_container').then((res) => {
// 判断参数框是否在移动,如果是则更新效果框的位置
// 如果效果框的顶部已经触控到顶部导航栏就停止跟随
if (res.top - contentContainer.bottom != 15) {
const newTop = res.top - (contentContainer.height + uni.upx2px(20))
const minTop = this.vuex_custom_bar_height + 1
if (newTop < minTop) {
this.contentContainerTop = minTop + 'px'
this.contentContainerIsTop = true
} else {
this.contentContainerTop = newTop + 'px'
this.contentContainerIsTop = false
}
}
})
},
// 更新状态切换栏位置信息
updateSectionContainerTop() {
this._tGetRect('#content_container').then((res) => {
this.contentContainerTop = (this.vuex_custom_bar_height + 148) + 'px'
this.sectionContainerTop = (res.height + 20) + 'px'
})
}
},
// 监听页面滚动
onPageScroll() {
this._handleContentConatinerPosition()
}
}

View File

@@ -0,0 +1,60 @@
/**
* 演示页面mixin
*/
module.exports = {
data() {
return {
}
},
onLoad() {
// 更新顶部导航栏信息
this.updateCustomBarInfo()
},
methods: {
// 点击左上角返回按钮时触发事件
goBack() {
// 通过判断当前页面的页面栈信息,是否有上一页进行返回,如果没有则跳转到首页
const pages = getCurrentPages()
if (pages && pages.length > 0) {
const firstPage = pages[0]
if (pages.length == 1 && (!firstPage.route || firstPage.route != 'pages/index')) {
uni.reLaunch({
url: '/pages/index'
})
} else {
uni.navigateBack({
delta: 1
})
}
} else {
uni.reLaunch({
url: '/pages/index'
})
}
},
// 更新顶部导航栏信息
async updateCustomBarInfo() {
// 获取vuex中的自定义顶栏的高度
let customBarHeight = this.vuex_custom_bar_height
let statusBarHeight = this.vuex_status_bar_height
// 如果获取失败则重新获取
if (!customBarHeight) {
try {
const navBarInfo = await this.$t.updateCustomBar()
customBarHeight = navBarInfo.customBarHeight
statusBarHeight = navBarInfo.statusBarHeight
} catch(e) {
setTimeout(() => {
this.updateCustomBarInfo()
}, 10)
return
}
}
// 更新vuex中的导航栏信息
this.$t.vuex('vuex_status_bar_height', statusBarHeight)
this.$t.vuex('vuex_custom_bar_height', customBarHeight)
}
}
}

View File

@@ -0,0 +1,330 @@
/**
* 页面展示列表数据
*/
export default {
data: [{
title: '图鸟首页',
backgroundColor: 'tn-cool-bg-color-1',
list: [{
icon: 'code',
title: '关于我们',
url: '/homePages/about',
author: '图鸟北北'
},{
icon: 'code',
title: '全局搜索',
url: '/homePages/search',
author: '图鸟北北'
},
{
icon: 'code',
title: '今日热榜',
url: '/homePages/hot',
author: '图鸟北北'
},
{
icon: 'code',
title: '前端业务',
url: '/homePages/profession',
author: '图鸟北北'
},
{
icon: 'code',
title: '加载效果',
url: '/homePages/loading',
author: '图鸟北北'
}
]
},
{
title: '酷炫圈子',
backgroundColor: 'tn-cool-bg-color-1',
list: [{
icon: 'code',
title: '博主_Me',
url: '/circlePages/blogger',
author: '图鸟北北'
},
{
icon: 'code',
title: '博主_Ta',
url: '/circlePages/blogger_other',
author: '图鸟北北'
},
{
icon: 'code',
title: '编辑发布',
url: '/circlePages/edit',
author: '图鸟北北'
},
{
icon: 'code',
title: '广告页',
url: '/circlePages/advertise',
author: '图鸟北北'
},
{
icon: 'code',
title: '资讯详情',
url: '/circlePages/news',
author: '图鸟北北'
},
{
icon: 'code',
title: '名片王者',
url: '/circlePages/king',
author: '图鸟北北'
},
{
icon: 'code',
title: '智能名片',
url: '/circlePages/business',
author: '图鸟北北'
},
{
icon: 'code',
title: '精选圈子',
url: '/circlePages/group',
author: '图鸟北北'
},
{
icon: 'code',
title: '积分排行',
url: '/circlePages/ranking',
author: '图鸟北北'
},
{
icon: 'code',
title: '圈子详情',
url: '/circlePages/details',
author: '图鸟北北'
},
{
icon: 'code',
title: '预约接龙',
url: '/circlePages/reserve',
author: '图鸟北北'
},
{
icon: 'code',
title: '活动创建',
url: '/circlePages/create',
author: '图鸟北北'
},
{
icon: 'code',
title: '打造圈子',
url: '/circlePages/build',
author: '图鸟北北'
},
{
icon: 'code',
title: '一起群聊',
url: '/circlePages/chat',
author: '图鸟北北'
},
{
icon: 'code',
title: '对话聊天',
url: '/circlePages/chatting',
author: '图鸟北北'
}
]
},
{
title: '活动广场',
backgroundColor: 'tn-cool-bg-color-1',
list: [{
icon: 'code',
title: '地图打卡',
url: '/activityPages/map',
author: '图鸟北北'
},
{
icon: 'code',
title: '快速答题',
url: '/activityPages/topic',
author: '图鸟北北'
},
{
icon: 'code',
title: '课程学习',
url: '/activityPages/study',
author: '图鸟北北'
},
{
icon: 'code',
title: '开源项目',
url: '/activityPages/project',
author: '图鸟北北'
},
{
icon: 'code',
title: '活动星球',
url: '/activityPages/planet',
author: '图鸟北北'
}
]
},
{
title: '商品优选',
backgroundColor: 'tn-cool-bg-color-1',
list: [{
icon: 'code',
title: '优质商家',
url: '/preferredPages/shop',
author: '图鸟北北'
},
{
icon: 'code',
title: '商品详情',
url: '/preferredPages/product',
author: '图鸟北北'
},
{
icon: 'code',
title: '历史订单',
url: '/preferredPages/order',
author: '图鸟北北'
},
{
icon: 'code',
title: '商品分类',
url: '/preferredPages/classify',
author: '图鸟北北'
},
{
icon: 'code',
title: '商家相册',
url: '/preferredPages/photo',
author: '图鸟北北'
},
{
icon: 'code',
title: '品牌官网',
url: '/preferredPages/website',
author: '图鸟北北'
},
{
icon: 'code',
title: '积分兑换',
url: '/preferredPages/redeem',
author: '图鸟北北'
},
{
icon: 'code',
title: '免单活动',
url: '/preferredPages/award',
author: '图鸟北北'
},
{
icon: 'code',
title: '免单获取',
url: '/preferredPages/awardget',
author: '图鸟北北'
}
]
},
{
title: '关于我的',
backgroundColor: 'tn-cool-bg-color-1',
list: [{
icon: 'code',
title: '使用协议',
url: '/minePages/protocol',
author: '图鸟北北'
},
{
icon: 'code',
title: '授权登录',
url: '/minePages/login',
author: '图鸟北北'
},
{
icon: 'code',
title: '消息通知',
url: '/minePages/message',
author: '图鸟北北'
},
{
icon: 'code',
title: '全局设置',
url: '/minePages/set',
author: '图鸟北北'
},
{
icon: 'code',
title: '立即体验',
url: '/minePages/start',
author: '图鸟北北'
},
{
icon: 'code',
title: '感谢名单',
url: '/minePages/thanks',
author: '图鸟北北'
},
{
icon: 'code',
title: '版本更新',
url: '/minePages/version',
author: '图鸟北北'
},
{
icon: 'code',
title: '帮助中心',
url: '/minePages/help',
author: '图鸟北北'
},
{
icon: 'code',
title: '头像上传',
url: '/minePages/avatar',
author: '图鸟北北'
},
{
icon: 'code',
title: '积分明细',
url: '/minePages/integral',
author: '图鸟北北'
},
{
icon: 'code',
title: '积分签到',
url: '/minePages/signed',
author: '图鸟北北'
},
{
icon: 'code',
title: '好物收藏',
url: '/minePages/collect',
author: '图鸟北北'
},
{
icon: 'code',
title: '账号安全',
url: '/minePages/safety',
author: '图鸟北北'
},
{
icon: 'code',
title: '赞赏支持',
url: '/minePages/reward',
author: '图鸟北北'
},
{
icon: 'code',
title: '缺省页',
url: '/minePages/default',
author: '图鸟北北'
},
{
icon: 'code',
title: '富文本',
url: '/minePages/content',
author: '图鸟北北'
}
]
}
]
}