图鸟UI V1.0.0 版本提交

This commit is contained in:
JaylenTech
2021-12-29 11:14:34 +08:00
commit cb0af8c384
203 changed files with 44944 additions and 0 deletions
Vendored
BIN
View File
Binary file not shown.
+3
View File
@@ -0,0 +1,3 @@
/unpackage/dist/*
/node_modules/*
/.idea/*
+20
View File
@@ -0,0 +1,20 @@
{ // launch.json 配置了启动调试时相关设置,configurations下节点名称可为 app-plus/h5/mp-weixin/mp-baidu/mp-alipay/mp-qq/mp-toutiao/mp-360/
// launchtype项可配置值为local或remote, local代表前端连本地云函数,remote代表前端连云端云函数
"version": "0.0",
"configurations": [{
"default" :
{
"launchtype" : "local"
},
"h5" :
{
"launchtype" : "local"
},
"mp-weixin" :
{
"launchtype" : "local"
},
"type" : "uniCloud"
}
]
}
+91
View File
@@ -0,0 +1,91 @@
<script>
import Vue from 'vue'
import store from './store/index.js'
import updateCustomBarInfo from './tuniao-ui/libs/function/updateCustomBarInfo.js'
export default {
onLaunch: function() {
uni.getSystemInfo({
success: function(e) {
// #ifndef H5
// 获取手机系统版本
const system = e.system.toLowerCase()
const platform = e.platform.toLowerCase()
// 判断是否为ios设备
if (platform.indexOf('ios') != -1 && (system.indexOf('ios') != -1 || system.indexOf('macos') != -1)) {
Vue.prototype.SystemPlatform = 'apple'
} else if (platform.indexOf('android') != -1 && (system.indexOf('android') != -1)) {
Vue.prototype.SystemPlatform = 'android'
} else {
Vue.prototype.SystemPlatform = 'devtools'
}
// #endif
}
})
// 获取设备的状态栏信息和自定义顶栏信息
// store.dispatch('updateCustomBarInfo')
updateCustomBarInfo().then((res) => {
store.commit('$tStore', {
name: 'vuex_status_bar_height',
value: res.statusBarHeight
})
store.commit('$tStore', {
name: 'vuex_custom_bar_height',
value: res.customBarHeight
})
})
// #ifdef MP-WEIXIN
//更新检测
if (wx.canIUse('getUpdateManager')) {
const updateManager = wx.getUpdateManager();
updateManager && updateManager.onCheckForUpdate((res) => {
if (res.hasUpdate) {
updateManager.onUpdateReady(() => {
uni.showModal({
title: '更新提示',
content: '新版本已经准备就绪,是否需要重新启动应用?',
success: (res) => {
if (res.confirm) {
uni.clearStorageSync() // 更新完成后刷新storage的数据
updateManager.applyUpdate()
}
}
})
})
updateManager.onUpdateFailed(() => {
uni.showModal({
title: '已有新版本上线',
content: '小程序自动更新失败,请删除该小程序后重新搜索打开哟~~~',
showCancel: false
})
})
} else {
//没有更新
}
})
} else {
uni.showModal({
title: '提示',
content: '当前微信版本过低,无法使用该功能,请更新到最新的微信后再重试。',
showCancel: false
})
}
// #endif
},
onShow: function() {
// console.log('App Show')
},
onHide: function() {
// console.log('App Hide')
}
}
</script>
<style lang="scss">
/* 注意要写在第一行,同时给style标签加入lang="scss"属性 */
@import './tuniao-ui/index.scss';
@import './tuniao-ui/iconfont.css';
</style>
+3
View File
@@ -0,0 +1,3 @@
<h3 align="center" style="margin: 30px 0 30px;font-weight: bold;font-size:40px;">Tuniao UI</h3>
<h3 align="center">炫酷且可以快速开发UI框架</h3>
+272
View File
@@ -0,0 +1,272 @@
<template>
<view class="basic-avatar">
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed>头像</tn-nav-bar>
<!-- 页面内容 -->
<view :style="{paddingTop: vuex_custom_bar_height + 'px'}">
<dynamic-demo-template ref="demoTemplate" :tips="tips" :sectionList="sectionList" :full="false" @click="click">
<block v-if="singleAvatarShow">
<tn-avatar
:backgroundColor="backgroundColor"
:src="src"
:text="text"
:icon="icon"
:shape="shape"
:size="size"
:shadow="shadow"
:border="border"
:borderColor="borderColor"
:imgMode="imgMode"
:badge="badge"
:badgeSize="badgeSize"
:badgeBgColor="badgeBgColor"
:badgeColor="badgeColor"
:badgeIcon="badgeIcon"
:badgeText="badgeText"
:badgePosition="badgePosition"
>
</tn-avatar>
</block>
<block v-else>
<tn-avatar-group
:lists="groupList"
:shape="shape"
:size="size"
:gap="0.4"
></tn-avatar-group>
</block>
</dynamic-demo-template>
</view>
</view>
</template>
<script>
import dynamicDemoTemplate from '@/libs/components/dynamic-demo-template.vue'
export default {
name: 'basicAvatar',
components: {dynamicDemoTemplate},
data() {
return {
backgroundColor: '',
src: 'https://tnuiimage.tnkjapp.com/avatar/xiaomai4.jpg',
text: '',
icon: '',
shape: 'circle',
size: '',
shadow: false,
border: false,
borderColor: 'rgba(0, 0, 0, 0.1)',
imgMode: 'aspectFill',
badge: false,
badgeSize: 28,
badgeBgColor: '#AAAAAA',
badgeColor: '#FFFFFF',
badgeIcon: 'sex-male',
badgeText: '',
badgePosition: [0, 0],
groupList: [
{src: 'https://tnuiimage.tnkjapp.com/avatar/xiaomai1.jpg'},
{src: 'https://tnuiimage.tnkjapp.com/avatar/xiaomai2.jpg'},
{text: 'TN'},
{icon: 'logo-tuniao'},
{src: 'https://tnuiimage.tnkjapp.com/avatar/xiaomai1.jpg'},
{src: 'https://tnuiimage.tnkjapp.com/avatar/xiaomai2.jpg'},
],
// 头像显示方式切换
singleAvatarShow: true,
tips: ['无需依赖额外的样式文件','使用tn-avatar组件'],
sectionList: [
{
name: '参数切换',
section: [
{
title: '形状',
optional: ['圆形','方形'],
methods: 'shapeChange'
},
{
title: '类型',
optional: ['图片','文字','图标'],
methods: 'typeChange'
},
{
title: '大小',
optional: ['默认','sm','lg','xl','120rpx'],
methods: 'sizeChange'
},
{
title: '阴影',
optional: ['显示','隐藏'],
methods: 'shadowChange',
current: 1
},
{
title: '边框',
optional: ['显示','隐藏'],
methods: 'borderChange',
current: 1
},
{
title: '自定义颜色',
optional: ['默认','自定义'],
methods: 'colorChange'
},
{
title: '角标',
optional: ['显示','隐藏'],
methods: 'badgeChange',
current: 1
},
{
title: '角标大小',
optional: ['默认','20'],
methods: 'badgeSizeChange',
show: false
},
{
title: '角标内容',
optional: ['图标','文字'],
methods: 'badgeContentChange',
show: false
},
{
title: '角标位置',
optional: ['默认','[8,8]'],
methods: 'badgePositionChange',
show: false
}
]
},
{
name: '样式切换',
section: [
{
title: '方式',
optional: ['单头像','头像组'],
methods: 'singleAvatarChange'
}
]
}
]
}
},
methods: {
click(event) {
this[event.methods] && this[event.methods](event)
},
// 切换头像形状
shapeChange(event) {
this.shape = event.index === 0 ? 'circle' : 'square'
},
// 切换头像类型
typeChange(event) {
switch (event.index) {
case 0:
this.src = 'https://tnuiimage.tnkjapp.com/avatar/xiaomai4.jpg'
this.text = ''
this.icon = ''
break
case 1:
this.src = ''
this.text = 'TN'
this.icon = ''
break
case 2:
this.src = ''
this.text = ''
this.icon = 'logo-tuniao'
break
}
},
// 切换头像大小
sizeChange(event) {
this.size = event.index === 0 ? '' : event.name
},
// 切换阴影状态
shadowChange(event) {
this.shadow = event.index === 0 ? true : false
},
// 切换边框状态
borderChange(event) {
this.border = event.index === 0 ? true : false
},
// 切换颜色
colorChange(event) {
if (event.index === 0) {
this.backgroundColor = ''
this.borderColor = 'rgba(0, 0, 0, 0.1)'
this.badgeBgColor = '#AAAAAA'
this.badgeColor = '#FFFFFF'
} else {
this.backgroundColor = '#01BEFF'
this.borderColor = '#E6E6E6'
this.badgeBgColor = 'tn-bg-red'
this.badgeColor = '#FFFFFF'
}
},
// 切换角标状态
badgeChange(event) {
if (event.index === 0) {
this.badge = true
this.$refs.demoTemplate.updateSectionBtnsState([7,8,9], true)
} else {
this.badge = false
this.$refs.demoTemplate.updateSectionBtnsState([7,8,9], false)
}
},
// 切换角标大小
badgeSizeChange(event) {
this.badgeSize = event.index === 0 ? 28 : Number(event.name)
},
// 切换角标内容
badgeContentChange(event) {
switch(event.index) {
case 0:
this.badgeIcon = 'sex-male'
this.badgeText = ''
this.badgeSizeChange({index: 0})
this.$refs.demoTemplate.updateSectionBtnsValue(0, 7, 0)
break
case 1:
this.badgeIcon = ''
this.badgeText = '99+'
this.badgeSize = 0
break
}
},
// 切换角标位置
badgePositionChange(event) {
switch(event.index) {
case 0:
this.badgePosition = [0, 0]
break
case 1:
this.badgePosition = [8, 8]
break
}
},
// 单头像、头像组切换
singleAvatarChange(event) {
this.singleAvatarShow = event.index === 0
}
},
}
</script>
<style lang="scss" scoped>
</style>
+200
View File
@@ -0,0 +1,200 @@
<template>
<view class="basic-badge">
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed>微标</tn-nav-bar>
<!-- 页面内容 -->
<view :style="{paddingTop: vuex_custom_bar_height + 'px'}">
<dynamic-demo-template ref="demoTemplate" :tips="tips" :sectionList="sectionList" :full="false" @click="click">
<block v-if="!absolute">
<tn-badge
:backgroundColor="backgroundColor"
:fontColor="fontColor"
:fontSize="fontSize"
:radius="radius"
:dot="dot"
:padding="padding"
:margin="margin"
>
<text v-if="dot === false">{{ value }}</text>
</tn-badge>
</block>
<block v-else>
<view class="badge-container">
<tn-badge
:backgroundColor="backgroundColor"
:fontColor="fontColor"
:fontSize="fontSize"
:radius="radius"
:dot="dot"
:padding="padding"
:margin="margin"
:absolute="true"
:top="top"
:right="right"
:translateCenter="translateCenter"
>
<text v-if="dot === false">{{ value }}</text>
</tn-badge>
</view>
</block>
</dynamic-demo-template>
</view>
</view>
</template>
<script>
import dynamicDemoTemplate from '@/libs/components/dynamic-demo-template.vue'
export default {
name: 'basicBadge',
components: {dynamicDemoTemplate},
data() {
return {
value: '0',
backgroundColor: '',
fontColor: '',
fontSize: 0,
radius: 0,
dot: false,
padding: '',
margin: '',
absolute: false,
top: '',
right: '',
translateCenter: true,
tips: ['无需依赖额外的样式文件','使用tn-badge组件'],
sectionList: [
{
name: '参数切换',
section: [
{
title: '数值',
optional: ['0','99','100','1024'],
methods: 'valueChange'
},
{
title: '点微标',
optional: ['是','否'],
methods: 'dotChange',
current: 1
},
{
title: '自定义颜色',
optional: ['默认','自定义'],
methods: 'colorChange'
},
{
title: '自定义大小',
optional: ['默认','自定义'],
methods: 'sizeChange'
},
{
title: '绝对定位',
optional: ['是','否'],
methods: 'absoluteChange',
current: 1
},
{
title: '自定义绝对定位位置',
optional: ['默认','自定义'],
methods: 'absolutePositionChange',
show: false
},
{
title: '居中绝对定位原点',
optional: ['是','否'],
methods: 'absoluteCenterChange',
show: false
}
]
}
]
}
},
methods: {
click(event) {
this[event.methods] && this[event.methods](event)
},
// 切换值
valueChange(event) {
this.value = this.$t.number.formatNumberString(event.name)
},
// 切换点显示状态
dotChange(event) {
if (event.index === 0) {
this.dot = true
this.$refs.demoTemplate.updateSectionBtnsState(0, false)
} else {
this.dot = false
this.$refs.demoTemplate.updateSectionBtnsState(0, true)
}
},
// 切换自定义颜色
colorChange(event) {
if (event.index === 0) {
this.backgroundColor = ''
this.fontColor = ''
} else {
this.backgroundColor = 'tn-bg-red'
this.fontColor = '#FFFFFF'
}
},
// 切换自定义大小
sizeChange(event) {
if (event.index === 0) {
this.radius = 0
this.fontSize = 0
this.padding = ''
this.margin = ''
} else {
this.radius = 48
this.fontSize = 30
this.padding = '10rpx 25rpx'
this.margin = '30rpx'
}
},
// 切换绝对定位状态
absoluteChange(event) {
if (event.index === 0) {
this.absolute = true
this.$refs.demoTemplate.updateSectionBtnsState([5,6], true)
} else {
this.absolute = false
this.$refs.demoTemplate.updateSectionBtnsState([5,6], false)
}
},
// 切换绝对定位的位置
absolutePositionChange(event) {
if (event.index === 0) {
this.top = ''
this.right = ''
} else {
this.top = '20rpx'
this.right = '100%'
}
},
// 切换绝对定位居中原点
absoluteCenterChange(event) {
this.translateCenter = event.index === 0
}
},
}
</script>
<style lang="scss" scoped>
.badge-container {
// 防止越过父级
position: relative;
width: 80rpx;
height: 80rpx;
background-color: $tn-font-sub-color;
}
</style>
+139
View File
@@ -0,0 +1,139 @@
<template>
<view class="basic-border">
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed>边框</tn-nav-bar>
<!-- 页面内容 -->
<view :style="{paddingTop: vuex_custom_bar_height + 'px'}">
<dynamic-demo-template ref="demoTemplate" :tips="tips" :sectionList="sectionList" :full="true" @click="click">
<view
class="border-content"
:class="[borderClass]"
></view>
<view style="visibility: hidden;height: 1px;">tuniao</view>
</dynamic-demo-template>
</view>
</view>
</template>
<script>
import dynamicDemoTemplate from '@/libs/components/dynamic-demo-template.vue'
export default {
name: 'basicBorder',
components: {dynamicDemoTemplate},
data() {
return {
borderType: 'solid',
borderPosition: '',
borderColor: '',
borderBold: false,
tips: ['无需依赖额外的样式文件','不使用任何组件'],
sectionList: [
{
name: '参数切换',
section: [
{
title: '样式',
optional: ['实线','虚线'],
methods: 'typeChange'
},
{
title: '位置',
optional: ['全部','上','下','左','右'],
methods: 'positionChange'
},
{
title: '颜色',
optional: ['默认','自定义'],
methods: 'colorChange'
},
{
title: '加粗',
optional: ['默认','加粗'],
methods: 'boldChange'
}
]
}
]
}
},
computed: {
borderClass() {
let clazz = ''
if (this.borderPosition === '') {
clazz += ` tn-border-${this.borderType}`
} else {
clazz += ` tn-border-${this.borderType}-${this.borderPosition}`
}
if (this.borderColor) {
clazz += ` ${this.borderColor}`
}
if (this.borderBold) {
clazz += ' tn-bold-border'
}
return clazz
}
},
methods: {
click(event) {
this[event.methods] && this[event.methods](event)
this.$refs.demoTemplate.updateSectionScrollView()
},
// 切换边框样式
typeChange(event) {
this.borderType = event.index === 0 ? 'solid' : 'dashed'
},
// 切换边框位置
positionChange(event) {
switch (event.index) {
case 0:
this.borderPosition = ''
break
case 1:
this.borderPosition = 'top'
break
case 2:
this.borderPosition = 'bottom'
break
case 3:
this.borderPosition = 'left'
break
case 4:
this.borderPosition = 'right'
break
}
},
// 切换边框颜色
colorChange(event) {
this.borderColor = event.index === 0 ? '' : 'tn-border-red'
},
// 切换边框加粗状态
boldChange(event) {
this.borderBold = event.index === 0 ? false : true
}
},
}
</script>
<style lang="scss" scoped>
.border-content {
width: 80%;
height: 80rpx;
background-color: #FFFFFF;
margin: 0 auto;
}
</style>
+230
View File
@@ -0,0 +1,230 @@
<template>
<view class="basic-button">
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed>按钮</tn-nav-bar>
<!-- 页面内容 -->
<view :style="{paddingTop: vuex_custom_bar_height + 'px'}">
<dynamic-demo-template ref="demoTemplate" :tips="tips" :sectionList="sectionList" :full="false" @click="click">
<tn-button
:backgroundColor="backgroundColor"
:fontColor="fontColor"
:fontSize="fontSize"
:shape="shape"
:shadow="shadow"
:width="width"
:height="height"
:size="size"
:fontBold="fontBold"
:padding="padding"
:margin="margin"
:plain="plain"
:border="border"
:borderBold="borderBold"
:disabled="disabled"
:loading="loading"
>
<block v-if="shape !== 'icon'">演示按钮</block>
<block v-else>
<text class="tn-icon-discover-planet-fill"></text>
</block>
</tn-button>
</dynamic-demo-template>
</view>
</view>
</template>
<script>
import dynamicDemoTemplate from '@/libs/components/dynamic-demo-template.vue'
export default {
name: 'basicButton',
components: {dynamicDemoTemplate},
data() {
return {
backgroundColor: '',
fontColor: '',
fontSize: 0,
shape: '',
shadow: false,
width: '',
height: '',
size: '',
fontBold: false,
padding: '',
margin: '',
plain: false,
border: true,
borderBold: false,
disabled: false,
loading: false,
tips: ['无需依赖额外的样式文件','使用tn-button组件'],
sectionList: [
{
name: '参数切换',
section: [
{
title: '自定义颜色',
optional: ['默认','自定义'],
methods: 'colorChange'
},
{
title: '自定义大小',
optional: ['默认','自定义'],
methods: 'sizeChange'
},
{
title: '内置大小',
optional: ['默认','sm','lg'],
methods: 'insertSizeChange'
},
{
title: '形状',
optional: ['默认','圆角','图标'],
methods: 'shapeChange'
},
{
title: '显示阴影',
optional: ['不显示','显示'],
methods: 'shadowChange'
},
{
title: '字体加粗控制',
optional: ['默认','加粗'],
methods: 'fontBoldChange'
},
{
title: '镂空控制',
optional: ['默认','镂空'],
methods: 'plainChange'
},
{
title: '镂空边框控制',
optional: ['显示','不显示'],
methods: 'borderChange'
},
{
title: '镂空边框加粗控制',
optional: ['默认','加粗'],
methods: 'borderBoldChange'
},
{
title: '禁用控制',
optional: ['关闭','开启'],
methods: 'disabledChange'
},
{
title: '加载控制',
optional: ['关闭','开启'],
methods: 'loadingChange'
}
]
}
]
}
},
methods: {
click(event) {
this[event.methods] && this[event.methods](event)
},
// 切换自定义颜色
colorChange(event) {
switch(event.index) {
case 0:
this.backgroundColor = ''
this.fontColor = ''
break
case 1:
this.backgroundColor = 'tn-bg-indigo'
this.fontColor = '#4030E8'
break
}
},
// 切换自定义大小
sizeChange(event) {
switch(event.index) {
case 0:
this.width = 'auto'
this.height = ''
this.fontSize = 0
this.padding = ''
this.$refs.demoTemplate.updateSectionBtnsState(2, true)
break
case 1:
this.width = '200rpx'
this.height = '80rpx'
this.fontSize = 36
this.padding = '10rpx 20rpx'
this.size = ''
this.$refs.demoTemplate.updateSectionBtnsState(2, false)
break
}
this.$refs.demoTemplate.updateSectionScrollView()
},
// 切换按钮形状
shapeChange(event) {
switch(event.index) {
case 0:
this.shape = ''
break
case 1:
this.shape = 'round'
break
case 2:
this.shape = 'icon'
break
}
},
// 切换阴影状态
shadowChange(event) {
if (event.index === 0) {
this.shadow = false
this.$refs.demoTemplate.updateSectionBtnsState(10, true)
} else {
this.shadow = true
this.loading = false
this.$refs.demoTemplate.updateSectionBtnsState(10, false)
}
},
// 切换内置尺寸状态
insertSizeChange(event) {
this.size = event.index === 0 ? '' : event.name
this.$refs.demoTemplate.updateSectionScrollView()
},
// 切换字体加粗状态
fontBoldChange(event) {
this.fontBold = event.index === 0 ? false : true
},
// 切换镂空状态
plainChange(event) {
this.plain = event.index === 0 ? false : true
},
// 切换镂空边框状态
borderChange(event) {
this.border = event.index === 0 ? true : false
},
// 切换镂空边框加粗状态
borderBoldChange(event) {
this.borderBold = event.index === 0 ? false : true
},
// 切换禁用状态
disabledChange(event) {
this.disabled = event.index === 0 ? false : true
},
// 切换加载状态
loadingChange(event) {
this.loading = event.index === 0 ? false : true
},
},
}
</script>
<style lang="scss" scoped>
</style>
+710
View File
@@ -0,0 +1,710 @@
<template>
<view class="basic-background">
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed>背景</tn-nav-bar>
<!-- 页面内容 -->
<view :style="{paddingTop: vuex_custom_bar_height + 'px'}">
<view class="tn-flex tn-flex-nowrap background-container">
<view class="background__left-container">
<scroll-view :style="[scrollViewStyle]" scroll-y>
<view class="background__left__picker">
<view class="background__left__picker__item-wrapper" @click="pickerColorClick(0)">
<view
class="background__left__picker__item background__left__picker__item--basic picker-color-item-0"
:class="[{'tn-shadow-blur': currentColorIndex === 0}]" style="background-color: #01BEFF;">
<text class="tn-icon-logo-tuniao"></text>
</view>
</view>
<block v-for="(item, index) in colorList" :key="index">
<view class="background__left__picker__item-wrapper" @click="pickerColorClick(index + 1)">
<view class="background__left__picker__item" :class="[`picker-color-item-${index + 1} tn-bg-${item.color}`, {'tn-shadow-blur': currentColorIndex === index + 1}]"></view>
</view>
</block>
<!-- 选中后的边框 -->
<view class="background__left__picker__item__select-wrapper" :style="[colorSelectItemStyle]">
<view class="circle-wrapper right">
<view class="circle-progress right-circle"
:class="{'circle-progress--active': colorSelectFlag}"
:style="{borderColor: currentColorIndex === 0 ? '#01BEFF' : colorList[currentColorIndex - 1]['value']['dark']}"></view>
</view>
<view class="circle-wrapper left">
<view class="circle-progress left-circle"
:class="{'circle-progress--active': colorSelectFlag}"
:style="{borderColor: currentColorIndex === 0 ? '#01BEFF' : colorList[currentColorIndex - 1]['value']['dark']}"></view>
</view>
</view>
</view>
</scroll-view>
</view>
<view class="background__right-container">
<scroll-view :style="[scrollViewStyle]" scroll-y>
<view class="background__right__show" :class="{'background__right__show--visible': colorSelectFlag}">
<block v-if="currentColorIndex === 0">
<view class="background__right__show--title">图鸟基础配色</view>
<!-- 色盘 start-->
<view class="box" >
<view v-for="(item,index) in 16" :key="index" :class="'colorwheel-box colorwheel-' + (index+1)"></view>
</view>
<!-- 色盘 end-->
<view class="background__right__show__content">
<view class="background__right__show__content__item tn-shadow-blur" style="background-color: #01BEFF;">
<view class="background__right__show__content__item--title">主色蓝</view>
<view class="background__right__show__content__item--value">#01BEFF</view>
</view>
<view class="background__right__show__content__item tn-shadow-blur" style="background-color: #FBBD12;">
<view class="background__right__show__content__item--title">主色橙</view>
<view class="background__right__show__content__item--value">#FBBD12</view>
</view>
<view class="background__right__show__content__item tn-shadow-blur" style="background-color: #00FFC6;">
<view class="background__right__show__content__item--title background__right__show__content__item--title--light">点缀青</view>
<view class="background__right__show__content__item--value">#00FFC6</view>
</view>
<view class="background__right__show__content__item tn-shadow-blur" style="background-color: #FFF00D;">
<view class="background__right__show__content__item--title background__right__show__content__item--title--light">点缀黄</view>
<view class="background__right__show__content__item--value">#FFF00D</view>
</view>
<view class="background__right__show__content__item tn-shadow-blur" style="background-color: #FF71D2;">
<view class="background__right__show__content__item--title">辅助粉</view>
<view class="background__right__show__content__item--value">#FF71D2</view>
</view>
<view class="background__right__show__content__item tn-shadow-blur" style="background-color: #82B2FF;">
<view class="background__right__show__content__item--title">辅助蓝</view>
<view class="background__right__show__content__item--value background__right__show__content__item--value--light">#82B2FF</view>
</view>
<view class="background__right__show__content__item tn-shadow-blur" style="background-color: #080808;">
<view class="background__right__show__content__item--title">文字颜色</view>
<view class="background__right__show__content__item--value background__right__show__content__item--value--light">#080808</view>
</view>
<view class="background__right__show__content__item tn-shadow-blur" style="background-color: #F4F4F4;">
<view class="background__right__show__content__item--title background__right__show__content__item--title--light">背景灰</view>
<view class="background__right__show__content__item--value background__right__show__content__item--value--light">#F4F4F4</view>
</view>
</view>
</block>
<block v-else>
<view class="background__right__show--title">{{ selectColorInfo.name }}-{{ selectColorInfo.color }}</view>
<view class="background__right__show__content">
<block v-for="(value, key, index) in selectColorInfo.value" :key="index">
<view class="background__right__show__content__item tn-shadow-blur" :class="[key === 'normal' ? `tn-bg-${selectColorInfo.color}` : `tn-bg-${selectColorInfo.color}--${key}`]">
<view class="background__right__show__content__item--title" :class="[['disabled','light'].includes(key) ? 'background__right__show__content__item--title--light' : '']">{{ key }}</view>
<view class="background__right__show__content__item--value"
:class="[['disabled','light'].includes(key) ? 'background__right__show__content__item--value--light' : '',{'tn-color-white': selectColorInfo.color === 'gray' && key === 'normal'}]"
>
{{ value }}</view>
</view>
</block>
</view>
<block v-if="!['brown','grey','gray'].includes(selectColorInfo.color)">
<view class="background__right__show--title background__right__show--title--gradient" :class="[`tn-cool-bg-color-${currentColorIndex % 16 + 1}`]">渐变色</view>
<view class="background__right__show__content">
<view class="background__right__show__content__item tn-shadow-blur" :class="[`tn-main-gradient-${selectColorInfo.color}`]">
<view class="background__right__show__content__item--title"></view>
<view class="background__right__show__content__item--value"></view>
</view>
<view class="background__right__show__content__item tn-shadow-blur" :class="[`tn-main-gradient-${selectColorInfo.color}--reverse`]">
<view class="background__right__show__content__item--title"></view>
<view class="background__right__show__content__item--value"></view>
</view>
<view class="background__right__show__content__item tn-shadow-blur" :class="[`tn-main-gradient-${selectColorInfo.color}--light`]">
<view class="background__right__show__content__item--title"></view>
<view class="background__right__show__content__item--value"></view>
</view>
<view class="background__right__show__content__item tn-shadow-blur" :class="[`tn-main-gradient-${selectColorInfo.color}--light--reverse`]">
<view class="background__right__show__content__item--title"></view>
<view class="background__right__show__content__item--value"></view>
</view>
</view>
</block>
</block>
</view>
</scroll-view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
name: 'basicBackground',
data() {
return {
colorList: [{
name: '红色',
color: 'red',
value: {
normal: '#E83A30',
dark: '#BA2E26',
disabled: '#F39C97',
light: '#FAD8D6'
}
},
{
name: '紫红色',
color: 'purplered',
value: {
normal: '#E72F8C',
dark: '#B9266F',
disabled: '#F397C5',
light: '#FAD5E8'
}
},
{
name: '紫色',
color: 'purple',
value: {
normal: '#892FE8',
dark: '#6E26BA',
disabled: '#C497F3',
light: '#E7D5FA'
}
},
{
name: '蓝紫色',
color: 'bluepurple',
value: {
normal: '#5F4FD9',
dark: '#4C3FAE',
disabled: '#AFA7EC',
light: '#DFDCF7'
}
},
{
name: '海蓝色',
color: 'aquablue',
value: {
normal: '#3646FF',
dark: '#2B38CC',
disabled: '#9AA2FF',
light: '#D7DAFF'
}
},
{
name: '蓝色',
color: 'blue',
value: {
normal: '#3D7EFF',
dark: '#3165CC',
disabled: '#9EBEFF',
light: '#D8E5FF'
}
},
{
name: '靛蓝色',
color: 'indigo',
value: {
normal: '#31C9E8',
dark: '#27A1BA',
disabled: '#98E4F3',
light: '#D6F4FA'
}
},
{
name: '青色',
color: 'cyan',
value: {
normal: '#2DE8BD',
dark: '#24BA97',
disabled: '#96F3DE',
light: '#D5FAF2'
}
},
{
name: '青绿色',
color: 'teal',
value: {
normal: '#24F083',
dark: '#1DC069',
disabled: '#91F7C1',
light: '#D3FCE6'
}
},
{
name: '绿色',
color: 'green',
value: {
normal: '#31E749',
dark: '#27B93A',
disabled: '#98F3A4',
light: '#D6FADB'
}
},
{
name: '黄绿色',
color: 'yellowgreen',
value: {
normal: '#A4E82F',
dark: '#82BA26',
disabled: '#D1F397',
light: '#EDFAD5'
}
},
{
name: '酸橙色',
color: 'lime',
value: {
normal: '#D5EB00',
dark: '#AABC00',
disabled: '#E9F57F',
light: '#F7FBCC'
}
},
{
name: '黄色',
color: 'yellow',
value: {
normal: '#FFF420',
dark: '#CCC21A',
disabled: '#FFF88F',
light: '#FFFDD2'
}
},
{
name: '橘黄色',
color: 'orangeyellow',
value: {
normal: '#FFCA28',
dark: '#CCA220',
disabled: '#FFE493',
light: '#FFF4D4'
}
},
{
name: '橙色',
color: 'orange',
value: {
normal: '#FFA726',
dark: '#CC851E',
disabled: '#FFD392',
light: '#FFEDD4'
}
},
{
name: '橘红色',
color: 'orangered',
value: {
normal: '#FF7043',
dark: '#CC5A36',
disabled: '#FFB7A1',
light: '#FFE2D9'
}
},
{
name: '棕色',
color: 'brown',
value: {
normal: '#914F2C',
dark: '#743F23',
disabled: '#C8A795',
light: '#E9DCD5'
}
},
{
name: '玄灰色',
color: 'grey',
value: {
normal: '#78909C',
dark: '#5F7E8B',
disabled: '#C6D1D8',
light: '#E4E9EC'
}
},
{
name: '灰色',
color: 'gray',
value: {
normal: '#AAAAAA',
dark: '#838383',
disabled: '#E6E6E6',
light: '#F8F7F8'
}
}
],
// scrollView的样式
scrollViewStyle: {
height: 0
},
// picker列表颜色列表信息
pickerColorInfos: [],
// picker列表颜色选中框样式
colorSelectItemStyle: {
top: 0,
left: 0
},
// 当前选中的颜色序号
currentColorIndex: 0,
colorSelectFlag: false,
// 当前选中颜色的色值信息
selectColorInfo: {}
}
},
onLoad() {
this.initScrollViewHeight()
},
onReady() {
// 等待加载组件完成
setTimeout(() => {
this.getPickerColorItemInfo()
}, 10)
},
methods: {
// 计算scrollView的高度
initScrollViewHeight() {
// 获取当前屏幕的安全高度
uni.getSystemInfo({
success: (systemInfo) => {
this.scrollViewStyle.height = systemInfo.safeArea.height - this.vuex_custom_bar_height + systemInfo
.statusBarHeight + 'px'
}
})
},
// 获取色值列表的位置信息
getPickerColorItemInfo() {
// 获取picker容器的信息
this._tGetRect('.background__left__picker').then((pickerInfo) => {
let view = uni.createSelectorQuery().in(this)
for (let i = 0; i <= this.colorList.length; i++) {
view.select('.picker-color-item-' + i).boundingClientRect()
}
view.exec(res => {
// 如果没有获取到,则重新获取
if (!res.length) {
setTimeout(() => {
this.getPickerColorItemInfo()
return
}, 10)
}
// 将每个选择颜色值的宽高,位置信息存入列表中
res.map((item, index) => {
this.pickerColorInfos.push({
x: (item.top - pickerInfo.top) + (item.height / 2),
y: (item.left - pickerInfo.left) + (item.width / 2)
})
// 初始化选中的圆环
this.updatePickerColorSelectItem()
this.updateSelectColorInfo()
})
})
})
},
// 色值选择
pickerColorClick(index) {
if (this.colorSelectFlag === false || index === this.currentColorIndex) {
return
}
this.currentColorIndex = index
this.updatePickerColorSelectItem()
this.updateSelectColorInfo()
},
// 设置选中圆环信息
updatePickerColorSelectItem() {
// 先设置已选中状态为false,然后再设置选中圆环的位置信息,等待动画执行完毕后在设置已选中状态为true
this.colorSelectFlag = false
const colorInfos = this.pickerColorInfos[this.currentColorIndex]
this.colorSelectItemStyle.top = colorInfos.x - uni.upx2px(40) + 'px'
this.colorSelectItemStyle.left = colorInfos.y - uni.upx2px(40) + 'px'
setTimeout(() => {
this.colorSelectFlag = true
}, 10)
},
// 设置选中颜色的信息
updateSelectColorInfo() {
if (this.currentColorIndex === 0) {
return
}
this.selectColorInfo = this.colorList[this.currentColorIndex - 1]
}
}
}
</script>
<style lang="scss" scoped>
/* 色盘 start*/
.box{
position: relative;
margin: auto;
display: block;
width: 550rpx;
height: 600rpx;
background: none;
}
.colorwheel-box{
position: absolute;
width: 80%;
height: 50%;
left: 10%;
bottom: 20%;
border-radius: 100% 10rpx;
opacity: 0.4;
}
.colorwheel-1{
background: #2DE8BD;
transform: rotate(-78.75deg);
}
.colorwheel-2{
background: #24F083;
transform: rotate(-90deg);
}
.colorwheel-3{
background: #31E749;
transform: rotate(-101.25deg);
}
.colorwheel-4{
background: #A4E82F;
transform: rotate(-112.5deg);
}
.colorwheel-5{
background: #D5EB00;
transform: rotate(-123.75deg);
}
.colorwheel-6{
background: #FFF420;
transform: rotate(-135deg);
}
.colorwheel-7{
background: #FFCA28;
transform: rotate(-146.25deg);
}
.colorwheel-8{
background: #FFA726;
transform: rotate(-157.5deg);
}
.colorwheel-9{
background: #FF7043;
transform: rotate(-168.75deg);
}
.colorwheel-10{
background: #E83A30;
transform: rotate(0deg);
}
.colorwheel-11{
background: #E72F8C;
transform: rotate(-11.25deg);
}
.colorwheel-12{
background: #892FE8;
transform: rotate(-22.5deg);
}
.colorwheel-13{
background: #5F4FD9;
transform: rotate(-33.75deg);
}
.colorwheel-14{
background: #3646FF;
transform: rotate(-45deg);
}
.colorwheel-15{
background: #3D7EFF;
transform: rotate(-56.25deg);
}
.colorwheel-16{
background: #31C9E8;
transform: rotate(-67.5deg);
}
/* 色盘 end*/
/* 背景颜色容器 start */
.background-container {
.background {
/* 左边容器 start */
&__left-container {
width: 16%;
height: 100%;
box-shadow: 0rpx 0rpx 80rpx 0rpx rgba(0, 0, 0, 0.07);
}
&__left {
&__picker {
display: flex;
flex-direction: column;
align-items: center;
padding-top: 20rpx;
position: relative;
&__item-wrapper {
width: 100%;
}
&__item {
width: 50rpx;
height: 50rpx;
margin: 18rpx auto;
border-radius: 50%;
border: none;
&--basic {
text-align: center;
color: #FFFFFF;
line-height: 50rpx;
}
&__select-wrapper {
width: 80rpx;
height: 80rpx;
position: absolute;
.circle-wrapper {
width: 40rpx;
height: 80rpx;
position: absolute;
top: 0;
overflow: hidden;
&.right {
right: 0;
}
&.left {
left: 0;
}
.circle-progress {
display: inline-block;
width: 80rpx;
height: 80rpx;
border: 6rpx solid transparent;
border-radius: 50%;
position: absolute;
top: 0;
transform: rotate(225deg);
&.right-circle {
right: 0;
border-bottom-color: transparent !important;
border-left-color: transparent !important;
// transition: transform 0.3s cubic-bezier(0,.13,0,1.43);
}
&.left-circle {
left: 0;
border-top-color: transparent !important;
border-right-color: transparent !important;
// transition: transform 0.3s cubic-bezier(0,.13,0,1.43);
}
&--active {
transform: rotate(45deg);
}
}
}
}
}
}
}
/* 左边容器 end */
/* 右边容器 start */
&__right-container {
width: 84%;
height: 100%;
}
&__right {
&__show {
padding: 30rpx;
overflow: hidden;
transform-origin: 0 50%;
// transform: scaleX(0) rotate(-90deg);
// transform: rotateY(-90deg);
// transform: scaleX(0);
// transition: all 0.2s linear;
&--visible {
// transform: scaleX(1) rotate(0deg);
// transform: rotateY(0deg);
// transform: scaleX(1);
}
&--title {
font-size: 46rpx;
text-transform: capitalize;
&--gradient {
-webkit-background-clip: text;
color: transparent;
}
}
&__content {
margin-top: 40rpx;
&__item {
width: 100%;
height: 160rpx;
border-radius: 10rpx;
margin-bottom: 40rpx;
display: flex;
justify-content: flex-start;
align-items: center;
align-content: center;
flex-wrap: wrap;
padding-left: 40rpx;
&--title {
width: 100%;
font-size: 1.4em;
line-height: 1.4em;
color: #FFFFFF;
text-transform: capitalize;
&--light {
color: #080808 !important;
}
}
&--value {
width: 100%;
font-size: 0.8em;
color: #AAAAAA;
&--light {
color: #818181 !important;
}
}
}
}
}
}
/* 右边容器 end */
}
}
/* 背景颜色容器 end */
@-webkit-keyframes circleProgressLoad_right {
0% {
transform: rotate(225deg);
}
100% {
transform: rotate(45deg);
}
}
@-webkit-keyframes circleProgressLoad_left {
0% {
transform: rotate(225deg);
}
100% {
transform: rotate(45deg);
}
}
</style>
+574
View File
@@ -0,0 +1,574 @@
<template>
<view class="basic-flex">
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed>Flex布局</tn-nav-bar>
<!-- 页面内容 -->
<view class="tn-margin-bottom-xl" :style="{paddingTop: vuex_custom_bar_height + 'px'}">
<view class="tn-padding-top">
<view class="tn-margin tn-text-bold tn-text-xl">
固定尺寸 & 元素
</view>
</view>
<view class="tn-margin">
<view class="tn-flex tn-flex-wrap">
<view class="tn-flex-basic-xs tn-padding tn-margin-top-sm tn-radius bg-flex-shadow tn-cool-bg-color-2 tn-shadow-blur">xs(20%)</view>
<view class="tn-flex-basic-md"></view>
<view class="tn-flex-basic-sm tn-padding tn-margin-top-sm tn-radius bg-flex-shadow tn-cool-bg-color-2 tn-shadow-blur">sm(40%)</view>
<view class="tn-flex-basic-md"></view>
<view class="tn-flex-basic-md tn-padding tn-margin-top-sm tn-radius bg-flex-shadow tn-cool-bg-color-2 tn-shadow-blur">md(50%)</view>
<view class="tn-flex-basic-lg tn-padding tn-margin-top-sm tn-radius bg-flex-shadow tn-cool-bg-color-2 tn-shadow-blur">lg(60%)</view>
<view class="tn-flex-basic-xl tn-padding tn-margin-top-sm tn-radius bg-flex-shadow tn-cool-bg-color-2 tn-shadow-blur">xl(80%)</view>
<view class="tn-flex-basic-full tn-padding tn-margin-top-sm tn-radius bg-flex-shadow tn-cool-bg-color-2 tn-shadow-blur">full(100%)</view>
</view>
</view>
<view class="tn-padding-top">
<view class="tn-margin tn-text-bold tn-text-lg">
应用示例1
</view>
</view>
<view class="tn-margin-sm">
<view class="tn-flex tn-flex-wrap">
<view class="tn-flex-basic-md">
<view class="tn-padding-lg tn-margin-xs tn-radius bg-flex-shadow tn-shadow-blur">
</view>
</view>
<view class="tn-flex-basic-md">
<view class="tn-padding-lg tn-margin-xs tn-radius bg-flex-shadow tn-shadow-blur">
</view>
</view>
<view class="tn-flex-basic-xs">
<view class="tn-padding-lg tn-margin-xs tn-radius bg-flex-shadow tn-shadow-blur">
</view>
</view>
<view class="tn-flex-basic-xs">
<view class="tn-padding-lg tn-margin-xs tn-radius bg-flex-shadow tn-shadow-blur">
</view>
</view>
<view class="tn-flex-basic-xs">
<view class="tn-padding-lg tn-margin-xs tn-radius bg-flex-shadow tn-shadow-blur">
</view>
</view>
<view class="tn-flex-basic-xs">
<view class="tn-padding-lg tn-margin-xs tn-radius bg-flex-shadow tn-shadow-blur">
</view>
</view>
<view class="tn-flex-basic-xs">
<view class="tn-padding-lg tn-margin-xs tn-radius bg-flex-shadow tn-shadow-blur">
</view>
</view>
</view>
</view>
<!-- <view class="tn-margin">
<view class="tn-flex tn-flex-wrap">
<view class="tn-flex-basic-xs tn-padding-lg tn-margin-top-sm tn-radius bg-flex-shadow tn-shadow-blur"></view>
<view class="tn-flex-basic-md"></view>
<view class="tn-flex-basic-sm tn-padding-lg tn-margin-top-sm tn-radius bg-flex-shadow tn-shadow-blur"></view>
<view class="tn-flex-basic-md"></view>
<view class="tn-flex-basic-md tn-padding-lg tn-margin-top-sm tn-radius bg-flex-shadow tn-shadow-blur"></view>
<view class="tn-flex-basic-lg tn-padding-lg tn-margin-top-sm tn-radius bg-flex-shadow tn-shadow-blur"></view>
<view class="tn-flex-basic-xl tn-padding-lg tn-margin-top-sm tn-radius bg-flex-shadow tn-shadow-blur"></view>
<view class="tn-flex-basic-full tn-padding-lg tn-margin-top-sm tn-radius bg-flex-shadow tn-shadow-blur"></view>
</view>
</view> -->
<view class="tn-padding-top">
<view class="tn-margin tn-text-bold tn-text-xl">
比例布局 & 元素
</view>
</view>
<view class="tn-margin-sm">
<view class="tn-flex">
<view class="tn-flex-1 tn-padding tn-margin-xs tn-radius bg-flex-shadow tn-cool-bg-color-2 tn-shadow-blur">1</view>
<view class="tn-flex-1 tn-padding tn-margin-xs tn-radius bg-flex-shadow tn-cool-bg-color-2 tn-shadow-blur">1</view>
</view>
<view class="tn-flex">
<view class="tn-flex-1 tn-padding tn-margin-xs tn-radius bg-flex-shadow tn-cool-bg-color-2 tn-shadow-blur">1</view>
<view class="tn-flex-2 tn-padding tn-margin-xs tn-radius bg-flex-shadow tn-cool-bg-color-2 tn-shadow-blur">2</view>
</view>
<view class="tn-flex">
<view class="tn-flex-1 tn-padding tn-margin-xs tn-radius bg-flex-shadow tn-cool-bg-color-2 tn-shadow-blur">1</view>
<view class="tn-flex-2 tn-padding tn-margin-xs tn-radius bg-flex-shadow tn-cool-bg-color-2 tn-shadow-blur">2</view>
<view class="tn-flex-3 tn-padding tn-margin-xs tn-radius bg-flex-shadow tn-cool-bg-color-2 tn-shadow-blur">3</view>
</view>
</view>
<view class="tn-padding-top">
<view class="tn-margin tn-text-bold tn-text-lg">
应用示例1
</view>
</view>
<view class="tn-flex tn-margin-sm">
<view class="tn-flex-1 tn-padding-sm tn-margin-xs tn-radius bg-flex-shadow tn-shadow-blur"></view>
<view class="tn-flex-2">
<view class="tn-padding-xl tn-margin-xs tn-radius bg-flex-shadow tn-shadow-blur">
</view>
<view class="tn-padding-xl tn-margin-left-xs tn-margin-right-xs tn-margin-top-sm tn-margin-bottom-xs tn-radius bg-flex-shadow tn-shadow-blur">
</view>
</view>
</view>
<view class="tn-padding-top">
<view class="tn-margin tn-text-bold tn-text-lg">
应用示例2
</view>
</view>
<view class="tn-flex tn-margin-sm">
<view class="tn-flex-2 tn-padding-sm tn-margin-xs tn-radius bg-flex-shadow tn-shadow-blur"></view>
<view class="tn-flex-2">
<view class="tn-padding-xl tn-margin-xs tn-radius bg-flex-shadow tn-shadow-blur">
</view>
<view class="tn-padding-xl tn-margin-left-xs tn-margin-right-xs tn-margin-top-sm tn-margin-bottom-xs tn-radius bg-flex-shadow tn-shadow-blur">
</view>
</view>
</view>
<view class="tn-padding-top">
<view class="tn-margin tn-text-bold tn-text-lg">
应用示例3
</view>
</view>
<view class="tn-flex tn-margin-sm">
<view class="tn-flex-3 tn-padding-sm tn-margin-xs tn-radius bg-flex-shadow tn-shadow-blur"></view>
<view class="tn-flex-2">
<view class="tn-padding-xl tn-margin-xs tn-radius bg-flex-shadow tn-shadow-blur">
</view>
<view class="tn-padding-xl tn-margin-left-xs tn-margin-right-xs tn-margin-top-sm tn-margin-bottom-xs tn-radius bg-flex-shadow tn-shadow-blur">
</view>
</view>
</view>
<view class="tn-padding-top">
<view class="tn-margin tn-text-bold tn-text-lg">
应用示例4
</view>
</view>
<view class="tn-flex tn-margin-sm">
<view class="tn-flex-2 tn-padding-sm tn-margin-xs tn-radius bg-flex-shadow tn-shadow-blur"></view>
<view class="tn-flex-2 tn-padding-sm tn-margin-xs tn-radius bg-flex-shadow tn-shadow-blur"></view>
<view class="tn-flex-3">
<view class="tn-padding-xl tn-margin-xs tn-radius bg-flex-shadow tn-shadow-blur">
</view>
<view class="tn-padding-xl tn-margin-left-xs tn-margin-right-xs tn-margin-top-sm tn-margin-bottom-xs tn-radius bg-flex-shadow tn-shadow-blur">
</view>
</view>
</view>
<view class="tn-padding-top">
<view class="tn-margin tn-text-bold tn-text-lg">
应用示例5
</view>
</view>
<view class="tn-flex tn-margin-sm">
<view class="tn-flex-1 tn-padding-sm tn-margin-xs tn-radius bg-flex-shadow tn-shadow-blur"></view>
<view class="tn-flex-1 tn-padding-sm tn-margin-xs tn-radius bg-flex-shadow tn-shadow-blur"></view>
<view class="tn-flex-1 tn-padding-sm tn-margin-xs tn-radius bg-flex-shadow tn-shadow-blur"></view>
<view class="tn-flex-2">
<view class="tn-padding-xl tn-margin-xs tn-radius bg-flex-shadow tn-shadow-blur">
</view>
<view class="tn-padding-xl tn-margin-left-xs tn-margin-right-xs tn-margin-top-sm tn-margin-bottom-xs tn-radius bg-flex-shadow tn-shadow-blur">
</view>
</view>
</view>
<view class="tn-padding-top">
<view class="tn-margin tn-text-bold tn-text-lg">
应用示例6
</view>
</view>
<view class="tn-flex tn-margin-sm">
<view class="tn-flex-2">
<view class="tn-padding-xl tn-margin-xs tn-radius bg-flex-shadow tn-shadow-blur">
</view>
<view class="tn-padding-xl tn-margin-left-xs tn-margin-right-xs tn-margin-top-sm tn-margin-bottom-xs tn-radius bg-flex-shadow tn-shadow-blur">
</view>
</view>
<view class="tn-flex-1 tn-padding-sm tn-margin-xs tn-radius bg-flex-shadow tn-shadow-blur"></view>
<view class="tn-flex-1 tn-padding-sm tn-margin-xs tn-radius bg-flex-shadow tn-shadow-blur"></view>
</view>
<view class="tn-padding-top">
<view class="tn-margin tn-text-bold tn-text-lg">
应用示例7
</view>
</view>
<view class="tn-flex tn-margin-sm">
<view class="tn-flex-1">
<view class="tn-padding-xl tn-margin-xs tn-radius bg-flex-shadow tn-shadow-blur">
</view>
<view class="tn-padding-xl tn-margin-left-xs tn-margin-right-xs tn-margin-top-sm tn-margin-bottom-xs tn-radius bg-flex-shadow tn-shadow-blur">
</view>
</view>
<view class="tn-flex-1">
<view class="tn-padding-xl tn-margin-xs tn-radius bg-flex-shadow tn-shadow-blur">
</view>
<view class="tn-padding-xl tn-margin-left-xs tn-margin-right-xs tn-margin-top-sm tn-margin-bottom-xs tn-radius bg-flex-shadow tn-shadow-blur">
</view>
</view>
</view>
<view class="tn-padding-top">
<view class="tn-margin tn-text-bold tn-text-lg">
应用示例8
</view>
</view>
<view class="tn-flex tn-margin-sm">
<view class="tn-flex-3">
<view class="tn-padding-xl tn-margin-xs tn-radius bg-flex-shadow tn-shadow-blur">
</view>
<view class="tn-padding-xl tn-margin-left-xs tn-margin-right-xs tn-margin-top-sm tn-margin-bottom-xs tn-radius bg-flex-shadow tn-shadow-blur">
</view>
</view>
<view class="tn-flex-2">
<view class="tn-padding-xl tn-margin-xs tn-radius bg-flex-shadow tn-shadow-blur">
</view>
<view class="tn-padding-xl tn-margin-left-xs tn-margin-right-xs tn-margin-top-sm tn-margin-bottom-xs tn-radius bg-flex-shadow tn-shadow-blur">
</view>
</view>
</view>
<view class="tn-padding-top">
<view class="tn-margin tn-text-bold tn-text-lg">
应用示例9
</view>
</view>
<view class="tn-flex tn-margin-sm">
<view class="tn-flex-1">
<view class="tn-padding-xl tn-margin-xs tn-radius bg-flex-shadow tn-shadow-blur">
</view>
<view class="tn-padding-xl tn-margin-left-xs tn-margin-right-xs tn-margin-top-sm tn-margin-bottom-xs tn-radius bg-flex-shadow tn-shadow-blur">
</view>
</view>
<view class="tn-flex-1">
<view class="tn-padding-xl tn-margin-xs tn-radius bg-flex-shadow tn-shadow-blur">
</view>
<view class="tn-padding-xl tn-margin-left-xs tn-margin-right-xs tn-margin-top-sm tn-margin-bottom-xs tn-radius bg-flex-shadow tn-shadow-blur">
</view>
</view>
<view class="tn-flex-1 tn-padding-sm tn-margin-xs tn-radius bg-flex-shadow tn-shadow-blur"></view>
</view>
<view class="tn-padding-top">
<view class="tn-margin tn-text-bold tn-text-lg">
应用示例10
</view>
</view>
<view class="tn-flex tn-margin-sm">
<view class="tn-flex-1">
<view class="tn-padding-xl tn-margin-xs tn-radius bg-flex-shadow tn-shadow-blur">
</view>
<view class="tn-padding-xl tn-margin-left-xs tn-margin-right-xs tn-margin-top-sm tn-margin-bottom-xs tn-radius bg-flex-shadow tn-shadow-blur">
</view>
</view>
<view class="tn-flex-2">
<view class="tn-padding-xl tn-margin-xs tn-radius bg-flex-shadow tn-shadow-blur">
</view>
<view class="tn-padding-xl tn-margin-left-xs tn-margin-right-xs tn-margin-top-sm tn-margin-bottom-xs tn-radius bg-flex-shadow tn-shadow-blur">
</view>
</view>
<view class="tn-flex-3 tn-padding-sm tn-margin-xs tn-radius bg-flex-shadow tn-shadow-blur"></view>
</view>
<view class="tn-padding-top">
<view class="tn-margin tn-text-bold tn-text-lg">
应用示例11
</view>
</view>
<view class="tn-flex tn-margin-sm">
<view class="tn-flex-1">
<view class="tn-padding-xl tn-margin-xs tn-radius bg-flex-shadow tn-shadow-blur">
</view>
<view class="tn-padding-xl tn-margin-left-xs tn-margin-right-xs tn-margin-top-sm tn-margin-bottom-xs tn-radius bg-flex-shadow tn-shadow-blur">
</view>
</view>
<view class="tn-flex-1">
<view class="tn-padding-xl tn-margin-xs tn-radius bg-flex-shadow tn-shadow-blur">
</view>
<view class="tn-padding-xl tn-margin-left-xs tn-margin-right-xs tn-margin-top-sm tn-margin-bottom-xs tn-radius bg-flex-shadow tn-shadow-blur">
</view>
</view>
<view class="tn-flex-1">
<view class="tn-padding-xl tn-margin-xs tn-radius bg-flex-shadow tn-shadow-blur">
</view>
<view class="tn-padding-xl tn-margin-left-xs tn-margin-right-xs tn-margin-top-sm tn-margin-bottom-xs tn-radius bg-flex-shadow tn-shadow-blur">
</view>
</view>
</view>
<view class="tn-padding-top">
<view class="tn-margin tn-text-bold tn-text-lg">
应用示例12
</view>
</view>
<view class="tn-flex tn-margin-sm">
<view class="tn-flex-1 tn-padding-sm tn-margin-xs tn-radius bg-flex-shadow tn-shadow-blur"></view>
<view class="tn-flex-3">
<view class="tn-padding-xl tn-margin-xs tn-radius bg-flex-shadow tn-shadow-blur">
</view>
<view class="tn-padding-xl tn-margin-left-xs tn-margin-right-xs tn-margin-top-sm tn-margin-bottom-xs tn-radius bg-flex-shadow tn-shadow-blur">
</view>
</view>
<view class="tn-flex-1">
<view class="tn-padding-xl tn-margin-xs tn-radius bg-flex-shadow tn-shadow-blur">
</view>
<view class="tn-padding-xl tn-margin-left-xs tn-margin-right-xs tn-margin-top-sm tn-margin-bottom-xs tn-radius bg-flex-shadow tn-shadow-blur">
</view>
</view>
</view>
<view class="tn-padding-top">
<view class="tn-margin tn-text-bold tn-text-lg">
应用示例13
</view>
</view>
<view class="tn-flex tn-margin-sm">
<view class="tn-flex-1">
<view class="tn-padding-xl tn-margin-xs tn-radius bg-flex-shadow tn-shadow-blur">
</view>
<view class="tn-padding-xl tn-margin-left-xs tn-margin-right-xs tn-margin-top-sm tn-margin-bottom-xs tn-radius bg-flex-shadow tn-shadow-blur">
</view>
</view>
<view class="tn-flex-3 tn-padding-sm tn-margin-xs tn-radius bg-flex-shadow tn-shadow-blur"></view>
<view class="tn-flex-1">
<view class="tn-padding-xl tn-margin-xs tn-radius bg-flex-shadow tn-shadow-blur">
</view>
<view class="tn-padding-xl tn-margin-left-xs tn-margin-right-xs tn-margin-top-sm tn-margin-bottom-xs tn-radius bg-flex-shadow tn-shadow-blur">
</view>
</view>
</view>
<view class="tn-padding-top">
<view class="tn-margin tn-text-bold tn-text-lg">
应用示例14
</view>
</view>
<view class="tn-flex tn-margin-sm">
<view class="tn-flex-1">
<view class="tn-padding-xl tn-margin-xs tn-radius bg-flex-shadow tn-shadow-blur">
</view>
<view class="tn-padding-xl tn-margin-left-xs tn-margin-right-xs tn-margin-top-sm tn-margin-bottom-xs tn-radius bg-flex-shadow tn-shadow-blur">
</view>
</view>
</view>
<view class="tn-padding-top">
<view class="tn-margin tn-text-bold tn-text-xl">
水平对齐 & justify
</view>
</view>
<view class="tn-margin-sm">
<view class="tn-flex tn-flex-row-left">
<view class="justify-content-item tn-padding tn-text-center tn-margin-xs tn-radius bg-flex-shadow tn-cool-bg-color-2 tn-shadow-blur">start</view>
<view class="justify-content-item tn-padding tn-text-center tn-margin-xs tn-radius bg-flex-shadow tn-cool-bg-color-2 tn-shadow-blur">start</view>
</view>
<view class="tn-flex tn-flex-row-right tn-margin-top-sm">
<view class="justify-content-item tn-padding tn-text-center tn-margin-xs tn-radius bg-flex-shadow tn-cool-bg-color-2 tn-shadow-blur">end</view>
<view class="justify-content-item tn-padding tn-text-center tn-margin-xs tn-radius bg-flex-shadow tn-cool-bg-color-2 tn-shadow-blur">end</view>
</view>
<view class="tn-flex tn-flex-row-center tn-margin-top-sm">
<view class="justify-content-item tn-padding tn-text-center tn-margin-xs tn-radius bg-flex-shadow tn-cool-bg-color-2 tn-shadow-blur">center</view>
<view class="justify-content-item tn-padding tn-text-center tn-margin-xs tn-radius bg-flex-shadow tn-cool-bg-color-2 tn-shadow-blur">center</view>
</view>
<view class="tn-flex tn-flex-row-around tn-margin-top-sm">
<view class="justify-content-item tn-padding tn-text-center tn-margin-xs tn-radius bg-flex-shadow tn-cool-bg-color-2 tn-shadow-blur">around</view>
<view class="justify-content-item tn-padding tn-text-center tn-margin-xs tn-radius bg-flex-shadow tn-cool-bg-color-2 tn-shadow-blur">around</view>
</view>
<view class="tn-flex tn-flex-row-between tn-margin-top-sm">
<view class="justify-content-item tn-padding tn-text-center tn-margin-xs tn-radius bg-flex-shadow tn-cool-bg-color-2 tn-shadow-blur">between</view>
<view class="justify-content-item tn-padding tn-text-center tn-margin-xs tn-radius bg-flex-shadow tn-cool-bg-color-2 tn-shadow-blur">between</view>
</view>
</view>
<view class="tn-padding-top">
<view class="tn-margin tn-text-bold tn-text-lg">
应用示例1
</view>
</view>
<view class="tn-margin">
<view class="tn-flex tn-flex-row-center tn-margin-top-sm">
<view class="justify-content-item tn-padding-xl tn-text-center tn-margin-xs tn-radius bg-flex-shadow tn-shadow-blur"></view>
<view class="justify-content-item tn-padding-xl tn-text-center tn-margin-xs tn-radius bg-flex-shadow tn-shadow-blur"></view>
<view class="justify-content-item tn-padding-xl tn-text-center tn-margin-xs tn-radius bg-flex-shadow tn-shadow-blur"></view>
</view>
</view>
<view class="tn-padding-top">
<view class="tn-margin tn-text-bold tn-text-lg">
应用示例2
</view>
</view>
<view class="tn-margin">
<view class="tn-flex tn-flex-row-center tn-margin-top-sm">
<view class="justify-content-item">
<view class="tn-padding-xl tn-margin-xs tn-radius bg-flex-shadow tn-shadow-blur">
</view>
<view class="tn-padding-xl tn-margin-xs tn-radius bg-flex-shadow tn-shadow-blur" style="margin-top: 20rpx;">
</view>
</view>
<view class="justify-content-item">
<view class="tn-padding-xl tn-margin-xs tn-radius bg-flex-shadow tn-shadow-blur">
</view>
<view class="tn-padding-xl tn-margin-xs tn-radius bg-flex-shadow tn-shadow-blur" style="margin-top: 20rpx;">
</view>
</view>
<view class="justify-content-item">
<view class="tn-padding-xl tn-margin-xs tn-radius bg-flex-shadow tn-shadow-blur">
</view>
<view class="tn-padding-xl tn-margin-xs tn-radius bg-flex-shadow tn-shadow-blur" style="margin-top: 20rpx;">
</view>
</view>
</view>
</view>
<view class="tn-padding-top">
<view class="tn-margin tn-text-bold tn-text-lg">
应用示例3
</view>
</view>
<view class="tn-margin">
<view class="tn-flex tn-flex-row-around tn-margin-top-sm">
<view class="justify-content-item tn-padding-xl tn-text-center tn-margin-xs tn-radius bg-flex-shadow tn-shadow-blur"></view>
<view class="justify-content-item tn-padding-xl tn-text-center tn-margin-xs tn-radius bg-flex-shadow tn-shadow-blur"></view>
<view class="justify-content-item tn-padding-xl tn-text-center tn-margin-xs tn-radius bg-flex-shadow tn-shadow-blur"></view>
</view>
</view>
<view class="tn-padding-top">
<view class="tn-margin tn-text-bold tn-text-lg">
应用示例4
</view>
</view>
<view class="tn-margin">
<view class="tn-flex tn-flex-row-around tn-margin-top-sm">
<view class="justify-content-item">
<view class="tn-padding-xl tn-radius bg-flex-shadow tn-shadow-blur">
</view>
<view class="tn-padding-xl tn-radius bg-flex-shadow tn-shadow-blur" style="margin-top: 20rpx;">
</view>
</view>
<view class="justify-content-item">
<view class="tn-padding-xl tn-radius bg-flex-shadow tn-shadow-blur">
</view>
<view class="tn-padding-xl tn-radius bg-flex-shadow tn-shadow-blur" style="margin-top: 20rpx;">
</view>
</view>
<view class="justify-content-item">
<view class="tn-padding-xl tn-radius bg-flex-shadow tn-shadow-blur">
</view>
<view class="tn-padding-xl tn-radius bg-flex-shadow tn-shadow-blur" style="margin-top: 20rpx;">
</view>
</view>
</view>
</view>
<view class="tn-padding-top">
<view class="tn-margin tn-text-bold tn-text-lg">
应用示例5
</view>
</view>
<view class="tn-margin">
<view class="tn-flex tn-flex-row-between tn-margin-top-sm">
<view class="justify-content-item tn-padding-xl tn-text-center tn-radius bg-flex-shadow tn-shadow-blur"></view>
<view class="justify-content-item tn-padding-xl tn-text-center tn-radius bg-flex-shadow tn-shadow-blur"></view>
<view class="justify-content-item tn-padding-xl tn-text-center tn-radius bg-flex-shadow tn-shadow-blur"></view>
</view>
</view>
<view class="tn-padding-top">
<view class="tn-margin tn-text-bold tn-text-lg">
应用示例6
</view>
</view>
<view class="tn-margin">
<view class="tn-flex tn-flex-row-between tn-margin-top-sm">
<view class="justify-content-item">
<view class="tn-padding-xl tn-radius bg-flex-shadow tn-shadow-blur">
</view>
<view class="tn-padding-xl tn-radius bg-flex-shadow tn-shadow-blur" style="margin-top: 20rpx;">
</view>
</view>
<view class="justify-content-item">
<view class="tn-padding-xl tn-radius bg-flex-shadow tn-shadow-blur">
</view>
<view class="tn-padding-xl tn-radius bg-flex-shadow tn-shadow-blur" style="margin-top: 20rpx;">
</view>
</view>
<view class="justify-content-item">
<view class="tn-padding-xl tn-radius bg-flex-shadow tn-shadow-blur">
</view>
<view class="tn-padding-xl tn-radius bg-flex-shadow tn-shadow-blur" style="margin-top: 20rpx;">
</view>
</view>
</view>
</view>
<view class="tn-padding-top">
<view class="tn-margin tn-text-bold tn-text-xl">
垂直对齐 & align
</view>
</view>
<view class="tn-margin-sm">
<view class="tn-flex tn-flex-col-top">
<view class="align-content-item tn-padding-xl tn-text-center tn-margin-xs tn-radius bg-flex-shadow tn-cool-bg-color-2 tn-shadow-blur">left</view>
<view class="align-content-item tn-padding-sm tn-text-center tn-margin-xs tn-radius bg-flex-shadow tn-cool-bg-color-2 tn-shadow-blur">top</view>
</view>
<view class="tn-flex tn-flex-col-center tn-margin-top-sm">
<view class="align-content-item tn-padding-xl tn-text-center tn-margin-xs tn-radius bg-flex-shadow tn-cool-bg-color-2 tn-shadow-blur">left</view>
<view class="align-content-item tn-padding-sm tn-text-center tn-margin-xs tn-radius bg-flex-shadow tn-cool-bg-color-2 tn-shadow-blur">center</view>
</view>
<view class="tn-flex tn-flex-col-bottom tn-margin-top-sm">
<view class="align-content-item tn-padding-xl tn-text-center tn-margin-xs tn-radius bg-flex-shadow tn-cool-bg-color-2 tn-shadow-blur">left</view>
<view class="align-content-item tn-padding-sm tn-text-center tn-margin-xs tn-radius bg-flex-shadow tn-cool-bg-color-2 tn-shadow-blur">bottom</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
name: 'BasicFlexLayout',
data() {
return {
}
},
methods: {
}
}
</script>
<style lang="scss" scoped>
@import '@/static/css/components/demo_page_common.scss';
/* 内容容器 start */
.bg-flex-shadow{
background-color: #00C3FF;
z-index: 9999;
}
/* 内容容器 end */
</style>
+169
View File
@@ -0,0 +1,169 @@
<template>
<view class="basic-grid">
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed>Grid布局</tn-nav-bar>
<!-- 页面内容 -->
<view :style="{paddingTop: vuex_custom_bar_height + 'px'}">
<dynamic-demo-template ref="demoTemplate" :tips="tips" :sectionList="sectionList" :full="true" @click="click">
<tn-grid v-if="showGrid" :align="align" :hoverClass="hoverClass" :col="col">
<block v-for="(item, index) in icons" :key="index">
<!-- #ifndef MP-WEIXIN -->
<tn-grid-item>
<view class="" style="margin: 60rpx 20rpx;font-size: 70rpx;color: #01BEFF;">
<text class="" :class="['tn-icon-' + item]"></text>
</view>
</tn-grid-item>
<!-- #endif-->
<!-- #ifdef MP-WEIXIN -->
<tn-grid-item :style="{width: gridItemWidth}">
<view class="icon__item--icon tn-cool-color-icon" :class="[$t.colorUtils.getRandomCoolBgClass(index)]">
<view class="tn-margin-top-sm" :class="['tn-icon-' + item]"></view>
</view>
</tn-grid-item>
<!-- #endif-->
</block>
</tn-grid>
</dynamic-demo-template>
</view>
</view>
</template>
<script>
import dynamicDemoTemplate from '@/libs/components/dynamic-demo-template.vue'
export default {
name: 'BasicGridLayout',
components: {dynamicDemoTemplate},
data() {
return {
showGrid: true,
align: 'left',
hoverClass: 'tn-hover',
col: 3,
icons: [
'zodiac-shu',
'zodiac-niu',
'zodiac-hu',
'zodiac-tu',
'zodiac-long',
'zodiac-she',
'zodiac-ma',
'zodiac-yang',
'zodiac-hou',
'zodiac-ji',
'zodiac-gou',
'zodiac-zhu',
'logo-tuniao',
],
tips: ['无需依赖额外的样式文件','使用tn-grid、tn-grid-item组件'],
sectionList: [
{
name: '参数切换',
section: [
{
title: '对齐方式',
optional: ['左对齐','居中','右对齐'],
methods: 'alignChange'
},
{
title: '点击效果',
optional: ['开启','关闭'],
methods: 'hoverChange'
},
{
title: '列数',
optional: ['3','4'],
methods: 'colChange'
}
]
}
]
}
},
computed: {
// 兼容小程序
// #ifdef MP-WEIXIN
gridItemWidth() {
return 100 / this.col + '%'
},
// #endif
},
methods: {
click(event) {
this[event.methods] && this[event.methods](event)
},
// 对齐方式控制
alignChange(event) {
switch(event.index) {
case 0:
this.align = 'left'
break
case 1:
this.align = 'center'
break
case 2:
this.align = 'right'
break
}
},
// 点击效果控制
hoverChange(event) {
this.hoverClass = event.index === 0 ? 'tn-hover' : 'none'
},
// 列数修改
colChange(event) {
this.col = event.index === 0 ? 3 : 4
this.$refs.demoTemplate.updateSectionScrollView()
},
},
}
</script>
<style lang="scss" scoped>
.icon {
&__item {
width: 30%;
background-color: #FFFFFF;
border-radius: 10rpx;
padding: 30rpx;
margin: 20rpx 10rpx;
margin-top: 0;
transform: scale(1);
transition: transform 0.3s linear;
transform-origin: center center;
&--icon {
width: 100rpx;
height: 100rpx;
font-size: 60rpx;
border-radius: 50%;
margin: 30rpx;
position: relative;
z-index: 1;
&::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://tnuiimage.tnkjapp.com/cool_bg_image/icon_bg6.png);
}
}
}
}
</style>
+168
View File
@@ -0,0 +1,168 @@
<template>
<view class="basic-icon">
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed>图标</tn-nav-bar>
<!-- 页面内容 -->
<view :style="{paddingTop: vuex_custom_bar_height + 'px'}">
<tn-sticky :customNavHeight="vuex_custom_bar_height">
<view class="search-content">
<input class="search-content__input" placeholder-class="search-content__input-placeholder" placeholder="请输入图标名称吖" @input="saerchInput" />
</view>
</tn-sticky>
<view class="icon__container tn-flex tn-flex-wrap tn-flex-row-left tn-flex-col-center tn-margin">
<block v-for="(item, index) in resultIconList" :key="index">
<view
class="icon__item tn-flex tn-flex-direction-column tn-flex-row-center tn-flex-col-center icon-shadow"
:class="[{'icon__item--active': index === currentIconIndex}]"
@click="clickIcon(index, item.name)"
>
<view class="icon__item--icon tn-flex tn-flex-row-center tn-flex-col-center tn-shadow-blur">
<view :class="[`tn-icon-${item.name}`]"></view>
</view>
<view class="icon__item--title tn-text-ellipsis">{{ item.name }}</view>
</view>
</block>
</view>
<view class="tn-text-center tn-margin-bottom-xl">
<view>目前300+里面缺少你想要的吗</view>
<view>请前往图鸟语雀留言写下你的需求叭</view>
</view>
<view class="tn-padding-bottom"></view>
</view>
</view>
</template>
<script>
import iconData from './iconfont.js'
export default {
name: 'basicIcon',
data() {
return {
// 图标列表
iconList: iconData.data,
// 用户输入的内容
searchValue: '',
// 当前点击的图标序号
currentIconIndex: -1
}
},
computed: {
resultIconList() {
if (this.searchValue === '') return this.iconList
return this.iconList.filter((item) => {
return item.name.includes(this.searchValue)
})
}
},
methods: {
// input输入的内容
saerchInput(e) {
this.searchValue = e.target.value
},
// 点击图标
clickIcon(index, name) {
this.currentIconIndex = index
this.$t.messageUtils.toast(name, false, null, 'none', 5000)
},
}
}
</script>
<style lang="scss" scoped>
/* 搜索框 start */
.search-content {
padding-top: 16rpx;
margin: 40rpx 40rpx;
&__input {
caret-color: $tn-main-color;
width: 100%;
height: 70rpx;
line-height: 60rpx;
border-radius: 100rpx;
text-align: center;
margin: 0 auto;
background-color: #FFFFFF;
color: #080808;
box-shadow: 0rpx 0rpx 80rpx 0rpx rgba(0, 0, 0, 0.05);
}
&__input-placeholder {
font-size: 24rpx;
}
}
/* 搜索框 end */
/* 图标容器 start */
.icon-shadow{
box-shadow: 0rpx 0rpx 80rpx 0rpx rgba(0, 0, 0, 0.06);
}
.icon {
&__container {
margin-bottom: 30rpx;
}
&__item {
width: 30.4%;
background-color: #FFFFFF;
border-radius: 10rpx;
padding: 30rpx;
margin: 20rpx 10rpx;
margin-top: 0;
transform: scale(1);
transition: transform 0.2s linear;
transform-origin: center center;
&--active {
transform: scale(0.95);
box-shadow:
inset 10rpx 10rpx 18rpx rgba(0, 0, 120, 0.04),
inset -8rpx -8rpx 20rpx rgba(0, 0, 120, 0.03);
}
&--icon {
width: 80rpx;
height: 80rpx;
font-size: 60rpx;
border-radius: 50%;
margin-bottom: 18rpx;
position: relative;
z-index: 1;
&::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://tnuiimage.tnkjapp.com/cool_bg_image/icon_bg.png);
}
}
&--title {
width: 100%;
color: #78909C;
font-size: 28rpx;
text-align: center;
}
}
}
/* 图标容器 end */
</style>
File diff suppressed because one or more lines are too long
+118
View File
@@ -0,0 +1,118 @@
<template>
<view class="basic-shadow">
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed>阴影</tn-nav-bar>
<!-- 页面内容 -->
<view :style="{paddingTop: vuex_custom_bar_height + 'px'}">
<dynamic-demo-template ref="demoTemplate" :tips="tips" :sectionList="sectionList" :full="true" @click="click">
<block v-if="shadowType === 'bg'">
<view
class="shadow-content"
:class="[shadowClass]"
></view>
</block>
<block v-else>
<view
class="shadow-image tn-shadow-blur"
></view>
</block>
<view style="visibility: hidden;height: 1px;">tuniao</view>
</dynamic-demo-template>
</view>
</view>
</template>
<script>
import dynamicDemoTemplate from '@/libs/components/dynamic-demo-template.vue'
export default {
name: 'basicShadow',
components: {dynamicDemoTemplate},
data() {
return {
shadowType: 'bg',
shadowColor: '',
shadowWarp: false,
tips: ['无需依赖额外的样式文件','不使用任何组件'],
sectionList: [
{
name: '参数切换',
section: [
{
title: '样式',
optional: ['背景阴影','图片阴影'],
methods: 'typeChange'
},
{
title: '颜色',
optional: ['默认','自定义'],
methods: 'colorChange'
}
]
}
]
}
},
computed: {
shadowClass() {
let clazz = ''
if (this.shadowType === 'bg') {
if (this.shadowWarp) {
clazz += ` tn-shadow-warp`
} else {
if (this.shadowColor === '') {
clazz += ` tn-shadow`
} else {
clazz += ` ${this.shadowColor}`
}
}
}
return clazz
}
},
methods: {
click(event) {
this[event.methods] && this[event.methods](event)
},
// 切换阴影样式
typeChange(event) {
this.shadowType = event.index === 0 ? 'bg' : 'image'
},
// 切换阴影颜色
colorChange(event) {
this.shadowColor = event.index === 0 ? '' : 'tn-shadow-red'
}
},
}
</script>
<style lang="scss" scoped>
.shadow-content {
width: 80%;
height: 80rpx;
background-color: $tn-font-holder-color;
margin: 0 auto;
}
.shadow-image {
width: 80%;
height: 80rpx;
margin: 0 auto;
z-index: 1;
background-image: url(https://vkceyugu.cdn.bspapp.com/VKCEYUGU-7207d16b-b9c3-4105-8d0d-e9e0c7785f66/605563a1-a210-42f3-99e4-8de3c655c59e.jpg);
background-size: cover;
background-position: top;
background-repeat: no-repeat;
}
</style>
+259
View File
@@ -0,0 +1,259 @@
<template>
<view class="basic-tag">
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed>标签</tn-nav-bar>
<!-- 页面内容 -->
<view :style="{paddingTop: vuex_custom_bar_height + 'px'}">
<dynamic-demo-template ref="demoTemplate" :tips="tips" :sectionList="sectionList" :full="false" @click="click" @modeClick="modeClick">
<block v-if="singleTagFlag">
<tn-tag :backgroundColor="backgroundColor" :fontColor="fontColor" :fontSize="fontSize" :shape="shape"
:width="width" :height="height" :size="size" :padding="padding" :margin="margin" :plain="plain"
:originLeft="originLeft" :originRight="originRight" :class="{'origin-demo':showOriginDemo}">
演示标签
</tn-tag>
</block>
<block v-else>
<!-- #ifdef H5 -->
<view class="capsule">
<tn-tag class="capsule-tag" width="50%" height="100%" padding="0" shape="circleLeft" :plain="false">
<text class="tn-icon-add"></text>
</tn-tag>
<tn-tag class="capsule-tag" width="50%" height="100%" padding="0" shape="circleRight" fontColor="#080808" :plain="true">
2
</tn-tag>
</view>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN -->
<view class="capsule">
<tn-tag class="capsule-tag" width="100%" height="100%" padding="0" shape="circleLeft" :plain="false">
<text class="tn-icon-add"></text>
</tn-tag>
<tn-tag class="capsule-tag" width="100%" height="100%" padding="0" shape="circleRight" fontColor="#080808" :plain="true">
2
</tn-tag>
</view>
<!-- #endif -->
</block>
</dynamic-demo-template>
</view>
</view>
</template>
<script>
import dynamicDemoTemplate from '@/libs/components/dynamic-demo-template.vue'
export default {
name: 'basicTag',
components: {dynamicDemoTemplate},
data() {
return {
backgroundColor: '',
fontColor: '',
fontSize: 0,
shape: '',
width: '',
height: '',
size: '',
padding: '',
margin: '',
plain: false,
originLeft: false,
originRight: false,
// 演示基准点控制
showOriginDemo: false,
// 单双标签切换
singleTagFlag: true,
tips: ['无需依赖额外的样式文件','使用tn-tag组件'],
sectionList: [
{
name: '参数切换',
section: [
{
title: '自定义颜色',
optional: ['默认','自定义'],
methods: 'colorChange'
},
{
title: '自定义大小',
optional: ['默认','自定义'],
methods: 'sizeChange'
},
{
title: '内置大小',
optional: ['默认','sm','lg'],
methods: 'innerSizeChange'
},
{
title: '形状',
optional: ['默认','圆角','椭圆','左半圆','右半圆'],
methods: 'shapeChange'
},
{
title: '镂空',
optional: ['默认','镂空'],
methods: 'plainChange'
},
{
title: '基准点',
optional: ['不设置','左基准','右基准'],
methods: 'originChange'
}
]
},
{
name: '样式切换',
section: [
{
title: '单双标签',
optional: ['单标签','双标签'],
methods: 'singleTagChange'
}
]
}
]
}
},
methods: {
click(event) {
this[event.methods] && this[event.methods](event)
},
modeClick(event) {
if (event.index === 0) {
this.singleTagFlag = true
this.$refs.demoTemplate.updateSectionBtnsValue(1, 0, 0)
}
},
// 切换自定义颜色
colorChange(event) {
if (event.index === 0) {
this.backgroundColor = ''
this.fontColor = ''
} else {
this.backgroundColor = 'tn-bg-red'
this.fontColor = '#FFFFFF'
}
},
// 切换自定义大小
sizeChange(event) {
if (event.index === 0) {
this.width = ''
this.height = ''
this.padding = ''
this.margin = ''
this.fontSize = 0
this.size = ''
this.$refs.demoTemplate.updateSectionBtnsState(2, true)
} else {
this.width = '240rpx'
this.height = '80rpx'
this.padding = '10rpx 20rpx'
this.margin = '10rpx'
this.fontSize = 36
this.$refs.demoTemplate.updateSectionBtnsState(2, false)
}
},
// 切换按钮形状
shapeChange(event) {
switch (event.index) {
case 0:
this.shape = ''
break
case 1:
this.shape = 'radius'
break
case 2:
this.shape = 'circle'
break
case 3:
this.shape = 'circleLeft'
break
case 4:
this.shape = 'circleRight'
break
}
},
// 切换内置大小状态
innerSizeChange(event) {
this.size = event.index === 0 ? '' : event.name
},
// 切换镂空状态
plainChange(event) {
switch(event.index) {
case 0:
this.plain = false
this.fontColor = '#FFFFFF'
break
case 1:
this.plain = true
this.fontColor = 'tn-color-black'
break
}
},
// 切换基准点状态
originChange(event) {
switch (event.index) {
case 0:
this.showOriginDemo = false
this.originLeft = false
this.originRight = false
break
case 1:
this.showOriginDemo = true
this.originLeft = true
this.originRight = false
break
case 2:
this.showOriginDemo = true
this.originLeft = false
this.originRight = true
break
}
},
// 切换单双标签
singleTagChange(event) {
this.singleTagFlag = event.index === 0
},
},
}
</script>
<style lang="scss" scoped>
/* #ifdef H5 */
.origin-demo {
transition: all 0.3s ease;
transform: scale(0.7);
}
/* #endif */
/* #ifdef MP-WEIXIN */
tn-tag {
width: 100%;
display: flex;
align-items: center;
justify-content: center;
}
/* #endif */
</style>
<style lang="scss">
/* #ifdef MP-WEIXIN */
.origin-demo {
.tn-tag-class {
transition: all 0.3s ease;
transform: scale(0.7);
}
}
/* #endif */
</style>
+245
View File
@@ -0,0 +1,245 @@
<template>
<view class="tn-bg-red" style="height: 100vh;">
<view class="tabbar">
<view class="tabbar__bg" :style="wrapStyle"></view>
<view class="tabbar__list">
<block v-for="(item, index) in tabbar" :key="index">
<view :id="`tabbar_item_${index}`" class="tabbar__item" :class="[{'tabbar__item--active': index === currentTabbarIndex}]" @click="changeTabbar(index)">
<view class="tabbar__item__icon" :class="[item.icon]"></view>
<view class="tabbar__item__text">{{ item.name }}</view>
</view>
</block>
</view>
<view class="tabbar__select-active-bg" :class="[showActiceBg ? 'tabbar__select-active-bg--show' : 'tabbar__select-active-bg--hide']" :style="activeBgStyle"></view>
</view>
</view>
</template>
<script>
export default {
name: 'TestPage',
data() {
return {
wrapMaskPositionLeft: 0,
activeBgPositionLeft: 0,
showActiceBg: false,
currentTabbarIndex: 0,
tabbarItemInfo: [],
tabbar: [
{ name: 'home', icon: 'tn-icon-baby' },
{ name: 'home', icon: 'tn-icon-baby' },
{ name: 'home', icon: 'tn-icon-baby' },
{ name: 'home', icon: 'tn-icon-baby' },
{ name: 'home', icon: 'tn-icon-baby' }
]
}
},
computed: {
wrapStyle() {
return {
'-webkit-mask-position': `${this.wrapMaskPositionLeft}px -1px, 100%`
}
},
activeBgStyle() {
return {
'left': `${this.activeBgPositionLeft}px`
}
}
},
onReady() {
this.$nextTick(() => {
this.getTabbarItemInfo()
this.updateHollowsPosition()
this.updateActiveBgPosition(true)
})
},
methods: {
// 获取底部元素的位置
getTabbarItemInfo() {
const view = uni.createSelectorQuery().in(this)
for(let i = 0; i < this.tabbar.length; i++) {
view.select('#tabbar_item_' + i).boundingClientRect()
}
view.exec(res => {
if (!res.length) {
setTimeout(() => {
this.getTabbarItemInfo()
}, 10)
return
}
// 将信息存入数组中
res.map((item) => {
this.tabbarItemInfo.push({
left: item.left,
width: item.width
})
})
console.log(this.tabbarItemInfo)
})
},
// 更新凹陷位置
updateHollowsPosition() {
const { width, left } = this.tabbarItemInfo[this.currentTabbarIndex]
// 计算掩模图片的宽高比
// const imageRatio = 200 / 92
// 计算定高的宽比
const imageFixedHeightWidthRatioValue = 300 * (uni.upx2px(64) / 92)
this.wrapMaskPositionLeft = left - ((imageFixedHeightWidthRatioValue - width) / 2)
console.log(imageFixedHeightWidthRatioValue, this.wrapMaskPositionLeft);
},
// 更新激活时背景的位置
updateActiveBgPosition(init = false) {
const { width, left } = this.tabbarItemInfo[this.currentTabbarIndex]
this.activeBgPositionLeft = left + ((width - uni.upx2px(100)) / 2)
if (!init) {
this.showActiceBg = false
setTimeout(() => {
this.showActiceBg = true
}, 150)
} else {
this.showActiceBg = true
}
},
// 修改当前选中的tabbar
changeTabbar(index) {
this.currentTabbarIndex = index
this.updateHollowsPosition()
this.updateActiveBgPosition()
}
}
}
</script>
<style lang="scss" scoped>
.tabbar {
height: 100%;
height: 110rpx;
position: fixed;
bottom: 0;
left: 0;
right: 0;
background-color: transparent;
&__bg {
position: absolute;
width: 100%;
height: 100%;
bottom: 0;
left: 0;
// background-color: rgba(255, 255, 255, 0.3);
background-color: #FFFFFF;
// , linear-gradient(#000, #000)
-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 61.5'%3E%3Cpath d='M100 0H0c32.9 0 49.3 61.5 100 61.5S167.1 0 200 0H100z'/%3E%3C/svg%3E"), linear-gradient(#000, #000);
// -webkit-mask-size: auto 50px, auto, cover;
-webkit-mask-size: auto 64rpx, cover;
-webkit-mask-repeat: no-repeat;
// -webkit-mask-position: 93.75px -1px, 100%;
-webkit-mask-composite: xor; /*只显示不重合的地方, chorem 、safari 支持*/
// backdrop-filter: blur(5px);
z-index: 1;
transition: 0.5s;
}
&__list {
position: absolute;
z-index: 2;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: space-between;
}
&__item {
height: 100%;
width: 100%;
flex: 1;
text-align: center;
font-size: 28rpx;
position: relative;
&--active {
.tabbar__item__icon {
top: -28rpx;
}
.tabbar__item__text {
opacity: 1;
}
}
&__icon {
font-size: 56rpx;
position: absolute;
left: 0;
right: 0;
top: 10px;
transition: 0.5s;
}
&__text {
position: absolute;
left: 0;
right: 0;
bottom: 10rpx;
transition: 0.5s;
opacity: 0;
}
}
&__select-active-bg {
position: absolute;
width: 100rpx;
height: 100rpx;
border-radius: 50%;
background-color: #FFFFFF;
transition: 0.5s;
z-index: -1;
&--hide {
top: calc(110rpx + 50rpx);
}
&--show {
top: -48rpx;
}
}
}
// .wrap {
// width: 100%;
// height: 100rpx;
// position: fixed;
// bottom: 0;
// left: 0;
// right: 0;
// // background-color: rgba(255, 255, 255, 0.3);
// background-color: #FFFFFF;
// // -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 80 28'%3E%3Cpath d='M13.37 9.37C17.23 20.36 27.7 28.23 40 28.23s22.77-7.87 26.63-18.85C68.62 3.73 74.01 0 80 0H0c5.99 0 11.38 3.73 13.37 9.37z'/%3E%3C/svg%3E"), linear-gradient(red, red);
// // -webkit-mask-size: 140rpx, 100%;
// // -webkit-mask-repeat: no-repeat;
// // -webkit-mask-position: 0 0, 0;
// // -webkit-mask-composite: xor; /*只显示不重合的地方, chorem 、safari 支持*/
// // mask-composite: exclude; /* 排除,只显示不重合的地方, firefox 支持 */
// // backdrop-filter: blur(5px)
// &::before {
// content: '';
// position: absolute;
// width: 100%;
// height: 100%;
// left: 0;
// top: 0;
// box-shadow: 0 -3rpx 8rpx rgba(0, 0, 0, 0.08);
// }
// }
</style>
@@ -0,0 +1,139 @@
<template>
<view class="components-action_sheet">
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed>操作菜单</tn-nav-bar>
<!-- 页面内容 -->
<view :style="{paddingTop: vuex_custom_bar_height + 'px'}">
<dynamic-demo-template ref="demoTemplate" :tips="demoTips" :sectionList="sectionList" :full="false" @click="click">
<tn-button fontColor="tn-color-white" @click="showActionSheet">弹出ActionSheet</tn-button>
</dynamic-demo-template>
</view>
<!-- actionSheet -->
<tn-action-sheet
v-model="show"
:tips="tips"
:list="list"
:borderRadius="borderRadius"
:cancelBtn="cancelBtn"
:maskCloseable="maskCloseable"
@click="clickActionSheetItem"
@close="closedActionSheet"
>
</tn-action-sheet>
</view>
</template>
<script>
import dynamicDemoTemplate from '@/libs/components/dynamic-demo-template.vue'
export default {
name: 'componentsActionSheet',
components: {dynamicDemoTemplate},
data() {
return {
show: false,
tips: {
text: '请选择正确的答案',
fontSize: 26
},
list: [
{
text: 'A'
},
{
text: 'B',
subText: '这是正确答案'
},
{
text: 'C',
disabled: true
},
{
text: 'D'
}
],
borderRadius: 0,
cancelBtn: true,
maskCloseable: true,
demoTips: ['无需依赖额外的样式文件','使用tn-action-sheet组件'],
sectionList: [
{
name: '参数切换',
section: [
{
title: '显示取消按钮',
optional: ['是','否'],
methods: 'cancelBtnChange'
},
{
title: '设置圆角',
optional: ['0','23'],
methods: 'borderRadiusChange'
},
{
title: '点击遮罩关闭',
optional: ['是','否'],
methods: 'maskCloseableChange'
}
]
}
]
}
},
methods: {
click(event) {
this[event.methods] && this[event.methods](event)
},
// 弹出ActionSheet
showActionSheet() {
this.openActionSheet()
},
// 切换圆角
borderRadiusChange(event) {
this.borderRadius = Number(event.name)
this.openActionSheet()
},
// 切换关闭按钮
cancelBtnChange(event) {
this.cancelBtn = event.index === 0 ? true : false
this.openActionSheet()
},
// 切换点击遮罩关闭
maskCloseableChange(event) {
this.maskCloseable = event.index === 0 ? true : false
this.openActionSheet()
},
// 点击了选项
clickActionSheetItem(index) {
if (index === 1) {
this.$t.messageUtils.toast('选择正确')
}
this.closedActionSheet()
},
// 打开actionSheet
openActionSheet() {
this.show = true
},
// 关闭actionSheet
closedActionSheet() {
this.show = false
}
},
}
</script>
<style lang="scss" scoped>
</style>
+213
View File
@@ -0,0 +1,213 @@
<template>
<view class="components-calendar">
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed>Calendar日历</tn-nav-bar>
<!-- 页面内容 -->
<view :style="{paddingTop: vuex_custom_bar_height + 'px'}">
<dynamic-demo-template ref="demoTemplate" :tips="tips" :sectionList="sectionList" :full="false" @click="click">
<view class="tn-flex tn-flex-wrap tn-flex-col-center tn-flex-row-center">
<tn-button style="width: 100%;" width="100%" fontColor="tn-color-white" @click="showCalendar">弹出日历</tn-button>
<view v-if="result !== ''" class="calendar-result tn-border-dashed">
{{ result }}
</view>
</view>
</dynamic-demo-template>
</view>
<!-- Calendar -->
<tn-calendar
v-if="show"
v-model="show"
:mode="mode"
:showLunar="showLunar"
:activeBgColor="activeBgColor"
:activeColor="activeColor"
:rangeBgColor="rangeBgColor"
:rangeColor="rangeColor"
:btnColor="btnColor"
:lunarColor="lunarColor"
:startText="startText"
:endText="endText"
:toolTips="toolTips"
:changeYear="changeYear"
:changeMonth="changeMonth"
@change="onChange"
></tn-calendar>
</view>
</template>
<script>
import dynamicDemoTemplate from '@/libs/components/dynamic-demo-template.vue'
export default {
name: 'componentsCalendar',
components: {dynamicDemoTemplate},
data() {
return {
show: false,
mode: 'date',
showLunar: true,
activeBgColor: '#01BEFF',
activeColor: '#FFFFFF',
rangeBgColor: '#E6E6E655',
rangeColor: '#01BEFF',
btnColor: '#01BEFF',
lunarColor: '#AAAAAA',
startText: '开始',
endText: '结束',
toolTips: '请选择日期',
changeYear: true,
changeMonth: true,
result: '',
tips: ['无需依赖额外的样式文件','使用tn-calendar组件'],
sectionList: [
{
name: '参数切换',
section: [
{
title: '模式',
optional: ['单个日期','日期范围'],
methods: 'modeChange'
},
{
title: '农历显示',
optional: ['显示','隐藏'],
methods: 'showLunarChange'
},
{
title: '自定义颜色',
optional: ['默认','自定义'],
methods: 'colorChange'
},
{
title: '自定义文案',
optional: ['默认','自定义'],
methods: 'textChange'
},
{
title: '年月切换',
optional: ['年月切换','月切换'],
methods: 'yearMonthChange'
}
]
}
]
}
},
methods: {
click(event) {
this[event.methods] && this[event.methods](event)
},
// 弹出日历
showCalendar() {
this.openCalendar()
},
// 切换模式
modeChange(event) {
switch (event.index) {
case 0:
this.mode = 'date'
break
case 1:
this.mode = 'range'
}
this.openCalendar()
},
// 切换农历显示
showLunarChange(event) {
this.showLunar = event.index === 0 ? true : false
this.openCalendar()
},
// 切换颜色
colorChange(event) {
switch (event.index) {
case 0:
this.activeBgColor = '#01BEFF'
this.activeColor = '#FFFFFF'
this.rangeBgColor = '#E6E6E655'
this.rangeColor = '#01BEFF'
this.btnColor = '#01BEFF'
this.lunarColor = '#AAAAAA'
break
case 1:
this.activeBgColor = '#E83A30'
this.activeColor = '#FFFFFF'
this.rangeBgColor = '#E6E6E680'
this.rangeColor = '#E72F8C'
this.btnColor = '#E83A30'
this.lunarColor = '#080808'
break
}
this.openCalendar()
},
// 切换文案
textChange(event) {
switch (event.index) {
case 0:
this.startText = '开始'
this.endText = '结束'
this.toolTips = '请选择日期'
break
case 1:
this.startText = '入住'
this.endText = '离店'
this.toolTips = '入住/离店日期'
break
}
this.openCalendar()
},
// 切换年月
yearMonthChange(event) {
switch (event.index) {
case 0:
this.changeYear = true
this.changeMonth = true
break
case 1:
this.changeYear = false
this.changeMonth = true
break
}
this.openCalendar()
},
// 打开日历
openCalendar() {
this.show = true
},
// 日历日期有改变
onChange(event) {
if (this.mode === 'date') {
this.result = event.date
}
if (this.mode === 'range') {
this.result = `${event.startDate}${event.endDate}`
}
this.$refs.demoTemplate.updateSectionScrollView()
}
},
}
</script>
<style lang="scss" scoped>
.calendar-result {
width: 100%;
margin-top: 20rpx;
padding: 10rpx 30rpx;
background-color: $tn-font-holder-color;
text-align: center;
}
</style>
+194
View File
@@ -0,0 +1,194 @@
<template>
<view class="components-collapse">
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed>Collapse折叠面板</tn-nav-bar>
<!-- 页面内容 -->
<view :style="{paddingTop: vuex_custom_bar_height + 'px'}">
<dynamic-demo-template ref="demoTemplate" :tips="tips" :sectionList="sectionList" :full="true" @click="click">
<tn-collapse v-if="!customCollapse" :accordion="accordion" :headStyle="headStyle" :bodyStyle="bodyStyle" :itemStyle="itemStyle" :arrow="arrow" :arrowColor="arrowColor" :hoverClass="hoverClass" @change="change">
<tn-collapse-item v-for="(item, index) in list" :key="index" :title="item.title" :disabled="item.disabled" :align="align">
<view class="collapse-item-content">
{{ item.content }}
</view>
</tn-collapse-item>
</tn-collapse>
<tn-collapse v-else :accordion="accordion" :headStyle="headStyle" :bodyStyle="bodyStyle" :itemStyle="itemStyle" :arrow="arrow" :arrowColor="arrowColor" :hoverClass="hoverClass" @change="change">
<tn-collapse-item title="足迹" :align="align">
<tn-list-cell>广州</tn-list-cell>
<tn-list-cell>深圳</tn-list-cell>
<tn-list-cell>佛山</tn-list-cell>
</tn-collapse-item>
<tn-collapse-item title="时间">
<tn-list-cell>12</tn-list-cell>
<tn-list-cell>11</tn-list-cell>
<tn-list-cell>10</tn-list-cell>
</tn-collapse-item>
</tn-collapse>
</dynamic-demo-template>
</view>
</view>
</template>
<script>
import dynamicDemoTemplate from '@/libs/components/dynamic-demo-template.vue'
export default {
name: 'componentsCollapse',
components: {dynamicDemoTemplate},
data() {
return {
list: [
{
title: '关雎',
content: '关关雎鸠,在河之洲。窈窕淑女,君子好逑。参差荇菜,左右流之。窈窕淑女,寤寐求之。求之不得,寤寐思服。悠哉悠哉,辗转反侧。参差荇菜,左右采之。窈窕淑女,琴瑟友之。参差荇菜,左右芼之。窈窕淑女,钟鼓乐之。',
disabled: false
},
{
title: '长歌行',
content: '青青园中葵,朝露待日晞。阳春布德泽,万物生光辉。常恐秋节至,焜黄华叶衰。百川东到海,何时复西归?少壮不努力,老大徒伤悲!',
disabled: false
},
{
title: '秋风辞',
content: '秋风起兮白云飞,草木黄落兮雁南归。兰有秀兮菊有芳,怀佳人兮不能忘。泛楼船兮济汾河,横中流兮扬素波。少壮几时兮奈老何!',
disabled: false
}
],
accordion: true,
headStyle: {},
bodyStyle: {},
itemStyle: {},
arrow: true,
arrowColor: '#AAAAAA',
hoverClass: 'tn-hover',
align: 'left',
customCollapse: false,
tips: ['无需依赖额外的样式文件','使用tn-collapse、tn-collapse-item组件'],
sectionList: [
{
name: '参数切换',
section: [
{
title: '手风琴模式',
optional: ['开启','关闭'],
methods: 'accoraionChange'
},
{
title: '禁用打开',
optional: ['无','禁止第二项打开'],
methods: 'disabledChange'
},
{
title: '点击效果',
optional: ['默认','无'],
methods: 'hoverClassChange'
},
{
title: '箭头显示',
optional: ['显示','隐藏'],
methods: 'arrowChange'
},
{
title: '自定义样式',
optional: ['默认','自定义'],
methods: 'styleChange'
},
{
title: '自定义Item内容',
optional: ['默认','自定义'],
methods: 'customItemChange'
}
]
}
]
}
},
methods: {
click(event) {
this[event.methods] && this[event.methods](event)
},
// 切换手风琴模式
accoraionChange(event) {
this.accordion = event.index === 0 ? true : false
},
// 切换Item禁止打开
disabledChange(event) {
if (event.index === 0) {
this.list[1].disabled = false
} else {
this.list[1].disabled = true
}
},
// 切换点击效果
hoverClassChange(event) {
this.hoverClass = event.index === 0 ? 'tn-hover' : ''
},
// 切换箭头显示
arrowChange(event) {
this.arrow = event.index === 0 ? true : false
},
// 切换自定义样式
styleChange(event) {
switch (event.index) {
case 0:
this.headStyle = {}
this.bodyStyle = {}
this.itemStyle = {}
this.arrowColor = '#AAAAAA'
this.align = 'left'
break
case 1:
this.headStyle = {
borderBottom: '1rpx solid #AAAAAA'
}
this.bodyStyle = {
margin: '10rpx'
}
this.itemStyle = {
'text-indent': '2em'
}
this.arrowColor = '#E6E6E6'
this.align = 'center'
break
}
},
// 切换自定义item内容
customItemChange(event) {
switch (event.index) {
case 0:
this.customCollapse = false
this.$refs.demoTemplate.updateSectionBtnsState(1, true)
break
case 1:
this.customCollapse = true
this.$refs.demoTemplate.updateSectionBtnsState(1, false)
break
}
},
// 面板发生了改变
change() {
setTimeout(() => {
this.$refs.demoTemplate.updateSectionScrollView()
}, 300)
}
},
}
</script>
<style lang="scss" scoped>
.collapse-item-content {
word-wrap: break-word;
}
</style>
+168
View File
@@ -0,0 +1,168 @@
<template>
<view class="components-count_down">
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed>countdown倒计时</tn-nav-bar>
<!-- 页面内容 -->
<view :style="{paddingTop: vuex_custom_bar_height + 'px'}">
<dynamic-demo-template ref="demoTemplate" :tips="tips" :sectionList="sectionList" :full="false" @click="click">
<tn-count-down
:timestamp="timestamp"
:backgroundColor="backgroundColor"
:fontColor="fontColor"
:fontSize="fontSize"
:separator="separator"
:separatorColor="separatorColor"
:separatorSize="separatorSize"
:showBorder="showBorder"
:borderColor="borderColor"
:showDays="showDays"
:showHours="showHours"
:showMinutes="showMinutes"
:showSeconds="showSeconds"
:hideZeroDay="hideZeroDay"
@end="countDownEnd"
></tn-count-down>
</dynamic-demo-template>
</view>
</view>
</template>
<script>
import dynamicDemoTemplate from '@/libs/components/dynamic-demo-template.vue'
export default {
name: 'componentsCountDown',
components: {dynamicDemoTemplate},
data() {
return {
timestamp: 3600,
backgroundColor: '#FFFFFF',
fontSize: 30,
fontColor: '#080808',
separator: 'en',
separatorSize: 30,
separatorColor: '#080808',
showBorder: true,
borderColor: '#080808',
showDays: true,
showHours: true,
showMinutes: true,
showSeconds: true,
hideZeroDay: false,
tips: ['无需依赖额外的样式文件','使用tn-count-down组件'],
sectionList: [
{
name: '参数切换',
section: [
{
title: '时间',
optional: ['360', '3600', '543000'],
methods: 'timestampChange',
current: 1
},
{
title: '大小',
optional: ['24', '30', '45'],
methods: 'sizeChange',
current: 1
},
{
title: '边框显示',
optional: ['显示','隐藏'],
methods: 'borderChange'
},
{
title: '分隔符',
optional: ['冒号','中文'],
methods: 'separatorChange'
},
{
title: '自定义颜色',
optional: ['默认','自定义'],
methods: 'customColorChange'
},
{
title: '自定义格式',
optional: ['日时分秒','时分秒'],
methods: 'customFormatChange'
}
]
}
]
}
},
methods: {
click(event) {
this[event.methods] && this[event.methods](event)
},
// 切换时间
timestampChange(event) {
this.timestamp = Number(event.name)
},
// 切换边框显示
borderChange(event) {
this.showBorder = event.index === 0 ? true : false
},
// 切换分隔符
separatorChange(event) {
this.separator = event.index === 0 ? 'en' : 'cn'
},
// 切换大小
sizeChange(event) {
this.fontSize = Number(event.name)
this.separatorSize = Number(event.name)
},
// 切换自定义颜色
customColorChange(event) {
switch(event.index) {
case 0:
this.backgroundColor = '#FFFFFF'
this.separatorColor = '#080808'
this.fontColor = '#080808'
this.borderColor = '#080808'
break
case 1:
this.backgroundColor = '#E6E6E6'
this.separatorColor = '#01BEFF'
this.fontColor = '#3D7EFF'
this.borderColor = '#31C9E8'
break
}
},
// 切换自定义格式
customFormatChange(event) {
switch(event.index) {
case 0:
this.showDays = true
this.showHours = true
this.showMinutes = true
this.showSeconds = true
break
case 1:
this.showDays = false
this.showHours = true
this.showMinutes = true
this.showSeconds = true
break
}
},
// 倒计时结束
countDownEnd() {
this.$t.messageUtils.toast('倒计时结束')
}
},
}
</script>
<style lang="scss" scoped>
</style>
@@ -0,0 +1,110 @@
<template>
<view class="components-count_scroll">
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed>countScroll数字滚动</tn-nav-bar>
<!-- 页面内容 -->
<view :style="{paddingTop: vuex_custom_bar_height + 'px'}">
<dynamic-demo-template ref="demoTemplate" :tips="tips" :sectionList="sectionList" :full="false" @click="click">
<tn-count-scroll
:value="value"
:height="height"
:fontColor="fontColor"
:fontSize="fontSize"
:bold="bold"
:duration="duration"
></tn-count-scroll>
</dynamic-demo-template>
</view>
</view>
</template>
<script>
import dynamicDemoTemplate from '@/libs/components/dynamic-demo-template.vue'
export default {
name: 'componentsCountTo',
components: {dynamicDemoTemplate},
data() {
return {
value: 888.88,
height: 32,
fontColor: '#080808',
fontSize: 32,
bold: false,
duration: 1.2,
tips: ['无需依赖额外的样式文件','使用tn-count-scroll组件'],
sectionList: [
{
name: '参数切换',
section: [
{
title: '值',
optional: ['90','1234','888.88'],
methods: 'valueChange',
current: 2
},
{
title: '持续时间',
optional: ['默认','0.5', '3'],
methods: 'durationChange'
},
{
title: '加粗',
optional: ['默认','加粗'],
methods: 'boldChange'
},
{
title: '自定义样式',
optional: ['默认','自定义'],
methods: 'customStyleChange'
}
]
}
]
}
},
methods: {
click(event) {
this[event.methods] && this[event.methods](event)
},
// 切换值
valueChange(event) {
this.value = Number(event.name)
},
// 切换持续时间
durationChange(event) {
this.duration = event.index === 0 ? 1.2 : Number(event.name)
},
// 切换加粗
boldChange(event) {
this.bold = event.index === 0 ? false : true
},
// 切换自定义样式
customStyleChange(event) {
switch(event.index) {
case 0:
this.height = 32
this.fontColor = '#080808'
this.fontSize = 32
break
case 1:
this.height = 80
this.fontColor = '#E88C30'
this.fontSize = 80
break
}
},
},
}
</script>
<style lang="scss" scoped>
</style>
+110
View File
@@ -0,0 +1,110 @@
<template>
<view class="components-count_to">
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed>countTo数字跳转</tn-nav-bar>
<!-- 页面内容 -->
<view :style="{paddingTop: vuex_custom_bar_height + 'px'}">
<dynamic-demo-template ref="demoTemplate" :tips="tips" :sectionList="sectionList" :full="false" @click="click">
<tn-count-to
:startVal="startVal"
:endVal="endVal"
:fontColor="fontColor"
:fontSize="fontSize"
:decimals="decimals"
:bold="bold"
></tn-count-to>
</dynamic-demo-template>
</view>
</view>
</template>
<script>
import dynamicDemoTemplate from '@/libs/components/dynamic-demo-template.vue'
export default {
name: 'componentsCountTo',
components: {dynamicDemoTemplate},
data() {
return {
fontColor: '#080808',
fontSize: 50,
startVal: 0,
endVal: 1000,
duration: 2000,
decimals: 0,
bold: false,
tips: ['无需依赖额外的样式文件','使用tn-count-to组件'],
sectionList: [
{
name: '参数切换',
section: [
{
title: '滚动范围',
optional: ['0-1000','100-2500'],
methods: 'valChange'
},
{
title: '小数显示位数',
optional: ['不显示','1','2'],
methods: 'decimalsChange'
},
{
title: '加粗',
optional: ['默认','加粗'],
methods: 'boldChange'
},
{
title: '自定义样式',
optional: ['默认','自定义'],
methods: 'customStyleChange'
}
]
}
]
}
},
methods: {
click(event) {
this[event.methods] && this[event.methods](event)
},
// 切换开始结束值
valChange(event) {
const value = event.name.split('-')
this.startVal = Number(value[0])
this.endVal = Number(value[1])
},
// 切换小数显示
decimalsChange(event) {
this.decimals = event.index === 0 ? 0 : Number(event.name)
},
// 切换加粗
boldChange(event) {
this.bold = event.index === 0 ? false : true
},
// 切换自定义样式
customStyleChange(event) {
switch(event.index) {
case 0:
this.fontColor = '#080808'
this.fontSize = 50
break
case 1:
this.fontColor = '#A4E82F'
this.fontSize = 100
break
}
},
},
}
</script>
<style lang="scss" scoped>
</style>
+523
View File
@@ -0,0 +1,523 @@
<template>
<view class="components-form">
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed>Form表单</tn-nav-bar>
<!-- 页面内容 -->
<view :style="{paddingTop: vuex_custom_bar_height + 'px'}">
<dynamic-demo-template ref="demoTemplate" :tips="tips" :sectionList="sectionList" :full="true" :fullWindowsScroll="true" @click="click">
<tn-form :model="model" ref="form" :errorType="errorType" :labelPosition="labelPosition" :labelWidth="labelWidth" :labelAlign="labelAlign">
<tn-form-item label="姓名" prop="name" leftIcon="identity" :required="true" :labelPosition="labelPosition" :labelAlign="labelAlign">
<tn-input v-model="model.name" type="text" placeholder="请输入姓名" :border="border"></tn-input>
</tn-form-item>
<tn-form-item label="性别" prop="sex" :labelPosition="labelPosition" :labelAlign="labelAlign">
<tn-input v-model="model.sex" type="select" placeholder="请选择性别" :border="border" :selectOpen="actionSheetShow" @click="actionSheetShow = true"></tn-input>
</tn-form-item>
<tn-form-item label="手机号码" prop="phone" rightIcon="phone" :labelPosition="labelPosition" :labelAlign="labelAlign">
<tn-input v-model="model.phone" type="number" placeholder="请输入手机号码" :border="border"></tn-input>
</tn-form-item>
<tn-form-item label="介绍" prop="desc" :labelPosition="labelPosition" :labelAlign="labelAlign">
<tn-input v-model="model.desc" type="textarea" placeholder="请输入介绍" :border="border" inputAlign="center"></tn-input>
</tn-form-item>
<tn-form-item label="密码" prop="password" :labelPosition="labelPosition" :labelAlign="labelAlign">
<tn-input v-model="model.password" type="password" placeholder="请输入密码" :border="border" :passwordIcon="true"></tn-input>
</tn-form-item>
<tn-form-item label="确认密码" prop="rePassword" :labelPosition="labelPosition" :labelAlign="labelAlign">
<tn-input v-model="model.rePassword" type="password" placeholder="请再次输入密码" :border="border"></tn-input>
</tn-form-item>
<tn-form-item label="水果" prop="fruit" :labelPosition="labelPosition" :labelAlign="labelAlign">
<tn-checkbox-group v-model="model.fruit" :width="checkboxWidth" :wrap="checkboxWrap" @change="checkboxGroupChange">
<tn-checkbox v-for="(item, index) in checkboxList" :key="index" v-model="item.check" :name="item.name" :disabled="item.disabled">{{ item.name }}</tn-checkbox>
</tn-checkbox-group>
</tn-form-item>
<tn-form-item label="支付方式" prop="payType" :labelPosition="labelPosition" :labelAlign="labelAlign">
<tn-radio-group v-model="model.payType" :width="radioWidth" :wrap="radioWrap" @change="radioGroupChange">
<tn-radio v-for="(item, index) in radioList" :key="index" :name="item.name" :disabled="item.disabled">{{ item.name }}</tn-radio>
</tn-radio-group>
</tn-form-item>
<tn-form-item label="所在地区" prop="region" :labelPosition="labelPosition" :labelAlign="labelAlign">
<tn-input v-model="model.region" type="select" placeholder="请选择所在地区" :border="border" :selectOpen="pickerShow" @click="pickerShow = true"></tn-input>
</tn-form-item>
<tn-form-item label="商品类型" prop="goodsType" :labelPosition="labelPosition" :labelAlign="labelAlign">
<tn-input v-model="model.goodsType" type="select" placeholder="请选择商品类型" :border="border" :selectOpen="selectShow" @click="selectShow = true"></tn-input>
</tn-form-item>
<tn-form-item label="验证码" prop="code" :labelPosition="labelPosition" :labelAlign="labelAlign">
<tn-input v-model="model.code" type="text" placeholder="请输入验证码" :border="border"></tn-input>
<tn-button slot="right" size="sm" backgroundColor="tn-bg-green" fontColor="tn-color-white" @click="getCode">{{ codeTips }}</tn-button>
</tn-form-item>
<tn-form-item label="记住密码" prop="remember" :labelPosition="labelPosition" :labelAlign="labelAlign">
<tn-switch v-model="model.remember" slot="right"></tn-switch>
</tn-form-item>
<tn-form-item label="上传图片" prop="photo" :labelPosition="labelPosition" :labelAlign="labelAlign">
<tn-image-upload :fileList="model.photo" @on-list-change="imageUploadChange"></tn-image-upload>
</tn-form-item>
</tn-form>
<view class="agreement">
<tn-checkbox v-model="model.agreement" @change="agreementCheckChange"></tn-checkbox>
<view class="agreement-text">勾选同意当前协议</view>
</view>
<tn-button width="100%" @click="submit">提交</tn-button>
</dynamic-demo-template>
<!-- 性别选项 -->
<tn-action-sheet
v-model="actionSheetShow"
:list="actionSheetList"
@click="actionSheetClick"
></tn-action-sheet>
<!-- 地区picker -->
<tn-picker
v-model="pickerShow"
mode="region"
@confirm="regionPickerConfirm"
></tn-picker>
<!-- 商品类型select -->
<tn-select
v-model="selectShow"
mode="single"
:list="selectList"
@confirm="goodsTypeSelectConfirm"
></tn-select>
<!-- 验证码倒计时 -->
<tn-verification-code
ref="code"
:seconds="60"
@change="codeChange"
></tn-verification-code>
</view>
</view>
</template>
<script>
import dynamicDemoTemplate from '@/libs/components/dynamic-demo-template.vue'
export default {
name: 'componentsForm',
components: {dynamicDemoTemplate},
data() {
return {
errorType: ['message','border-bottom','toast'],
labelPosition: 'left',
labelAlign: 'right',
border: false,
actionSheetShow: false,
labelWidth: 140,
checkboxWidth: 'auto',
checkboxWrap: false,
radioWidth: 'auto',
radioWrap: false,
pickerShow: false,
selectShow: false,
codeTips: '获取验证码',
checkboxList:[
{
name: '苹果',
disabled: false
},
{
name: '橘子',
disabled: false
},
{
name: '香蕉',
disabled: false
},
{
name: '榴莲',
disabled: true
}
],
radioList:[
{
name: '微信',
disabled: false
},
{
name: '支付宝',
disabled: true
},
{
name: '云闪付',
disabled: false
}
],
actionSheetList:[
{
text: '男'
},
{
text: '女'
},
{
text: '保密'
}
],
selectList: [
{
label: '手机',
value: 1101
},
{
label: '笔记本',
value: 1102
},
{
label: '手表',
value: 1103
}
],
model: {
name: '',
sex: '',
phone: '',
desc: '',
password: '',
rePassword: '',
fruit: ['橘子'],
payType: '微信',
region: '',
goodsType: '',
code: '',
remember: false,
photo: [],
agreement: false
},
rules: {
name: [
{
required: true,
message: '请输入用户名',
trigger: 'blur'
},
{
min: 3,
max: 5,
message: '姓名长度在3到5个字符',
trigger: ['change','blur'],
},
{
// 此为同步验证,可以直接返回true或者false,如果是异步验证,稍微不同,见下方说明
validator: (rule, value, callback) => {
return this.$t.test.chinese(value);
},
message: '姓名必须为中文',
// 触发器可以同时用blur和change,二者之间用英文逗号隔开
trigger: ['change','blur'],
},
{
// 异步验证需要通过调用callback(),并且在里面抛出new Error()
// 抛出的内容为需要提示的信息,和其他方式的message属性的提示一样
asyncValidator: (rule, value, callback) => {
if (value === '图鸟') {
callback(new Error('姓名重复'));
} else {
// 没有错误,也要执行callback()回调
callback();
}
},
trigger: ['blur'],
}
],
sex: [
{
required: true,
message: '请选择性别',
trigger: 'change'
}
],
phone: [
{
required: true,
message: '请输入手机号码',
trigger: 'change'
}
],
desc: [
{
min: 5,
message: '简介不能少于5个字',
trigger: 'change'
},
{
// 正则表达式验证演示
pattern: /^[\u4e00-\u9fa5]+$/gi,
message: '简介只能包含中文',
trigger: 'change'
}
],
password: [
{
required: true,
message: '请输入密码',
trigger: ['change','blur']
},
{
pattern: /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]+\S{5,12}$/,
message: '需同时含有字母和数字,长度在6-12之间',
trigger: ['change','blur']
}
],
rePassword: [
{
required: true,
message: '请再次输入密码',
trigger: ['change','blur']
},
{
validator: (rule, value, callback) => {
return value === this.model.password;
},
message: '两次输入的密码不相等',
trigger: ['change','blur'],
}
],
fruit: [
{
required: true,
message: '请选择水果',
trigger: 'change',
type: 'array'
}
],
payType: [
{
required: true,
message: '请选择支付方式',
trigger: 'change'
}
],
region: [
{
required: true,
message: '所在地区不能为空',
trigger: 'change'
}
],
goodsType: [
{
required: true,
message: '商品类型不能为空',
trigger: 'change'
}
],
code: [
{
required: true,
message: '验证码不能为空',
trigger: 'change'
}
],
remember: [
{
required: true,
message: '记住密码不能为空',
trigger: 'change'
}
],
photo: [
{
required: true,
message: '请选择图片',
trigger: 'change',
type: 'array'
}
],
},
tips: ['无需依赖额外的样式文件','使用tn-toast组件'],
sectionList: [
{
name: '参数切换',
section: [
{
title: 'label显示位置',
optional: ['左边','上边'],
methods: 'labelPositionChange'
},
{
title: 'label对齐方式',
optional: ['左对齐','右对齐','居中'],
methods: 'labelAlignChange',
current: 1
},
{
title: '边框显示',
optional: ['显示','隐藏'],
methods: 'borderChange',
current: 1
},
{
title: '可选项排列方式',
optional: ['默认','宽度的50%','换行'],
methods: 'checkRadioStyleChange'
},
{
title: '错误提示方式',
optional: ['message','toast','下划线','输入框'],
methods: 'errorTypeChange'
}
]
}
]
}
},
onReady() {
this.$refs.form.setRules(this.rules)
},
methods: {
click(event) {
this[event.methods] && this[event.methods](event)
},
// 切换label显示位置
labelPositionChange(event) {
switch (event.index) {
case 0:
this.labelPosition = 'left'
break
case 1:
this.labelPosition = 'top'
break
}
},
// 切换label对其方式
labelAlignChange(event) {
switch (event.index) {
case 0:
this.labelAlign = 'left'
break
case 1:
this.labelAlign = 'right'
break
case 2:
this.labelAlign = 'center'
break
}
},
// 切换边框显示
borderChange(event) {
this.border = event.index === 0 ? true : false
},
// 切换可选项样式
checkRadioStyleChange(event) {
switch (event.index) {
case 0:
this.checkboxWidth = 'auto'
this.checkboxWrap = false
this.radioWidth = 'auto'
this.radioWrap = false
break
case 1:
this.checkboxWidth = '50%'
this.checkboxWrap = false
this.radioWidth = '50%'
this.radioWrap = false
break
case 2:
this.checkboxWidth = 'auto'
this.checkboxWrap = true
this.radioWidth = 'auto'
this.radioWrap = true
break
}
},
// 切换错误提示方式
errorTypeChange(event) {
switch (event.index) {
case 0:
this.errorType = ['message']
break
case 1:
this.errorType = ['toast']
break
case 2:
this.errorType = ['border-bottom']
break
case 3:
this.errorType = ['border']
break
}
},
// 表单提交
submit() {
this.$refs.form.validate(valid => {
if (valid) {
// 验证通过
if (!this.model.agreement) {
this.$t.messageUtils.toast('请勾选协议')
return
}
} else {
// 验证失败
}
})
},
// 点击actionSheet选择性别
actionSheetClick(index) {
uni.hideKeyboard()
this.model.sex = this.actionSheetList[index].text
},
// 点击地区选择器
regionPickerConfirm(event) {
this.model.region = event.province.label + '-' + event.city.label + '-' + event.area.label
},
// 点击商品类型列选择器
goodsTypeSelectConfirm(event) {
this.model.goodsType = `${event[0]['label']}`
},
// 多选项值改变事件
checkboxGroupChange(event) {
this.model.fruit = event
},
// 单选项值改变事件
radioGroupChange(event) {
this.model.payType = event
},
// 获取验证码
getCode() {
if (this.$refs.code.canGetCode) {
this.$t.messageUtils.loading('正在获取验证码')
setTimeout(() => {
this.$t.messageUtils.closeLoading()
this.$t.messageUtils.toast('验证码已经发送')
// 通知组件开始计时
this.$refs.code.start()
}, 2000)
} else {
this.$t.messageUtils.toast(this.$refs.code.secNum + '秒后再重试')
}
},
// 验证码倒计时时间改变
codeChange(text) {
this.codeTips = text
},
// 图片有修改
imageUploadChange(lists) {
this.model.photo = lists
},
// 同意协议状态修改
agreementCheckChange(event) {
this.model.agreement = event.value
}
}
}
</script>
<style lang="scss" scoped>
.agreement {
display: flex;
align-items: center;
margin: 40rpx 0;
&-text {
padding-left: 8rpx;
color: $tn-font-sub-color;
}
}
</style>
@@ -0,0 +1,273 @@
<template>
<view class="components-image_upload">
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed>图片上传</tn-nav-bar>
<!-- 页面内容 -->
<view :style="{paddingTop: vuex_custom_bar_height + 'px'}">
<dynamic-demo-template ref="demoTemplate" :tips="tips" :sectionList="sectionList" :full="true" :fullWindowsScroll="fullWindowsScroll" @click="click">
<tn-image-upload
ref="imageUpload"
:action="action"
:formData="formData"
:fileList="fileList"
:disabled="disabled"
:autoUpload="autoUpload"
:maxCount="maxCount"
:showUploadList="showUploadList"
:showProgress="showProgress"
:deleteable="deleteable"
:customBtn="customBtn"
:beforeUpload="beforeUpload"
@on-list-change="listChange"
@on-oversize="oversize"
@on-exceed="exceed"
@on-choose-complete="chooseComplete"
@on-choose-fail="chooseFail"
@on-uploaded="uploaded"
@on-success="uploadSuccess"
@on-change="uploadChange"
@on-progress="uploadProgress"
@on-error="uploadError"
@on-remove="fileRemove"
>
<view v-if="!showUploadList" slot="file" style="width: 100%;">
<view v-for="(item,index) in lists" :key="index" class="tn-image-upload__item">
<image
class="tn-image-upload__item__image"
:src="item.url || item.path"
mode="aspectFill"
></image>
</view>
</view>
<!-- <template v-if="!showUploadList" v-slot:file="data">
<view v-for="(item,index) in data.file" :key="index" class="tn-image-upload__item">
<image
class="tn-image-upload__item__image"
:src="item.url || item.path"
mode="aspectFill"
></image>
</view>
</template> -->
<view v-if="customBtn" slot="addBtn" class="tn-image-upload__custom-btn" hover-class="tn-hover-class" hover-stay-time="150">
<view>选择图片</view>
</view>
</tn-image-upload>
<view class="tn-flex tn-margin-top-xs tn-flex-row-center">
<tn-button fontColor="tn-color-white" @tap="upload">上传</tn-button>
<tn-button fontColor="tn-color-white" backgroundColor="tn-bg-red" margin="0rpx 0rpx 0rpx 20rpx" @tap="clear">清空列表</tn-button>
</view>
</dynamic-demo-template>
</view>
</view>
</template>
<script>
import dynamicDemoTemplate from '@/libs/components/dynamic-demo-template.vue'
export default {
components: {dynamicDemoTemplate},
data() {
return {
action: 'https://www.hualigs.cn/api/upload',
// action: '',
formData: {
apiType: 'this,ali',
token: 'dffc1e06e636cff0fdf7d877b6ae6a2e',
image: null
},
// 预上传列表
// [{
// url: 'http://127.0.0.1:8888/upload/tuniao.jpg'
// }]
fileList: [],
showUploadList: true,
customBtn: false,
autoUpload: true,
showProgress: true,
deleteable: true,
customStyle: false,
maxCount: 9,
disabled: false,
lists: [],
tips: ['无需依赖额外的样式文件','使用tn-image-upload组件'],
sectionList: [
{
name: '参数切换',
section: [
{
title: '上传方式',
optional: ['自动上传','手动上传'],
methods: 'autoUploadChange'
},
{
title: '进度显示',
optional: ['是','否'],
methods: 'showProgressChange'
},
{
title: '删除按钮显示',
optional: ['是','否'],
methods: 'deleteableChange'
},
{
title: '最大上传数',
optional: ['2','6','9'],
methods: 'maxCountChange',
current: 2
},
{
title: '自定义列表和上传按钮样式',
optional: ['是','否'],
methods: 'customUploadListChange',
current: 1
},
{
title: '是否禁用',
optional: ['是','否'],
methods: 'disabledChange',
current: 1
}
]
}
],
fullWindowsScroll: false
}
},
methods: {
click(event) {
this[event.methods] && this[event.methods](event)
},
// 切换上传方式
autoUploadChange(event) {
this.autoUpload = event.index === 0 ? true : false
},
// 切换进度显示
showProgressChange(event) {
this.showProgress = event.index === 0 ? true : false
},
// 切换删除按钮显示
deleteableChange(event) {
this.deleteable = event.index === 0 ? true : false
},
// 切换允许上传数
maxCountChange(event) {
this.maxCount = Number(event.name)
},
// 切换自定义列表样式
customUploadListChange(event) {
if (event.index === 0) {
this.customStyle = true
this.showUploadList = false
this.customBtn = true
} else if (event.index === 1) {
this.customStyle = false
this.showUploadList = true
this.customBtn = false
}
this.$refs.demoTemplate.updateSectionScrollView()
},
// 切换禁用
disabledChange(event) {
this.disabled = event.index === 0 ? true : false
this.$refs.demoTemplate.updateSectionScrollView()
},
// 手动上传文件
upload() {
this.$refs.imageUpload.upload()
},
// 手动清空列表
clear() {
this.$refs.imageUpload.clear()
},
// 文件上传前执行
beforeUpload(index, lists) {
console.log('文件上传前执行', lists, index);
console.log(this.formData);
this.formData.image = lists[index].file
return true
},
listChange(lists, index) {
console.log('上传文件列表发生改变', lists, index);
this.lists.splice(0, this.lists.length)
this.$nextTick(() => {
this.lists = this.$t.deepClone(lists)
if (this.customStyle && lists.length > 4) {
this.fullWindowsScroll = true
} else {
this.$refs.demoTemplate.updateSectionScrollView()
}
})
},
oversize(val, lists, index) {
console.log('上传的文件超过大小', val, lists, index);
},
exceed(val, lists, index) {
console.log('上传的文件超过允许数量', val, lists, index);
},
chooseComplete(lists, index) {
console.log('文件选择成功', lists, index);
},
chooseFail(err) {
console.log('文件选择失败', err);
},
uploaded(lists, index) {
console.log('全部上传文件处理完成', lists, index);
},
uploadSuccess(data, currentIndex, lists, index) {
console.log('文件上传成功', data, currentIndex, lists, index);
},
uploadChange(res, currentIndex, lists, index) {
console.log('文件上传信息有变', res, currentIndex, lists, index);
},
uploadProgress(res, currentIndex, lists, index) {
console.log('文件上传进度', res, currentIndex, lists, index);
},
uploadError(err, currentIndex, lists, index) {
console.log('文件上传失败', err, currentIndex, lists, index);
},
fileRemove(currentIndex, lists, index) {
console.log('文件移除成功', currentIndex, lists, index);
},
},
}
</script>
<style lang="scss" scoped>
.tn-image-upload__item {
width: 100%;
height: 180rpx;
border-radius: 30rpx;
margin-bottom: 20rpx;
&__image {
width: 100%;
height: 180rpx;
border-radius: 30rpx;
}
}
.tn-image-upload__custom-btn {
background-color: $tn-font-holder-color;
width: 100%;
height: 180rpx;
display: flex;
align-items: center;
justify-content: center;
border-radius: 30rpx;
}
</style>
+91
View File
@@ -0,0 +1,91 @@
<template>
<view class="components-index-list">
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed>IndexList索引列表</tn-nav-bar>
<!-- 页面内容 -->
<view :style="{paddingTop: vuex_custom_bar_height + 'px'}">
<tn-index-list :scrollTop="scrollTop" :indexList="indexList" :customBarHeight="vuex_custom_bar_height" :stickyTop="vuex_custom_bar_height">
<view v-for="(item, index) in list" :key="index">
<tn-index-anchor :index="item.letter"></tn-index-anchor>
<view v-for="(data_item,data_index) in item.data" :key="data_index" class="index-list-item tn-border-solid-bottom">
{{ data_item.name }}
</view>
</view>
</tn-index-list>
</view>
</view>
</template>
<script>
import indexList from '../mock/index.list.js'
const letterArr = indexList.list.map(val => {
return val.letter
})
export default {
name: 'componentsIndexList',
data() {
return {
// 滚动的距离
scrollTop: 0,
scrollTopArr: [0, 0],
selectIndexScrollTop: [0 ,0],
// 索引列表
indexList: letterArr,
list: indexList.list
}
},
onPageScroll(e) {
this.scrollTop = e.scrollTop
},
methods: {
onScroll(e, index) {
// this.scrollTop = e.detail.scrollTop
this.$set(this.scrollTopArr, index - 1, e.detail.scrollTop)
},
// 侧边栏索引选中事件
indexListSelect(e, index) {
this.$set(this.selectIndexScrollTop, index - 1, e.scrollTop)
}
}
}
</script>
<style lang="scss" scoped>
.index-list-item {
display: flex;
box-sizing: border-box;
width: 100%;
padding: 20rpx 24rpx;
overflow: hidden;
color: $tn-font-color;
font-size: 28rpx;
line-height: 48rpx;
background-color: #FFFFFF;
}
.index-list-image-item {
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
overflow: hidden;
color: $tn-font-color;
font-size: 28rpx;
&__image {
width: 100rpx;
height: 100rpx;
margin: 8rpx 8rpx;
margin-right: 10rpx;
}
}
</style>
+324
View File
@@ -0,0 +1,324 @@
<template>
<view class="components-keyboard">
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed>keyboard键盘</tn-nav-bar>
<!-- 页面内容 -->
<view :style="{paddingTop: vuex_custom_bar_height + 'px'}">
<dynamic-demo-template ref="demoTemplate" :tips="tips" :sectionList="sectionList" :full="true" @click="click">
<view v-if="mode === 'number' || mode === 'card'" class="number-value">
<tn-input v-model="inputValue" type="text" :disabled="true" :border="true" placeholder="键盘输入的内容" @click="showKeyboard"></tn-input>
<tn-button class="clear-btn" backgroundColor="tn-bg-gray" fontColor="white" width="120rpx" height="70rpx" @click="clearInputValue">清空</tn-button>
</view>
<view v-else class="car-value">
<block v-for="(item, index) in 8" :key="index">
<view
class="car-input"
:class="{'new-energy': index === 7 && !licensePlateValue[index]}"
@tap="chooseLicensePlateNumber(index)"
>
<block v-if="index === 7 && !licensePlateValue[index]">
<view class="new-energy-car">
<view class="icon tn-icon-add"></view>
<view class="text">新能源</view>
</view>
</block>
<block v-else>
{{ licensePlateValue[index] || '' }}
</block>
</view>
<view class="car-point" v-if="index === 1">
<view class="point"></view>
</view>
</block>
</view>
</dynamic-demo-template>
</view>
<!-- 键盘 -->
<tn-keyboard
v-model="value"
:mode="mode"
:dotEnabled="dotEnabled"
:randomEnabled="randomEnabled"
:switchEnMode="switchEnMode"
:tooltip="tooltip"
:mask="mask"
@change="onChange"
@cancel="onCancel"
@confirm="onConfirm"
@backspace="onBackspace"
></tn-keyboard>
</view>
</template>
<script>
import dynamicDemoTemplate from '@/libs/components/dynamic-demo-template.vue'
export default {
name: 'componentsKeyboard',
components: {dynamicDemoTemplate},
data() {
return {
value: false,
mode: 'number',
dotEnabled: true,
randomEnabled: false,
switchEnMode: false,
tooltip: true,
mask: true,
// 输入的值
inputValue: '',
// 输入的车牌
licensePlateValue: ['','','','','','','',''],
// 当前选择输入的车牌号码位置
currentLicensePlateIndex: 0,
tips: ['无需依赖额外的样式文件','使用tn-keyboard组件'],
sectionList: [
{
name: '参数切换',
section: [
{
title: '模式',
optional: ['数字','身份证','车牌'],
methods: 'modeChange'
},
{
title: '显示点',
optional: ['显示','隐藏'],
methods: 'dotEnabledChange'
},
{
title: '打乱顺序',
optional: ['是','否'],
methods: 'randomEnabledChange',
current: 1
},
{
title: '显示顶部工具栏',
optional: ['显示','隐藏'],
methods: 'tooltipChange'
},
{
title: '遮罩显示',
optional: ['是','否'],
methods: 'maskChange'
}
]
}
]
}
},
watch: {
mode(value) {
switch (value) {
case 'number':
this.$refs.demoTemplate.updateSectionBtnsValue(0, 0, 0)
break
case 'card':
this.$refs.demoTemplate.updateSectionBtnsValue(0, 0, 1)
break
case 'car':
this.$refs.demoTemplate.updateSectionBtnsValue(0, 0, 2)
break
}
},
currentLicensePlateIndex(value) {
if (value === 0) {
this.switchEnMode = false
} else {
this.switchEnMode = true
}
}
},
methods: {
click(event) {
this[event.methods] && this[event.methods](event)
},
// 弹出键盘
showKeyboard() {
this.value = true
},
// 切换模式
modeChange(event) {
switch (event.index) {
case 0:
this.mode = 'number'
this.dotEnabled = true
this.value = true
this.$refs.demoTemplate.updateSectionBtnsState(1, true)
break
case 1:
this.mode = 'card'
this.value = true
this.$refs.demoTemplate.updateSectionBtnsState(1, false)
break
case 2:
this.mode = 'car'
this.licensePlateValue = ['','','','','','','','']
this.$refs.demoTemplate.updateSectionBtnsState(1, false)
break
}
},
// 切换点显示
dotEnabledChange(event) {
this.dotEnabled = event.index === 0 ? true : false
this.value = true
},
// 切换乱序显示
randomEnabledChange(event) {
this.randomEnabled = event.index === 0 ? true : false
this.value = true
},
// 切换顶部工具栏显示
tooltipChange(event) {
this.tooltip = event.index === 0 ? true : false
this.value = true
},
// 切换遮罩状态
maskChange(event) {
this.mask = event.index === 0 ? true : false
this.value = true
},
// 键盘输入值改变
onChange(e) {
if (this.mode === 'number' || this.mode === 'card') {
this.inputValue += e
} else if (this.mode === 'car') {
// 判断输入的值是否正确
if (this.currentLicensePlateIndex === 0 && !this.$t.test.chinese(e)) {
this.$t.messageUtils.toast('车牌归属地选择错误')
return
} else if (this.currentLicensePlateIndex === 1 && !this.$t.test.letter(e)) {
this.$t.messageUtils.toast('车牌归属地字母选择错误')
return
}
if (this.currentLicensePlateIndex !== 0 && !this.$t.test.enOrNum(e)) {
this.$t.messageUtils.toast('车牌号码选择错误')
return
}
// this.licensePlateValue[this.currentLicensePlateIndex] = e
this.$set(this.licensePlateValue, this.currentLicensePlateIndex, e)
this.currentLicensePlateIndex++
// 判断车牌是否已经选择完成
if (this.currentLicensePlateIndex === 8) {
this.value = false
}
}
},
// 点击了取消按钮
onCancel() {
this.$t.messageUtils.toast('点击了取消按钮')
},
// 点击了确认按钮
onConfirm() {
this.$t.messageUtils.toast('点击了确认按钮')
this.value = false
},
// 点击了退格按钮
onBackspace() {
if (this.mode === 'number' || this.mode === 'card') {
if (!this.inputValue) {
return
}
this.inputValue = this.inputValue.substring(0, this.inputValue.length - 1)
} else if (this.mode === 'car') {
let licensePlateIndex = this.currentLicensePlateIndex > 7 ? 7 : this.currentLicensePlateIndex
if (this.licensePlateValue[licensePlateIndex] !== '') {
this.$set(this.licensePlateValue, licensePlateIndex, '')
} else {
licensePlateIndex = licensePlateIndex < 1 ? 0 : --licensePlateIndex
this.$set(this.licensePlateValue, licensePlateIndex, '')
}
this.currentLicensePlateIndex = licensePlateIndex
}
},
// 点击车牌对于位置进行选择输入
chooseLicensePlateNumber(index) {
this.currentLicensePlateIndex = index
this.mode = 'car'
this.value = true
},
// 清空内容
clearInputValue() {
this.inputValue = ''
}
},
}
</script>
<style lang="scss" scoped>
.number-value {
display: flex;
align-items: center;
.clear-btn {
margin-left: 10rpx;
}
}
.car-value {
display: flex;
.car-input {
position: relative;
display: flex;
align-items: center;
justify-content: center;
height: 74rpx;
width: 64rpx;
border: 1px solid $tn-border-solid-color;
border-radius: 18rpx;
text-align: center;
font-size: 38rpx;
line-height: 1;
margin-left: 10rpx;
background-color: #FFFFFF;
&.new-energy {
background: transparent;
border-style: dashed;
}
}
.car-point {
display: flex;
align-items: center;
justify-content: center;
height: 74rpx;
width: 20rpx;
margin-left: 10rpx;
.point {
width: 20rpx;
height: 20rpx;
background-color: $tn-font-holder-color;
border-radius: 50%;
}
}
.new-energy-car {
display: flex;
flex-direction: column;
font-size: 16rpx;
color: $tn-font-sub-color;
.icon {
margin-bottom: 8rpx;
}
}
}
</style>
+306
View File
@@ -0,0 +1,306 @@
<template>
<view class="components-list">
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed>列表</tn-nav-bar>
<!-- 页面内容 -->
<view :style="{paddingTop: vuex_custom_bar_height + 'px'}">
<dynamic-demo-template ref="demoTemplate" :tips="tips" :sectionList="sectionList" :full="true" @click="click">
<tn-list-view
:backgroundColor="viewBackgroundColor"
:fontColor="viewFontColor"
:fontSize="viewFontSize"
:title="viewTitle"
:unlined="viewUnlined"
:card="viewCard"
:marginTop="viewMarginTop"
>
<block v-if="viewCustomTitle">
<view slot="title" class="list-title-container">
<tn-button class="list-title-button">设置</tn-button>
</view>
</block>
<block v-for="(item, index) in 3" :key="index">
<tn-list-cell
:backgroundColor="cellBackgroundColor"
:fontColor="cellFontColor"
:fontSize="cellFontSize"
:arrow="cellArrow"
:arrowRight="cellArrowRight"
:hover="cellHover"
:radius="cellRadius"
:unlined="cellUnlined"
:lineLeft="cellLineLeft"
:lineRight="cellLineRight"
>选项 {{ index }}</tn-list-cell>
</block>
</tn-list-view>
</dynamic-demo-template>
</view>
</view>
</template>
<script>
import dynamicDemoTemplate from '@/libs/components/dynamic-demo-template.vue'
export default {
name: 'componentsList',
components: {dynamicDemoTemplate},
data() {
return {
viewBackgroundColor: '',
viewFontColor: '',
viewFontSize: 0,
viewTitle: '',
viewCustomTitle: false,
viewCard: false,
viewMarginTop: '',
viewUnlined: 'all',
cellBackgroundColor: '',
cellFontColor: '',
cellFontSize: 0,
cellArrow: true,
cellArrowRight: true,
cellRadius: false,
cellUnlined: false,
cellLineLeft: true,
cellLineRight: true,
cellHover: false,
tips: ['无需依赖额外的样式文件','使用tn-list-view、tn-list-cell组件'],
sectionList: [
{
name: '容器参数',
section: [
{
title: '自定义颜色',
optional: ['默认','自定义'],
methods: 'viewColorChange'
},
{
title: '自定义大小',
optional: ['默认','自定义'],
methods: 'viewSizeChange'
},
{
title: '标题类型',
optional: ['空白','文字标题','自定义标题'],
methods: 'viewTitleChange'
},
{
title: '容器类型',
optional: ['默认','卡片'],
methods: 'viewContainerChange'
},
{
title: '边框类型',
optional: ['全部显示','上边框','下边框','不显示'],
methods: 'viewBoardChange',
current: 3
}
]
},
{
name: '列表参数',
section: [
{
title: '自定义颜色',
optional: ['默认','自定义'],
methods: 'cellColorChange'
},
{
title: '自定义大小',
optional: ['默认','自定义'],
methods: 'cellSizeChange'
},
{
title: '显示类型',
optional: ['默认','圆角'],
methods: 'cellRadiusChange'
},
{
title: '箭头',
optional: ['隐藏','显示'],
methods: 'cellArrowChange',
current: 1
},
{
title: '箭头边距',
optional: ['默认','无边距'],
methods: 'cellArrowRightChange'
},
{
title: '显示底边',
optional: ['显示','隐藏'],
methods: 'cellUnlinedChange',
},
{
title: '底边边距',
optional: ['默认','无边距'],
methods: 'cellLineChange',
},
{
title: '点击效果',
optional: ['无','有'],
methods: 'cellHoverChange',
}
]
}
]
}
},
methods: {
click(event) {
this[event.methods] && this[event.methods](event)
},
// 切换容器颜色
viewColorChange(event) {
if (event.index === 0) {
this.viewBackgroundColor = ''
this.viewFontColor = ''
} else {
this.viewBackgroundColor = '#F8F7F8'
this.viewFontColor = 'tn-color-grey'
}
},
// 切换容器大小
viewSizeChange(event) {
if (event.index === 0) {
this.viewFontSize = 0
this.viewMarginTop = ''
} else {
this.viewFontSize = 32
this.viewMarginTop = '48rpx'
}
this.$refs.demoTemplate.updateSectionScrollView()
},
// 切换容器标题
viewTitleChange(event) {
switch(event.index) {
case 0:
this.viewTitle = ''
this.viewCustomTitle = false
break
case 1:
this.viewTitle = '请选择对应的选项'
this.viewCustomTitle = false
break
case 2:
this.viewTitle = ''
this.viewCustomTitle = true
break
}
this.$refs.demoTemplate.updateSectionScrollView()
},
// 切换容器类型
viewContainerChange(event) {
this.viewCard = event.index === 0 ? false : true
this.$refs.demoTemplate.updateSectionScrollView()
},
// 切换容器边框类型
viewBoardChange(event) {
switch(event.index) {
case 0:
this.viewUnlined = ''
break
case 1:
this.viewUnlined = 'bottom'
break
case 2:
this.viewUnlined = 'top'
break
case 3:
this.viewUnlined = 'all'
break
}
},
// 切换列表颜色
cellColorChange(event) {
if (event.index === 0) {
this.cellBackgroundColor = ''
this.cellFontColor = ''
} else {
this.cellBackgroundColor = '#D6F4FA'
this.cellFontColor = 'tn-color-grey'
}
},
// 切换列表大小
cellSizeChange(event) {
if (event.index === 0) {
this.cellFontSize = 0
} else {
this.cellFontSize = 36
}
this.$refs.demoTemplate.updateSectionScrollView()
},
// 切换列表圆角
cellRadiusChange(event) {
this.cellRadius = event.index === 0 ? false : true
},
// 切换列表箭头显示
cellArrowChange(event) {
if (event.index === 0) {
this.cellArrow = false
this.$refs.demoTemplate.updateSectionBtnsState(4, false)
} else {
this.cellArrow = true
this.$refs.demoTemplate.updateSectionBtnsState(4, true)
}
},
// 切换列表箭头贴边
cellArrowRightChange(event) {
this.cellArrowRight = event.index === 0 ? true : false
},
// 切换列表底边显示
cellUnlinedChange(event) {
if (event.index === 0) {
this.cellUnlined = false
this.$refs.demoTemplate.updateSectionBtnsState(6, true)
} else {
this.cellUnlined = true
this.$refs.demoTemplate.updateSectionBtnsState(6, false)
}
},
// 切换列表底边的边距
cellLineChange(event) {
if (event.index === 0) {
this.cellLineLeft = true
this.cellLineRight = true
} else if (event.index === 1) {
this.cellLineLeft = false
this.cellLineRight = false
}
},
// 切换列表点击效果
cellHoverChange(event) {
this.cellHover = event.index === 0 ? false : true
},
},
}
</script>
<style lang="scss" scoped>
.list-title-container {
display: flex;
justify-content: flex-end;
padding: 10rpx;
.list-title-button {
width: 160rpx !important;
height: 46rpx !important;
color: #FFFFFF;
margin: 10rpx !important;
}
}
</style>
+105
View File
@@ -0,0 +1,105 @@
<template>
<view class="components-loading">
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed>Loading加载动画</tn-nav-bar>
<!-- 页面内容 -->
<view :style="{paddingTop: vuex_custom_bar_height + 'px'}">
<dynamic-demo-template ref="demoTemplate" :tips="tips" :sectionList="sectionList" :full="false" @click="click">
<tn-loading
:show="show"
:mode="mode"
:color="color"
:size="size"
></tn-loading>
</dynamic-demo-template>
</view>
</view>
</template>
<script>
import dynamicDemoTemplate from '@/libs/components/dynamic-demo-template.vue'
export default {
name: 'componentsLoading',
components: {dynamicDemoTemplate},
data() {
return {
show: true,
mode: 'circle',
color: '',
size: 34,
tips: ['无需依赖额外的样式文件','使用tn-loading组件'],
sectionList: [
{
name: '参数切换',
section: [
{
title: '显示',
optional: ['显示','隐藏'],
methods: 'showChange'
},
{
title: '模式',
optional: ['圆圈','花朵'],
methods: 'modeChange'
},
{
title: '颜色',
optional: ['默认','#31E749','#31C9E8'],
methods: 'colorChange'
},
{
title: '尺寸',
optional: ['28','34','54'],
methods: 'sizeChange',
current: 1
}
]
}
]
}
},
methods: {
click(event) {
this[event.methods] && this[event.methods](event)
},
// 切换是否显示
showChange(event) {
this.show = event.index === 0 ? true : false
},
// 切换模式
modeChange(event) {
switch (event.index) {
case 0:
this.mode = 'circle'
this.$refs.demoTemplate.updateSectionBtnsState(2, true)
break
case 1:
this.mode = 'flower'
this.$refs.demoTemplate.updateSectionBtnsState(2, false)
break
}
},
// 切换颜色
colorChange(event) {
this.color = event.index === 0 ? '' : event.name
},
// 切换尺寸
sizeChange(event) {
this.size = Number(event.name)
},
},
}
</script>
<style lang="scss" scoped>
</style>
+585
View File
@@ -0,0 +1,585 @@
module.exports = {
list: [{
"letter": "A",
"data": [{
"name": "阿拉斯加",
"mobile": "13588889999",
"keyword": "阿拉斯加ABA13588889999"
},
{
"name": "阿克苏",
"mobile": "0551-4386721",
"keyword": "阿克苏AKESU0551-4386721"
},
{
"name": "阿拉善",
"mobile": "4008009100",
"keyword": "阿拉善ALASHAN4008009100"
},
{
"name": "阿勒泰",
"mobile": "13588889999",
"keyword": "阿勒泰ALETAI13588889999"
},
{
"name": "阿里",
"mobile": "13588889999",
"keyword": "阿里ALI13588889999"
},
{
"name": "安阳",
"mobile": "13588889999",
"keyword": "13588889999安阳ANYANG"
}
]
},
{
"letter": "B",
"data": [{
"name": "白城",
"mobile": "该主子没有留电话~",
"keyword": "白城BAICHENG"
},
{
"name": "白山",
"mobile": "13588889999",
"keyword": "白山BAISHAN13588889999"
},
{
"name": "白银",
"mobile": "13588889999",
"keyword": "白银BAIYIN13588889999"
},
{
"name": "保定",
"mobile": "13588889999",
"keyword": "保定BAODING13588889999"
}
]
},
{
"letter": "C",
"data": [{
"name": "沧州",
"mobile": "13588889999",
"keyword": "沧州CANGZHOU13588889999"
},
{
"name": "长春",
"mobile": "13588889999",
"keyword": "长春CHANGCHUN13588889999"
}
]
},
{
"letter": "D",
"data": [{
"name": "大理",
"mobile": "13588889999",
"keyword": "大理DALI13588889999"
},
{
"name": "大连",
"mobile": "13588889999",
"keyword": "大连DALIAN13588889999"
}
]
},
{
"letter": "E",
"data": [{
"name": "鄂尔多斯",
"mobile": "13588889999",
"keyword": "鄂尔多斯EERDUOSI13588889999"
},
{
"name": "恩施",
"mobile": "13588889999",
"keyword": "恩施ENSHI13588889999"
},
{
"name": "鄂州",
"mobile": "13588889999",
"keyword": "鄂州EZHOU13588889999"
}
]
},
{
"letter": "F",
"data": [{
"name": "防城港",
"mobile": "该主子没有留电话~",
"keyword": "防城港FANGCHENGGANG"
},
{
"name": "抚顺",
"mobile": "13588889999",
"keyword": "抚顺FUSHUN13588889999"
},
{
"name": "阜新",
"mobile": "13588889999",
"keyword": "阜新FUXIN13588889999"
},
{
"name": "阜阳",
"mobile": "13588889999",
"keyword": "阜阳FUYANG13588889999"
},
{
"name": "抚州",
"mobile": "13588889999",
"keyword": "抚州FUZHOU13588889999"
},
{
"name": "福州",
"mobile": "13588889999",
"keyword": "福州FUZHOU13588889999"
}
]
},
{
"letter": "G",
"data": [{
"name": "甘南",
"mobile": "13588889999",
"keyword": "甘南GANNAN13588889999"
},
{
"name": "赣州",
"mobile": "13588889999",
"keyword": "赣州GANZHOU13588889999"
},
{
"name": "甘孜",
"mobile": "13588889999",
"keyword": "甘孜GANZI13588889999"
}
]
},
{
"letter": "H",
"data": [{
"name": "哈尔滨",
"mobile": "13588889999",
"keyword": "哈尔滨HAERBIN13588889999"
},
{
"name": "海北",
"mobile": "13588889999",
"keyword": "海北HAIBEI13588889999"
},
{
"name": "海东",
"mobile": "13588889999",
"keyword": "海东HAIDONG13588889999"
},
{
"name": "海口",
"mobile": "13588889999",
"keyword": "海口HAIKOU13588889999"
}
]
},
{
"letter": "I",
"data": [{
"name": "ice",
"mobile": "13588889999",
"keyword": "佳木斯JIAMUSI13588889999"
}]
},
{
"letter": "J",
"data": [{
"name": "佳木斯",
"mobile": "13588889999",
"keyword": "佳木斯JIAMUSI13588889999"
},
{
"name": "吉安",
"mobile": "13588889999",
"keyword": "吉安JIAN13588889999"
},
{
"name": "江门",
"mobile": "13588889999",
"keyword": "江门JIANGMEN13588889999"
}
]
},
{
"letter": "K",
"data": [{
"name": "开封",
"mobile": "13588889999",
"keyword": "开封KAIFENG13588889999"
},
{
"name": "喀什",
"mobile": "13588889999",
"keyword": "喀什KASHI13588889999"
},
{
"name": "克拉玛依",
"mobile": "13588889999",
"keyword": "克拉玛依KELAMAYI13588889999"
}
]
},
{
"letter": "L",
"data": [{
"name": "来宾",
"mobile": "13588889999",
"keyword": "来宾LAIBIN13588889999"
},
{
"name": "兰州",
"mobile": "13588889999",
"keyword": "兰州LANZHOU13588889999"
},
{
"name": "拉萨",
"mobile": "13588889999",
"keyword": "拉萨LASA13588889999"
},
{
"name": "乐山",
"mobile": "13588889999",
"keyword": "乐山LESHAN13588889999"
},
{
"name": "凉山",
"mobile": "13588889999",
"keyword": "凉山LIANGSHAN13588889999"
},
{
"name": "连云港",
"mobile": "13588889999",
"keyword": "连云港LIANYUNGANG13588889999"
},
{
"name": "聊城",
"mobile": "18322223333",
"keyword": "聊城LIAOCHENG18322223333"
},
{
"name": "辽阳",
"mobile": "18322223333",
"keyword": "辽阳LIAOYANG18322223333"
},
{
"name": "辽源",
"mobile": "18322223333",
"keyword": "辽源LIAOYUAN18322223333"
},
{
"name": "丽江",
"mobile": "18322223333",
"keyword": "丽江LIJIANG18322223333"
},
{
"name": "临沧",
"mobile": "18322223333",
"keyword": "临沧LINCANG18322223333"
},
{
"name": "临汾",
"mobile": "18322223333",
"keyword": "临汾LINFEN18322223333"
},
{
"name": "临夏",
"mobile": "18322223333",
"keyword": "临夏LINXIA18322223333"
},
{
"name": "临沂",
"mobile": "18322223333",
"keyword": "临沂LINYI18322223333"
},
{
"name": "林芝",
"mobile": "18322223333",
"keyword": "林芝LINZHI18322223333"
},
{
"name": "丽水",
"mobile": "18322223333",
"keyword": "丽水LISHUI18322223333"
}
]
},
{
"letter": "M",
"data": [{
"name": "眉山",
"mobile": "15544448888",
"keyword": "眉山MEISHAN15544448888"
},
{
"name": "梅州",
"mobile": "15544448888",
"keyword": "梅州MEIZHOU15544448888"
},
{
"name": "绵阳",
"mobile": "15544448888",
"keyword": "绵阳MIANYANG15544448888"
},
{
"name": "牡丹江",
"mobile": "15544448888",
"keyword": "牡丹江MUDANJIANG15544448888"
}
]
},
{
"letter": "N",
"data": [{
"name": "南昌",
"mobile": "15544448888",
"keyword": "南昌NANCHANG15544448888"
},
{
"name": "南充",
"mobile": "15544448888",
"keyword": "南充NANCHONG15544448888"
},
{
"name": "南京",
"mobile": "15544448888",
"keyword": "南京NANJING15544448888"
},
{
"name": "南宁",
"mobile": "15544448888",
"keyword": "南宁NANNING15544448888"
},
{
"name": "南平",
"mobile": "15544448888",
"keyword": "南平NANPING15544448888"
}
]
},
{
"letter": "O",
"data": [{
"name": "欧阳",
"mobile": "15544448888",
"keyword": "欧阳ouyang15544448888"
}]
},
{
"letter": "P",
"data": [{
"name": "盘锦",
"mobile": "15544448888",
"keyword": "盘锦PANJIN15544448888"
},
{
"name": "攀枝花",
"mobile": "15544448888",
"keyword": "攀枝花PANZHIHUA15544448888"
},
{
"name": "平顶山",
"mobile": "15544448888",
"keyword": "平顶山PINGDINGSHAN15544448888"
},
{
"name": "平凉",
"mobile": "15544448888",
"keyword": "平凉PINGLIANG15544448888"
},
{
"name": "萍乡",
"mobile": "15544448888",
"keyword": "萍乡PINGXIANG15544448888"
},
{
"name": "普洱",
"mobile": "15544448888",
"keyword": "普洱PUER15544448888"
},
{
"name": "莆田",
"mobile": "15544448888",
"keyword": "莆田PUTIAN15544448888"
},
{
"name": "濮阳",
"mobile": "15544448888",
"keyword": "濮阳PUYANG15544448888"
}
]
},
{
"letter": "Q",
"data": [{
"name": "黔东南",
"mobile": "15544448888",
"keyword": "黔东南QIANDONGNAN15544448888"
},
{
"name": "黔南",
"mobile": "15544448888",
"keyword": "黔南QIANNAN15544448888"
},
{
"name": "黔西南",
"mobile": "15544448888",
"keyword": "黔西南QIANXINAN15544448888"
}
]
},
{
"letter": "R",
"data": [{
"name": "日喀则",
"mobile": "15544448888",
"keyword": "日喀则RIKAZE15544448888"
},
{
"name": "日照",
"mobile": "15544448888",
"keyword": "日照RIZHAO15544448888"
}
]
},
{
"letter": "S",
"data": [{
"name": "三门峡",
"mobile": "15544448888",
"keyword": "三门峡SANMENXIA15544448888"
},
{
"name": "三明",
"mobile": "15544448888",
"keyword": "三明SANMING15544448888"
},
{
"name": "三沙",
"mobile": "15544448888",
"keyword": "三沙SANSHA15544448888"
}
]
},
{
"letter": "T",
"data": [{
"name": "塔城",
"mobile": "15544448888",
"keyword": "塔城TACHENG15544448888"
},
{
"name": "漯河",
"mobile": "15544448888",
"keyword": "漯河TAHE15544448888"
},
{
"name": "泰安",
"mobile": "15544448888",
"keyword": "泰安TAIAN15544448888"
}
]
},
{
"letter": "W",
"data": [{
"name": "潍坊",
"mobile": "15544448888",
"keyword": "潍坊WEIFANG15544448888"
},
{
"name": "威海",
"mobile": "15544448888",
"keyword": "威海WEIHAI15544448888"
},
{
"name": "渭南",
"mobile": "15544448888",
"keyword": "渭南WEINAN15544448888"
},
{
"name": "文山",
"mobile": "15544448888",
"keyword": "文山WENSHAN15544448888"
}
]
},
{
"letter": "X",
"data": [{
"name": "厦门",
"mobile": "15544448888",
"keyword": "厦门XIAMEN15544448888"
},
{
"name": "西安",
"mobile": "15544448888",
"keyword": "西安XIAN15544448888"
},
{
"name": "湘潭",
"mobile": "15544448888",
"keyword": "湘潭XIANGTAN15544448888"
}
]
},
{
"letter": "Y",
"data": [{
"name": "雅安",
"mobile": "15544448888",
"keyword": "雅安YAAN15544448888"
},
{
"name": "延安",
"mobile": "15544448888",
"keyword": "延安YANAN15544448888"
},
{
"name": "延边",
"mobile": "15544448888",
"keyword": "延边YANBIAN15544448888"
},
{
"name": "盐城",
"mobile": "15544448888",
"keyword": "盐城YANCHENG15544448888"
}
]
},
{
"letter": "Z",
"data": [{
"name": "枣庄",
"mobile": "15544448888",
"keyword": "枣庄ZAOZHUANG15544448888"
},
{
"name": "张家界",
"mobile": "15544448888",
"keyword": "张家界ZHANGJIAJIE15544448888"
},
{
"name": "张家口",
"mobile": "15544448888",
"keyword": "张家口ZHANGJIAKOU15544448888"
}
]
},
{
"letter": "#",
"data": [{
"name": "其他.",
"mobile": "16666666666",
"keyword": "echo16666666666"
}]
}
]
}
+277
View File
@@ -0,0 +1,277 @@
<template>
<view class="modal">
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed>模态框</tn-nav-bar>
<!-- 页面内容 -->
<view :style="{paddingTop: vuex_custom_bar_height + 'px'}">
<dynamic-demo-template ref="demoTemplate" :tips="tips" :sectionList="sectionList" :full="false" @click="click">
<tn-button fontColor="tn-color-white" @click="showModal">弹出模态框</tn-button>
</dynamic-demo-template>
</view>
<!-- 模态框 -->
<tn-modal
v-model="show"
:backgroundColor="backgroundColor"
:width="width"
:padding="padding"
:radius="radius"
:fontColor="fontColor"
:fontSize="fontSize"
:title="title"
:content="content"
:button="button"
:showCloseBtn="closeBtn || !maskCloseable"
:maskCloseable="maskCloseable"
:zoom="zoom"
:custom="custom"
@click="clickBtn"
>
<view v-if="custom">
<view class="custom-modal-content">
<tn-form :labelWidth="140">
<tn-form-item label="手机号码" :borderBottom="false">
<tn-input placeholder="请输入手机号码"></tn-input>
</tn-form-item>
<tn-form-item label="验证码" :borderBottom="false">
<tn-input placeholder="请输入验证码"></tn-input>
<view slot="right" class="tn-flex tn-flex-col-center tn-flex-row-center">
<tn-button :fontSize="20" padding="10rpx" height="46rpx" fontColor="tn-color-white">获取验证码</tn-button>
</view>
</tn-form-item>
</tn-form>
</view>
</view>
</tn-modal>
</view>
</template>
<script>
import dynamicDemoTemplate from '@/libs/components/dynamic-demo-template.vue'
export default {
name: 'componentsModal',
components: {dynamicDemoTemplate},
data() {
return {
title: '使用提醒',
content: '确定不使用TuniaoUI',
show: false,
backgroundColor: '',
width: '84%',
padding: '',
radius: 12,
fontColor: '',
fontSize: 0,
button:[
{
text: '取消',
backgroundColor: '#A4E82F',
fontColor: '#FFFFFF'
},
{
text: '确定',
backgroundColor: 'tn-bg-red',
fontColor: '#FFFFFF'
}
],
closeBtn: true,
maskCloseable: true,
zoom: true,
custom: false,
tips: ['无需依赖额外的样式文件','使用tn-modal组件'],
sectionList: [
{
name: '参数切换',
section: [
{
title: '自定义颜色',
optional: ['默认','自定义'],
methods: 'colorChange'
},
{
title: '自定义大小',
optional: ['默认','自定义'],
methods: 'sizeChange'
},
{
title: '自定义内容',
optional: ['是','否'],
methods: 'customChange',
current: 1
},
{
title: '圆角',
optional: ['默认','60'],
methods: 'radiusChange'
},
{
title: '标题',
optional: ['显示','隐藏'],
methods: 'titleChange'
},
{
title: '按钮',
optional: ['显示','隐藏'],
methods: 'buttonChange'
},
{
title: '右上角关闭按钮',
optional: ['显示','隐藏'],
methods: 'closeBtnChange'
},
{
title: '点击mask关闭',
optional: ['是','否'],
methods: 'maskCloseableChange'
},
{
title: '动画',
optional: ['有','无'],
methods: 'zoomChange'
}
]
}
]
}
},
methods: {
click(event) {
this[event.methods] && this[event.methods](event)
},
// 弹出模态框
showModal(event) {
this.openModal()
},
// 切换颜色
colorChange(event) {
if (event.index === 0) {
this.backgroundColor = ''
this.fontColor = ''
} else {
this.backgroundColor = '#E4E9EC'
this.fontColor = '#BA7027'
}
this.openModal()
},
// 切换大小
sizeChange(event) {
if (event.index === 0) {
// this.width = '84%'
this.padding = ''
this.fontSize = 0
} else {
// this.width = '480rpx'
this.padding = '30rpx 26rpx'
this.fontSize = 35
}
this.openModal()
},
// 切换自定义内容
customChange(event) {
if (event.index === 0) {
this.custom = true
this.$refs.demoTemplate.updateSectionBtnsState([4,5], false)
} else {
this.custom = false
this.$refs.demoTemplate.updateSectionBtnsState([4,5], true)
}
this.openModal()
},
// 切换圆角
radiusChange(event) {
this.radius = event.index === 0 ? 12 : Number(event.name)
this.openModal()
},
// 切换标题信息
titleChange(event) {
this.title = event.index === 0 ? '使用提醒' : ''
this.openModal()
},
// 切换按钮
buttonChange(event) {
this.button = event.index === 0 ? [
{
text: '取消',
backgroundColor: '#E6E6E6',
fontColor: '#FFFFFF'
},
{
text: '确定',
backgroundColor: 'tn-bg-indigo',
fontColor: '#FFFFFF'
}
] : []
this.openModal()
},
// 切换关闭按钮显示隐藏
closeBtnChange(event) {
this.closeBtn = event.index === 0 ? true : false
this.openModal()
},
// 切换蒙版层关闭
maskCloseableChange(event) {
if (event.index === 0) {
this.maskCloseable = true
} else {
this.maskCloseable = false
this.closeBtn = true
this.$refs.demoTemplate.updateSectionBtnsValue(0, 6, 0)
}
this.openModal()
},
// 切换动画
zoomChange(event) {
this.zoom = event.index === 0 ? true : false
this.openModal()
},
// 打开模态框
openModal() {
this.show = true
},
// 点击按钮
clickBtn(event) {
this.show = false
this.$t.messageUtils.toast('点击了第'+(event.index + 1)+'个按钮')
}
},
}
</script>
<style lang="scss" scoped>
</style>
<style lang="scss">
.tn-modal-class {
.custom-modal-content {
width: 100%;
height: 100%;
padding: 40rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
.icon {
font-size: 100rpx;
margin-bottom: 20rpx;
color: $tn-main-color;
}
.text {
font-size: 40rpx;
}
}
}
</style>
+148
View File
@@ -0,0 +1,148 @@
<template>
<view class="components-nav_bar">
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed>navBar导航栏</tn-nav-bar>
<!-- 页面内容 -->
<view :style="{paddingTop: vuex_custom_bar_height + 'px'}">
<dynamic-demo-template ref="demoTemplate" :tips="tips" :sectionList="sectionList" :full="true" @click="click">
<!-- 普通导航栏 -->
<tn-nav-bar v-if="mode === 'normal'" :fixed="false" :height="height" :backgroundColor="backgroundColor" :alpha="alpha">图鸟科技</tn-nav-bar>
<!-- 自定义内容导航栏隐藏返回按钮 -->
<tn-nav-bar v-if="mode === 'customNav'" :fixed="false" :isBack="false" :height="height" :backgroundColor="backgroundColor" :alpha="alpha">
<view class="custom-nav-content">
<view class="search-content">
<tn-input class="search-input" v-model="searchValue" placeholder="请输入要搜索的内容" :border="true" :height="50" :showLeftIcon="true" leftIcon="search"></tn-input>
</view>
</view>
</tn-nav-bar>
<!-- 自定义放回按钮 -->
<tn-nav-bar v-if="mode === 'customBack'" :fixed="false" :customBack="true" :height="height" :backgroundColor="backgroundColor" :alpha="alpha">
<view slot="back" class='tn-custom-nav-bar__back'>
<view><text class='tn-icon-left'></text></view>
<view><text class='tn-icon-home-capsule-fill'></text></view>
</view>
<view class="custom-nav-content">
<view class="search-content">
<tn-input class="search-input" v-model="searchValue" placeholder="请输入要搜索的内容" :border="true" :height="50" :showLeftIcon="true" leftIcon="search"></tn-input>
</view>
</view>
</tn-nav-bar>
</dynamic-demo-template>
</view>
</view>
</template>
<script>
import dynamicDemoTemplate from '@/libs/components/dynamic-demo-template.vue'
export default {
name: 'componentsNavbar',
components: {dynamicDemoTemplate},
data() {
return {
searchValue: '',
mode: 'normal',
height: 46,
backgroundColor: '#FFFFFF',
alpha: false,
tips: ['无需依赖额外的样式文件','使用tn-toast组件'],
sectionList: [
{
name: '参数切换',
section: [
{
title: '高度',
optional: ['默认','46','80'],
methods: 'heightChange',
current: 1
},
{
title: '样式',
optional: ['默认','自定义返回按钮', '隐藏返回栏自定义内容'],
methods: 'modeChange'
},
{
title: '背景颜色',
optional: ['默认','#01BEFF','透明'],
methods: 'backgroundColorChange'
}
]
}
]
}
},
methods: {
click(event) {
this[event.methods] && this[event.methods](event)
},
// 切换高度
heightChange(event) {
this.height = event.index === 0 ? 0 : Number(event.name)
},
// 切换样式
modeChange(event) {
switch(event.index) {
case 0:
this.mode = 'normal'
break
case 1:
this.mode = 'customBack'
break
case 2:
this.mode = 'customNav'
break
}
},
// 切换背景颜色
backgroundColorChange(event) {
switch(event.index) {
case 0:
this.backgroundColor = '#FFFFFF'
this.alpha = false
break
case 1:
this.backgroundColor = event.name
this.alpha = false
break
case 2:
this.alpha = true
break
}
},
},
}
</script>
<style lang="scss" scoped>
@import '@/static/css/templatePage/custom_nav_bar.scss';
.custom-nav-content {
width: 80%;
height: 100%;
display: flex;
align-items: center;
margin-left: 20rpx;
.search-content {
flex: 1;
.search-input {
border-radius: 30rpx;
/* #ifdef MP-WEIXIN */
/deep/ .tn-input-class {
border-radius: 30rpx;
}
/* #endif */
}
}
}
</style>
+292
View File
@@ -0,0 +1,292 @@
<template>
<view class="components-notice-bar">
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed>noticeBar通知栏</tn-nav-bar>
<!-- 页面内容 -->
<view :style="{paddingTop: vuex_custom_bar_height + 'px'}">
<dynamic-demo-template ref="demoTemplate" :tips="tips" :sectionList="sectionList" :full="true" @click="click">
<tn-notice-bar
:show="show"
:list="list"
:mode="mode"
:backgroundColor="backgroundColor"
:fontColor="fontColor"
:fontSize="fontSize"
:playStatus="playStatus"
:leftIcon="leftIcon"
:leftIconName="leftIconName"
:leftIconSize="leftIconSize"
:rightIcon="rightIcon"
:rightIconName="rightIconName"
:rightIconSize="rightIconSize"
:closeBtn="closeBtn"
:radius="radius"
:padding="padding"
:autoplay="autoplay"
:duration="duration"
:speed="speed"
:circular="circular"
:autoHidden="autoHidden"
@click="onClick"
@close="close"
@clickLeft="onLeftClick"
@clickRight="onRightClick"
@end="end"
></tn-notice-bar>
</dynamic-demo-template>
</view>
</view>
</template>
<script>
import dynamicDemoTemplate from '@/libs/components/dynamic-demo-template.vue'
export default {
name: 'componentsNoticeBar',
components: {dynamicDemoTemplate},
data() {
return {
list: [
'TuniaoUI现已发布V1.0.0',
'今天天气晴朗,适合处理bug',
'TuniaoUIV2.0.0即将发布',
'今天想提前下班,领导不允许:"你提前走人就算你是旷工了啊!"'
],
show: true,
mode: 'horizontal',
backgroundColor: '',
fontColor: '',
fontSize: 0,
playStatus: 'play',
leftIcon: true,
leftIconName: 'sound',
leftIconSize: 34,
rightIcon: false,
rightIconName: 'right',
rightIconSize: 26,
closeBtn: false,
radius: 0,
padding: '18rpx 24rpx',
autoplay: true,
duration: 2000,
speed: 160,
circular: true,
autoHidden: true,
tips: ['无需依赖额外的样式文件','使用tn-notice-bar组件'],
sectionList: [
{
name: '参数切换',
section: [
{
title: '滚动模式',
optional: ['水平连续','水平不连续','垂直'],
methods: 'modeChange'
},
{
title: '显示状态',
optional: ['显示','隐藏'],
methods: 'showChange'
},
{
title: '播放状态',
optional: ['播放','暂停'],
methods: 'playStatusChange'
},
{
title: '速度控制',
optional: ['减速','加速'],
methods: 'speedChange'
},
{
title: '图标显示',
optional: ['默认','显示右边图标','显示关闭按钮','全部不显示'],
methods: 'iconChange'
},
{
title: '自定义图标',
optional: ['默认','自定义'],
methods: 'iconNameChange'
},
{
title: '自定义颜色',
optional: ['默认','自定义'],
methods: 'colorChange'
},
{
title: '自定义样式',
optional: ['默认','自定义'],
methods: 'styleChange'
}
]
}
]
}
},
methods: {
click(event) {
this[event.methods] && this[event.methods](event)
},
// 切换滚动模式
modeChange(event) {
this.speed = 160
this.duration = 2000
switch (event.index) {
case 0:
this.mode = 'horizontal'
this.circular = true
break
case 1:
this.mode = 'horizontal'
this.circular = false
break
case 2:
this.mode = 'vertical'
break
}
},
// 切换显示状态
showChange(event) {
this.show = event.index === 0 ? true : false
},
// 切换播放状态
playStatusChange(event) {
this.playStatus = event.index === 0 ? 'play' : 'paused'
},
// 切换滚动速度
speedChange(event) {
switch (event.index) {
case 0:
if (this.mode === 'horizontal' && this.circular) {
const speed = this.speed - 10
this.speed = speed > 0 ? speed : 0
} else {
const duration = this.duration + 100
if (duration > 3000) {
this.$t.messageUtils.toast('达到速度最小值')
this.duration = 3000
} else {
this.duration = duration
}
}
break
case 1:
if (this.mode === 'horizontal' && this.circular) {
const speed = this.speed + 10
if (speed > 300) {
this.$t.messageUtils.toast('达到速度最大值')
this.speed = 300
} else {
this.speed = speed
}
} else {
const duration = this.duration - 100
this.duration = this.duration > 0 ? duration : 0
}
break
}
},
// 切换图标显示
iconChange(event) {
switch (event.index) {
case 0:
this.leftIcon = true
this.rightIcon = false
this.closeBtn = false
break
case 1:
this.rightIcon = true
break
case 2:
this.closeBtn = true
break
case 3:
this.leftIcon = false
this.rightIcon = false
this.closeBtn = false
break
}
},
// 切换自定义图标
iconNameChange(event) {
switch (event.index) {
case 0:
this.leftIconName = 'sound'
this.rightIconName = 'right'
break
case 1:
this.leftIconName = 'tag'
this.rightIconName = 'trophy'
break
}
},
// 切换自定义颜色
colorChange(event) {
switch (event.index) {
case 0:
this.backgroundColor = ''
this.fontColor = ''
break
case 1:
this.backgroundColor = 'tn-bg-red'
this.fontColor = '#FFFFFF'
break
}
},
// 切换自定义样式
styleChange(event) {
switch (event.index) {
case 0:
this.fontSize = 0
this.radius = 0
this.leftIconSize = 34
this.rightIconSize = 26
break
case 1:
this.fontSize = 40
this.radius = 10
this.leftIconSize = 50
this.rightIconSize = 30
break
}
},
// 点击消息
onClick(index) {
this.$t.messageUtils.toast('点击了消息')
},
// 点击关闭按钮
close() {
this.$t.messageUtils.toast('点击关闭按钮')
},
// 点击左边图标
onLeftClick() {
this.$t.messageUtils.toast('点击左边图标')
},
// 点击右边图标
onRightClick() {
this.$t.messageUtils.toast('点击右边图标')
},
// 一个周期滚动结束
end() {
console.log('滚动结束');
}
},
}
</script>
<style lang="scss" scoped>
</style>
+171
View File
@@ -0,0 +1,171 @@
<template>
<view class="components-number_box">
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed>numberBox步进输入</tn-nav-bar>
<!-- 页面内容 -->
<view :style="{paddingTop: vuex_custom_bar_height + 'px'}">
<dynamic-demo-template ref="demoTemplate" :tips="tips" :sectionList="sectionList" :full="false" @click="click">
<tn-number-box
v-model="value"
:min="min"
:max="max"
:step="step"
:disabled="disabled"
:disabledInput="disabledInput"
:inputWidth="inputWidth"
:inputHeight="inputHeight"
:positiveInteger="positiveInteger"
:backgroundColor="backgroundColor"
:fontColor="fontColor"
:fontSize="fontSize"
></tn-number-box>
</dynamic-demo-template>
</view>
</view>
</template>
<script>
import dynamicDemoTemplate from '@/libs/components/dynamic-demo-template.vue'
export default {
name: 'componentsNumberBox',
components: {dynamicDemoTemplate},
data() {
return {
value: 0,
min: 0,
max: 100,
step: 1,
disabled: false,
disabledInput: false,
inputWidth: 88,
inputHeight: 50,
positiveInteger: true,
backgroundColor: '#E6E6E6',
fontColor: '',
fontSize: 0,
tips: ['无需依赖额外的样式文件','使用tn-number-box组件'],
sectionList: [
{
name: '参数切换',
section: [
{
title: '初始值',
optional: ['0','1','2.5','3','4','5'],
methods: 'valueChange'
},
{
title: '最小最大值',
optional: ['0-100','50-1000'],
methods: 'minMaxChange'
},
{
title: '步进值',
optional: ['1','5','0.5'],
methods: 'stepChange'
},
{
title: '只允许输入正整数',
optional: ['是','否'],
methods: 'positiveIntegerChange'
},
{
title: '禁用状态',
optional: ['是','否'],
methods: 'disabledChange',
current: 1
},
{
title: '禁用输入状态',
optional: ['是','否'],
methods: 'disabledInputChange',
current: 1
},
{
title: '自定义尺寸',
optional: ['默认','自定义'],
methods: 'customSizeChange'
},
{
title: '自定义颜色',
optional: ['默认','自定义'],
methods: 'customColorChange'
}
]
}
]
}
},
methods: {
click(event) {
this[event.methods] && this[event.methods](event)
},
// 切换初始值
valueChange(event) {
this.value = Number(event.name)
},
// 切换最小最大值
minMaxChange(event) {
const value = event.name.split('-')
this.min = Number(value[0])
this.max = Number(value[1])
},
// 切换步进值
stepChange(event) {
this.step = Number(event.name)
},
// 切换允许正整数状态
positiveIntegerChange(event) {
this.positiveInteger = event.index === 0 ? true : false
},
// 切换禁用状态
disabledChange(event) {
this.disabled = event.index === 0 ? true : false
},
// 切换禁用输入状态
disabledInputChange(event) {
this.disabledInput = event.index === 0 ? true : false
},
// 切换自定义尺寸
customSizeChange(event) {
switch(event.index) {
case 0:
this.inputWidth = 88
this.inputHeight = 50
this.fontSize = 0
break
case 1:
this.inputWidth = 120
this.inputHeight = 60
this.fontSize = 40
break
}
},
// 切换自定义颜色
customColorChange(event) {
switch(event.index) {
case 0:
this.backgroundColor = '#E6E6E6'
this.fontColor = ''
break
case 1:
this.backgroundColor = '#AAAAAA'
this.fontColor = 'tn-color-grey'
break
}
},
},
}
</script>
<style lang="scss" scoped>
</style>
+303
View File
@@ -0,0 +1,303 @@
<template>
<view class="components-picker">
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed>Picker选择器</tn-nav-bar>
<!-- 页面内容 -->
<view :style="{paddingTop: vuex_custom_bar_height + 'px'}">
<dynamic-demo-template ref="demoTemplate" :tips="tips" :sectionList="sectionList" :full="false" @click="click">
<view class="tn-flex tn-flex-row-center"><tn-button fontColor="tn-color-white" @click="showPicker">弹出Picker</tn-button></view>
<view class="picker-result tn-border-dashed">
{{ result }}
</view>
</dynamic-demo-template>
</view>
<!-- picker -->
<tn-picker
v-model="show"
:mode="mode"
:params="params"
:range="range"
:rangeKey="rangeKey"
:defaultSelector="defaultSelector"
:showTimeTag="showTimeTag"
:startYear="startYear"
:endYear="endYear"
:defaultTime="defaultTime"
:defaultRegin="defaultRegion"
:areaCode="areaCode"
:maskCloseable="maskCloseable"
@cancel="cancelPicker"
@confirm="confirmPicker"
>
</tn-picker>
</view>
</template>
<script>
import dynamicDemoTemplate from '@/libs/components/dynamic-demo-template.vue'
export default {
name: 'componentsPicker',
components: {dynamicDemoTemplate},
data() {
return {
result: 'Picker结果',
show: false,
mode: 'selector',
params: {
year: true,
month: true,
day: true,
hour: false,
minute: false,
second: false,
province: true,
city: true,
area: true,
timestamp: true
},
showTimeTag: false,
startYear: 2000,
endYear: 2100,
defaultTime: '2021/10/01 12:00:00',
defaultRegion: ['广东省','广州市','天河区'],
areaCode: [],
maskCloseable: true,
range: ['哆啦A梦','大熊','小夫','静香','胖虎'],
rangeKey: '',
defaultSelector: [0],
tips: ['无需依赖额外的样式文件','使用tn-picker组件'],
sectionList: [
{
name: '参数切换',
section: [
{
title: '模式',
optional: ['单列','多列','时间','地区'],
methods: 'modeChange'
},
{
title: '显示时分秒',
optional: ['隐藏','显示'],
methods: 'timeSecondChange',
show: false
},
{
title: '显示时间单位',
optional: ['隐藏','显示'],
methods: 'showTimeTagChange',
show: false
},
{
title: '指定起始年份',
optional: ['2000-2100','2020-2030'],
methods: 'timeRangeChange',
show: false
},
{
title: '默认时间',
optional: ['2021/10/01 12:00:00','2021-10-01 17:00:00'],
methods: 'defaultTimeChange',
show: false
},
{
title: '默认地区',
optional: ['广东省-广州市-天河区','44-4401-440107'],
methods: 'defaultRegionChange',
show: false
},
{
title: '点击遮罩关闭',
optional: ['是','否'],
methods: 'maskCloseableChange'
}
]
}
]
}
},
methods: {
click(event) {
this[event.methods] && this[event.methods](event)
},
// 弹出Picker
showPicker(event) {
this.openPicker()
},
// 切换模式
modeChange(event) {
switch(event.index) {
case 0:
this.mode = 'selector'
this.range = ['哆啦A梦','大熊','小夫','静香','胖虎']
this.defaultSelector = [0]
this.rangeKey = ''
this.$refs.demoTemplate.updateSectionBtnsState([1,2,3,4], false)
this.$refs.demoTemplate.updateSectionBtnsState(5, false)
break
case 1:
this.mode = 'multiSelector'
this.range = [
[
{
id: 1,
name: '哆啦A梦'
},
{
id: 2,
name: '大熊'
},
{
id: 3,
name: '小夫'
},
{
id: 4,
name: '静香'
},
{
id: 5,
name: '胖虎'
},
],
[
{
id: 1,
name: '家'
},
{
id: 2,
name: '学校'
},
{
id: 3,
name: '操场'
}
]
]
this.defaultSelector = [0,0]
this.rangeKey = 'name'
this.$refs.demoTemplate.updateSectionBtnsState([1,2,3,4], false)
this.$refs.demoTemplate.updateSectionBtnsState(5, false)
break
case 2:
this.mode = 'time'
this.$refs.demoTemplate.updateSectionBtnsState([1,2,3,4], true)
this.$refs.demoTemplate.updateSectionBtnsState(5, false)
break
case 3:
this.mode = 'region'
this.$refs.demoTemplate.updateSectionBtnsState([1,2,3,4], false)
this.$refs.demoTemplate.updateSectionBtnsState(5, true)
break
}
this.openPicker()
},
// 切换显示时分秒
timeSecondChange(event) {
this.params = {
year: true,
month: true,
day: true,
hour: true,
minute: true,
second: true,
province: true,
city: true,
area: true,
timestamp: true
}
this.openPicker()
},
// 切换显示时间单位
showTimeTagChange(event) {
this.showTimeTag = event.index === 0 ? false : true
this.openPicker()
},
// 切换起始年份
timeRangeChange(event) {
if (event.index === 0) {
this.startYear = 2000
this.endYear = 2100
} else if (event.index === 1) {
this.startYear = 2020
this.endYear = 2030
}
this.openPicker()
},
// 切换默认时间
defaultTimeChange(event) {
this.defaultTime = event.name
this.openPicker()
},
// 切换默认地区
defaultRegionChange(event) {
if (event.index === 0) {
this.defaultRegion = ['广东省','广州市','天河区']
this.areaCode = []
} else if (event.index === 1) {
this.defaultRegion = []
this.areaCode = ['44','4401','440111']
}
this.openPicker()
},
// 切换点击遮罩关闭
maskCloseableChange(event) {
this.maskCloseable = event.index === 0 ? true : false
this.openPicker()
},
// 点击取消按钮
cancelPicker(event) {
this.$t.messageUtils.toast('点击了取消按钮')
},
// 点击确认按钮
confirmPicker(event) {
switch (this.mode) {
case 'selector':
this.result = this.range[event[0]]
this.defaultSelector = event
break
case 'multiSelector':
this.result = `${this.range[0][event[0]][this.rangeKey]} - ${this.range[1][event[1]][this.rangeKey]}`
this.defaultSelector = event
break
case 'time':
this.result = `${event.year}-${event.month}-${event.day} ${this.params.hour ? event.hour+':' : ''}${this.params.minute ? event.minute+':' : ''}${this.params.second ? event.second : ''}`
this.defaultTime = this.result
break
case 'region':
this.result = `${event.province.label}-${event.city.label}-${event.area.label}`
break
}
},
// 打开Picker
openPicker() {
this.show = true
},
},
}
</script>
<style lang="scss" scoped>
.picker-result {
margin-top: 20rpx;
padding: 10rpx 30rpx;
background-color: $tn-font-holder-color;
text-align: center;
}
</style>
+240
View File
@@ -0,0 +1,240 @@
<template>
<view class="components-popup">
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed>弹框</tn-nav-bar>
<!-- 页面内容 -->
<view :style="{paddingTop: vuex_custom_bar_height + 'px'}">
<dynamic-demo-template ref="demoTemplate" :tips="tips" :sectionList="sectionList" :full="false" @click="click">
<tn-button fontColor="tn-color-white" :disabled="show" @click="showPopup">弹出弹框</tn-button>
</dynamic-demo-template>
</view>
<!-- popup -->
<tn-popup
v-model="show"
:marginTop="vuex_custom_bar_height"
length="50%"
:mode="mode"
:backgroundColor="backgroundColor"
:width="width"
:height="height"
:borderRadius="borderRadius"
:closeBtn="closeBtn"
:closeBtnIcon="closeBtnIcon"
:closeBtnPosition="closeBtnPosition"
:maskCloseable="maskCloseable"
@close="closedPopup"
>
<view class="popup-content" :class="{'popup-content--center': mode === 'center'}">
<tn-button shape="round" @click="closedPopup" width="220rpx" fontColor="#080808">关闭弹窗</tn-button>
</view>
</tn-popup>
</view>
</template>
<script>
import dynamicDemoTemplate from '@/libs/components/dynamic-demo-template.vue'
export default {
name: 'componentsPopup',
components: {dynamicDemoTemplate},
data() {
return {
show: false,
mode: 'left',
backgroundColor: '',
width: '',
height: '',
borderRadius: 0,
closeBtn: true,
closeBtnIcon: 'close',
closeBtnPosition: 'top-right',
maskCloseable: true,
popupShowSubsectionIndex: 1,
tips: ['无需依赖额外的样式文件','使用tn-popup组件, 如果使用了自定义顶部,需要设置marginTop属性为自定义顶部的高度'],
sectionList: [
{
name: '参数切换',
section: [
{
title: '背景颜色',
optional: ['默认','tn-bg-grey--light','#C6D1D8'],
methods: 'backgroundColorChange'
},
{
title: '宽高',
optional: ['默认','自定义'],
methods: 'widthHeightChange'
},
{
title: '圆角',
optional: ['0','23'],
methods: 'borderRadiusChange'
},
{
title: '弹出位置',
optional: ['上','下','中','左','右'],
methods: 'modeChange',
current: 3
},
{
title: '关闭按钮',
optional: ['显示','隐藏'],
methods: 'closeBtnChange'
},
{
title: '关闭按钮图标',
optional: ['close','cross-fill'],
methods: 'closeBtnIconChange'
},
{
title: '关闭按钮位置',
optional: ['左上','右上','左下','右下'],
methods: 'closeBtnPositionChange',
current: 1
},
{
title: '点击遮罩关闭',
optional: ['是','否'],
methods: 'maskCloseableChange'
}
]
}
]
}
},
methods: {
click(event) {
this[event.methods] && this[event.methods](event)
},
// 弹出弹框
showPopup() {
this.openPopup()
},
// 切换弹出位置
modeChange(event) {
switch(event.index) {
case 0:
this.mode = 'top'
break
case 1:
this.mode = 'bottom'
break
case 2:
this.mode = 'center'
break
case 3:
this.mode = 'left'
break
case 4:
this.mode = 'right'
break
}
this.openPopup()
},
// 切换背景颜色
backgroundColorChange(event) {
this.backgroundColor = event.index === 0 ? '' : event.name
this.openPopup()
},
// 切换宽高设置
widthHeightChange(event) {
if (event.index === 0) {
this.width = ''
this.height = ''
} else {
this.width = this.mode !== 'center' ? '30%' : '60%'
this.height = this.mode !== 'center' ? '30%' : '20%'
}
this.openPopup()
},
// 切换圆角
borderRadiusChange(event) {
this.borderRadius = Number(event.name)
this.openPopup()
},
// 切换关闭按钮
closeBtnChange(event) {
if (event.index === 0) {
this.closeBtn = true
this.$refs.demoTemplate.updateSectionBtnsState([5,6], true)
} else {
this.closeBtn = false
this.$refs.demoTemplate.updateSectionBtnsState([5,6], false)
}
this.openPopup()
},
// 切换关闭按钮图标
closeBtnIconChange(event) {
this.closeBtnIcon = event.name
this.openPopup()
},
// 切换关闭按钮的位置
closeBtnPositionChange(event) {
switch(event.index) {
case 0:
this.closeBtnPosition = 'top-left'
break
case 1:
this.closeBtnPosition = 'top-right'
break
case 2:
this.closeBtnPosition = 'bottom-left'
break
case 3:
this.closeBtnPosition = 'bottom-right'
break
}
this.openPopup()
},
// 切换点击遮罩关闭
maskCloseableChange(event) {
if (event.index === 0) {
this.maskCloseable = true
} else {
this.maskCloseable = false
this.closeBtn = true
this.$refs.demoTemplate.updateSectionBtnsValue(0, 4, 0)
this.$refs.demoTemplate.updateSectionBtnsState([5,6], true)
}
this.openPopup()
},
// 打开Popup
openPopup() {
this.show = true
},
// 关闭Popup
closedPopup() {
this.show = false
}
},
}
</script>
<style lang="scss" scoped>
.popup-content {
height: 100%;
width: auto;
display: flex;
justify-content: center;
align-items: center;
&--center {
padding: 150rpx 50rpx;
}
}
</style>
+204
View File
@@ -0,0 +1,204 @@
<template>
<view class="components-progress">
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed>Progress进度条</tn-nav-bar>
<!-- 页面内容 -->
<view :style="{paddingTop: vuex_custom_bar_height + 'px'}">
<dynamic-demo-template ref="demoTemplate" :tips="tips" :sectionList="sectionList" :full="true" @click="click">
<block v-if="customPercent">
<tn-line-progress v-if="mode === 'line'" :percent="percent" :height="height" :activeColor="activeColor"
:striped="striped" :stripedAnimation="stripedAnimation" :showPercent="showPercent">
<block v-if="customPercent">
<view class="tn-color-white">加载中</view>
</block>
</tn-line-progress>
<view class="tn-flex tn-flex-row-center">
<tn-circle-progress v-if="mode === 'circle'" :percent="percent" :showPercent="showPercent">
<block v-if="customPercent">
<view class="tn-color-red">加载中</view>
</block>
</tn-circle-progress>
</view>
</block>
<block v-else>
<tn-line-progress v-if="mode === 'line'" :percent="percent" :height="height" :activeColor="activeColor"
:striped="striped" :stripedAnimation="stripedAnimation" :showPercent="showPercent"></tn-line-progress>
<view class="tn-flex tn-flex-row-center">
<tn-circle-progress v-if="mode === 'circle'" :percent="percent" :showPercent="showPercent">
</tn-circle-progress>
</view>
</block>
</dynamic-demo-template>
</view>
</view>
</template>
<script>
import dynamicDemoTemplate from '@/libs/components/dynamic-demo-template.vue'
export default {
name: 'componentsStriped',
components: {
dynamicDemoTemplate
},
data() {
return {
mode: 'line',
percent: 50,
height: 28,
activeColor: '#01BEFF',
showPercent: false,
striped: false,
stripedAnimation: true,
customPercent: false,
tips: ['无需依赖额外的样式文件', '使用tn-line-progress、tn-circle-progress组件'],
sectionList: [
{
name: '参数切换',
section: [
{
title: '模式',
optional: ['线条','圆环'],
methods: 'modeChange'
},
{
title: '进度',
optional: ['减少10%','增加10%'],
methods: 'percentChange'
},
{
title: '高度',
optional: ['18','28','38'],
methods: 'heightChange',
current: 1
},
{
title: '激活时颜色',
optional: ['#01BEFF','#2DE88D'],
methods: 'activeColorChange'
},
{
title: '显示条纹',
optional: ['是','否'],
methods: 'stripedChange',
current: 1
},
{
title: '动态条纹',
optional: ['是','否'],
methods: 'stripedAnimationChange',
show: false
},
{
title: '显示进度信息',
optional: ['是','否'],
methods: 'showPercentChange',
current: 1
},
{
title: '自定义进度信息',
optional: ['是','否'],
methods: 'customPercentChange',
current: 1
}
]
}
]
}
},
methods: {
click(event) {
this[event.methods] && this[event.methods](event)
},
// 切换模式
modeChange(event) {
switch (event.index) {
case 0:
this.mode = 'line'
if (this.striped) {
this.$refs.demoTemplate.updateSectionBtnsState([2,3,4,5], true)
} else {
this.$refs.demoTemplate.updateSectionBtnsState([2,3,4], true)
}
break
case 1:
this.mode = 'circle'
this.$refs.demoTemplate.updateSectionBtnsState([2,3,4,5], false)
break
}
this.$refs.demoTemplate.updateSectionScrollView()
},
// 切换进度
percentChange(event) {
let percent = 0
switch (event.index) {
case 0:
percent = this.percent - 10
this.percent = percent > 0 ? percent : 0
break
case 1:
percent = this.percent + 10
this.percent = percent > 100 ? 100 : percent
break
}
},
// 切换高度
heightChange(event) {
this.height = Number(event.name)
this.$refs.demoTemplate.updateSectionScrollView()
},
// 切换激活时颜色
activeColorChange(event) {
this.activeColor = event.name
},
// 切换进度信息显示
showPercentChange(event) {
if (event.index === 0) {
this.showPercent = true
this.customPercent = false
this.$refs.demoTemplate.updateSectionBtnsState(7, false)
} else {
this.showPercent = false
this.$refs.demoTemplate.updateSectionBtnsState(7, true)
}
},
// 切换条纹
stripedChange(event) {
if (event.index === 0) {
this.striped = true
this.$refs.demoTemplate.updateSectionBtnsState(5, true)
} else {
this.striped = false
this.$refs.demoTemplate.updateSectionBtnsState(5, false)
}
},
// 切换条纹动画
stripedAnimationChange(event) {
this.stripedAnimation = event.index === 0 ? true : false
},
// 切换自定义进度信息
customPercentChange(event) {
this.customPercent = event.index === 0 ? true : false
}
},
}
</script>
<style lang="scss" scoped>
tn-line-progress, .tn-line-progress {
width: 100%;
}
</style>
+177
View File
@@ -0,0 +1,177 @@
<template>
<view class="components-rate">
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed>rate评分</tn-nav-bar>
<!-- 页面内容 -->
<view :style="{paddingTop: vuex_custom_bar_height + 'px'}">
<dynamic-demo-template ref="demoTemplate" :tips="tips" :sectionList="sectionList" :full="false" @click="click">
<tn-rate
v-model="value"
:count="count"
:disabled="disabled"
:allowHalf="allowHalf"
:size="size"
:activeIcon="activeIcon"
:inactiveIcon="inactiveIcon"
:activeColor="activeColor"
:inactiveColor="inactiveColor"
:colors="colors"
:icons="icons"
></tn-rate>
</dynamic-demo-template>
</view>
</view>
</template>
<script>
import dynamicDemoTemplate from '@/libs/components/dynamic-demo-template.vue'
export default {
name: 'componentsRate',
components: {dynamicDemoTemplate},
data() {
return {
value: 0,
count: 5,
disabled: false,
allowHalf: false,
size: 32,
activeIcon: 'star-fill',
inactiveIcon: 'star',
activeColor: '#01BEFF',
inactiveColor: '#AAAAAA',
colors: [],
icons: [],
tips: ['无需依赖额外的样式文件','使用tn-rate组件'],
sectionList: [
{
name: '参数切换',
section: [
{
title: '初始值',
optional: ['0','1','2.5','3','4','5'],
methods: 'valueChange'
},
{
title: '半星状态',
optional: ['是','否'],
methods: 'allowHalfChange',
current: 1
},
{
title: '禁用状态',
optional: ['是','否'],
methods: 'disabledChange',
current: 1
},
{
title: '尺寸',
optional: ['24','32','68'],
methods: 'sizeChange',
current: 1
},
{
title: '图标数量',
optional: ['3','4','5','6'],
methods: 'countChange',
current: 2
},
{
title: '图标',
optional: ['默认','自定义'],
methods: 'iconChange'
},
{
title: '颜色',
optional: ['默认','自定义'],
methods: 'colorChange'
},
{
title: '根据选择数显示图标信息',
optional: ['是','否'],
methods: 'showDiffChange',
current: 1
}
]
}
]
}
},
methods: {
click(event) {
this[event.methods] && this[event.methods](event)
},
// 切换初始值
valueChange(event) {
this.value = Number(event.name)
},
// 切换半星状态
allowHalfChange(event) {
this.allowHalf = event.index === 0 ? true : false
},
// 切换禁用状态
disabledChange(event) {
this.disabled = event.index === 0 ? true : false
},
// 切换尺寸
sizeChange(event) {
this.size = Number(event.name)
},
// 切换图标数量
countChange(event) {
this.count = Number(event.name)
},
// 切换图标
iconChange(event) {
switch (event.index) {
case 0:
this.activeIcon = 'star-fill'
this.inactiveIcon = 'star'
break
case 1:
this.activeIcon = 'emoji-good-fill'
this.inactiveIcon = 'emoji-good'
break
}
},
// 切换颜色
colorChange(event) {
switch (event.index) {
case 0:
this.activeColor = '#01BEFF'
this.inactiveColor = '#AAAAAA'
break
case 1:
this.activeColor = '#31E749'
this.inactiveColor = '#E7D5FA'
break
}
},
// 切换不同状态显示不同的图标信息
showDiffChange(event) {
switch (event.index) {
case 0:
this.colors = ['#01BEFF','#3D7EFF','#31C9E8']
this.icons = ['star-fill','praise-fill','flower-fill']
break
case 1:
this.colors = []
this.icons = []
break
}
}
},
}
</script>
<style lang="scss" scoped>
</style>
+179
View File
@@ -0,0 +1,179 @@
<template>
<view class="components-read-more">
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed>ReadMore查看更多</tn-nav-bar>
<!-- 页面内容 -->
<view :style="{paddingTop: vuex_custom_bar_height + 'px'}">
<dynamic-demo-template ref="demoTemplate" :tips="tips" :sectionList="sectionList" :full="true" :fullWindowsScroll="fullWindowsScroll" @click="click">
<tn-read-more
:showHeight="showHeight"
:closeBtn="closeBtn"
:openText="openText"
:closeText="closeText"
:openIcon="openIcon"
:closeIcon="closeIcon"
:fontColor="fontColor"
:fontSize="fontSize"
:shadowStyle="shadowStyle"
@open="open"
@closed="closed">
<rich-text :nodes="content"></rich-text>
</tn-read-more>
</dynamic-demo-template>
</view>
</view>
</template>
<script>
import dynamicDemoTemplate from '@/libs/components/dynamic-demo-template.vue'
export default {
name: 'componentsReadMore',
components: {dynamicDemoTemplate},
data() {
return {
content: `噫吁嚱,危乎高哉!
蜀道之难,难于上青天!
蚕丛及鱼凫,开国何茫然!
尔来四万八千岁,不与秦塞通人烟。
西当太白有鸟道,可以横绝峨眉巅。
地崩山摧壮士死,然后天梯石栈相钩连。
上有六龙回日之高标,下有冲波逆折之回川。
黄鹤之飞尚不得过,猿猱欲度愁攀援。
青泥何盘盘,百步九折萦岩峦。
扪参历井仰胁息,以手抚膺坐长叹。
问君西游何时还?畏途巉岩不可攀。
但见悲鸟号古木,雄飞雌从绕林间。
又闻子规啼夜月,愁空山。
蜀道之难,难于上青天,使人听此凋朱颜!
连峰去天不盈尺,枯松倒挂倚绝壁。
飞湍瀑流争喧豗,砯崖转石万壑雷。
其险也如此,嗟尔远道之人胡为乎来哉!(也如此 一作:也若此)
剑阁峥嵘而崔嵬,一夫当关,万夫莫开。
所守或匪亲,化为狼与豺。
朝避猛虎,夕避长蛇,磨牙吮血,杀人如麻。
锦城虽云乐,不如早还家。
蜀道之难,难于上青天,侧身西望长咨嗟!`,
showHeight: 400,
closeBtn: false,
openText: '展开阅读全文',
closeText: '收起',
openIcon: 'down',
closeIcon: 'up',
fontColor: '',
fontSize: 0,
shadowStyle: {
backgroundImage: "linear-gradient(-180deg, rgba(255, 255, 255, 0) 0%, #fff 80%)",
paddingTop: "300rpx",
marginTop: "-300rpx"
},
fullWindowsScroll: false,
tips: ['无需依赖额外的样式文件','使用tn-read-more组件'],
sectionList: [
{
name: '参数切换',
section: [
{
title: '默认高度',
optional: ['200','400', '600'],
methods: 'showHeightChange',
current: 1
},
{
title: '显示收起按钮',
optional: ['显示','隐藏'],
methods: 'closeBtnChange',
current: 1
},
{
title: '自定义样式',
optional: ['默认','自定义'],
methods: 'customChange'
}
]
}
]
}
},
onReady() {
setTimeout(() => {
this.$refs.demoTemplate.updateSectionScrollView()
}, 100)
},
methods: {
click(event) {
this[event.methods] && this[event.methods](event)
},
// 切换默认高度
showHeightChange(event) {
this.showHeight = Number(event.name)
},
// 切换收起按钮模式
closeBtnChange(event) {
this.closeBtn = event.index === 0 ? true : false
},
// 切换自定义样式
customChange(event) {
switch (event.index) {
case 0:
this.openText = '展开阅读全文'
this.closeText = '收起'
this.openIcon = 'down'
this.closeIcon = 'up'
this.fontColor = ''
this.fontSize = 0
this.shadowStyle = {
backgroundImage: "linear-gradient(-180deg, rgba(255, 255, 255, 0) 0%, #fff 80%)",
paddingTop: "300rpx",
marginTop: "-300rpx"
}
break
case 1:
this.openText = '付费解锁剩余内容'
this.closeText = '折起来'
this.openIcon = 'money'
this.closeIcon = 'close-circle'
this.fontSize = 30
this.shadowStyle = {
backgroundImage: "linear-gradient(-180deg, rgba(255, 255, 255, 0) 0%, #AAA 100%)",
paddingTop: "300rpx",
marginTop: "-300rpx"
}
break
}
},
// 展开
open() {
// setTimeout(() => {
// this.$refs.demoTemplate.updateSectionScrollView()
// }, 350)
this.fullWindowsScroll = true
},
// 收起
closed() {
setTimeout(() => {
this.fullWindowsScroll = false
this.$refs.demoTemplate.updateSectionScrollView()
}, 350)
}
},
}
</script>
<style lang="scss" scoped>
</style>
+148
View File
@@ -0,0 +1,148 @@
<template>
<view class="components-toast">
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed>ScrollList横向滚动</tn-nav-bar>
<!-- 页面内容 -->
<view :style="{paddingTop: vuex_custom_bar_height + 'px'}">
<dynamic-demo-template ref="demoTemplate" :tips="tips" :sectionList="sectionList" :full="true" @click="click">
<tn-scroll-list
:indicator="indicator"
:indicatorWidth="indicatorWidth"
:indicatorBarWidth="indicatorBarWidth"
:indicatorColor="indicatorColor"
:indicatorActiveColor="indicatorActiveColor"
>
<view class="tn-flex tn-margin-sm">
<block v-for="(item, index) in 14" :key="index">
<view class="tn-flex-1 tn-padding-sm tn-margin-xs tn-radius">
<view class="tn-flex tn-flex-direction-column tn-flex-row-center tn-flex-col-center">
<view class="icon3__item--icon tn-flex tn-flex-row-center tn-flex-col-center tn-shadow-blur" :class="[$t.colorUtils.getRandomCoolBgClass(index)]">
<view class="tn-icon-gloves-fill"></view>
</view>
<view class="tn-color-black tn-text-lg tn-text-center">
<text class="tn-text-ellipsis">傻北</text>
</view>
</view>
</view>
</block>
</view>
</tn-scroll-list>
</dynamic-demo-template>
</view>
</view>
</template>
<script>
import dynamicDemoTemplate from '@/libs/components/dynamic-demo-template.vue'
export default {
name: 'componentsScrollList',
components: {dynamicDemoTemplate},
data() {
return {
indicator: true,
indicatorWidth: 50,
indicatorBarWidth: 20,
indicatorColor: '#E6E6E6',
indicatorActiveColor: '#01BEFF',
tips: ['无需依赖额外的样式文件','使用tn-scroll-list组件'],
sectionList: [
{
name: '参数切换',
section: [
{
title: '指示条',
optional: ['显示','隐藏'],
methods: 'indicatorChange'
},
{
title: '指示条样式',
optional: ['默认','自定义'],
methods: 'customChange'
}
]
}
]
}
},
methods: {
click(event) {
this[event.methods] && this[event.methods](event)
},
// 切换指示条状态
indicatorChange(event) {
this.indicator = event.index === 0 ? true : false
this.$refs.demoTemplate.updateSectionScrollView()
},
// 切换自定义指示条
customChange(event) {
switch (event.index) {
case 0:
this.indicatorWidth = 50
this.indicatorBarWidth = 20
this.indicatorColor = '#E6E6E6'
this.indicatorActiveColor = '#01BEFF'
break
case 1:
this.indicatorWidth = 100
this.indicatorBarWidth = 30
this.indicatorColor = '#D6F4FA'
this.indicatorActiveColor = '#27A1BA'
break
}
}
},
}
</script>
<style lang="scss" scoped>
.icon3 {
&__item {
width: 30%;
background-color: #FFFFFF;
border-radius: 10rpx;
padding: 30rpx;
margin: 20rpx 10rpx;
margin-top: 0;
transform: scale(1);
transition: transform 0.3s linear;
transform-origin: center center;
&--icon {
width: 100rpx;
height: 100rpx;
font-size: 60rpx;
border-radius: 25%;
margin-bottom: 18rpx;
position: relative;
z-index: 1;
&::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://tnuiimage.tnkjapp.com/cool_bg_image/icon_bg6.png);
}
}
}
}
</style>
+377
View File
@@ -0,0 +1,377 @@
<template>
<view class="components-select">
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed>Select列选择器</tn-nav-bar>
<!-- 页面内容 -->
<view :style="{paddingTop: vuex_custom_bar_height + 'px'}">
<dynamic-demo-template ref="demoTemplate" :tips="tips" :sectionList="sectionList" :full="false" @click="click">
<view class="tn-flex tn-flex-row-center"><tn-button fontColor="tn-color-white" @click="showSelect">弹出Select</tn-button></view>
<view class="select-result tn-border-dashed">
{{ result }}
</view>
</dynamic-demo-template>
</view>
<!-- select -->
<tn-select
v-model="show"
:mode="mode"
title="请选择数据"
:list="list"
:maskCloseable="maskCloseable"
@cancel="cancelSelect"
@confirm="confirmSelect"
>
</tn-select>
</view>
</template>
<script>
import dynamicDemoTemplate from '@/libs/components/dynamic-demo-template.vue'
export default {
name: 'componentsSelect',
components: {dynamicDemoTemplate},
data() {
return {
result: 'Select结果',
show: false,
mode: 'single',
list: [
{
value: 1,
label: '哆啦A梦'
},
{
value: 2,
label: '大熊'
},
{
value: 3,
label: '小夫'
},
{
value: 4,
label: '静香'
},
{
value: 5,
label: '胖虎'
}
],
maskCloseable: true,
tips: ['无需依赖额外的样式文件','使用tn-select组件'],
sectionList: [
{
name: '参数切换',
section: [
{
title: '模式',
optional: ['单列','多列','自动多列'],
methods: 'modeChange'
},
{
title: '点击遮罩关闭',
optional: ['是','否'],
methods: 'maskCloseableChange'
}
]
}
]
}
},
methods: {
click(event) {
this[event.methods] && this[event.methods](event)
},
// 弹出Select
showSelect(event) {
this.openSelect()
},
// 切换模式
modeChange(event) {
switch(event.index) {
case 0:
this.mode = 'single'
this.list = [
{
value: 1,
label: '哆啦A梦'
},
{
value: 2,
label: '大熊'
},
{
value: 3,
label: '小夫'
},
{
value: 4,
label: '静香'
},
{
value: 5,
label: '胖虎'
}
]
break
case 1:
this.mode = 'multi'
this.list = [
[
{
value: 1,
label: '哆啦A梦'
},
{
value: 2,
label: '大熊'
},
{
value: 3,
label: '小夫'
},
{
value: 4,
label: '静香'
},
{
value: 5,
label: '胖虎'
},
],
[
{
value: 1,
label: '家'
},
{
value: 2,
label: '学校'
},
{
value: 3,
label: '操场'
}
]
]
break
case 2:
this.mode = 'multi-auto'
this.list = [
{
value: 11,
label: '森林—1',
children: [
{
value: 1101,
label: '树-11',
children: [
{
value: 110101,
label: '树叶-111'
},
{
value: 110102,
label: '树叶-112'
},
{
value: 110103,
label: '树叶-113'
},
{
value: 110104,
label: '树叶-114'
}
]
},
{
value: 1102,
label: '树-12',
children: [
{
value: 110201,
label: '树叶-121'
},
{
value: 110202,
label: '树叶-122'
},
{
value: 110203,
label: '树叶-123'
},
{
value: 110204,
label: '树叶-124'
}
]
},
{
value: 1103,
label: '树-13',
children: [
{
value: 110301,
label: '树叶-131'
},
{
value: 110302,
label: '树叶-132'
},
{
value: 110303,
label: '树叶-133'
},
{
value: 110304,
label: '树叶-134'
}
]
}
]
},
{
value: 12,
label: '森林—2',
children: [
{
value: 1201,
label: '树-21',
children: [
{
value: 120101,
label: '树叶-211'
},
{
value: 120102,
label: '树叶-212'
},
{
value: 120103,
label: '树叶-213'
},
{
value: 120104,
label: '树叶-214'
}
]
},
{
value: 1202,
label: '树-22',
children: [
{
value: 120201,
label: '树叶-221'
},
{
value: 120202,
label: '树叶-222'
},
{
value: 120203,
label: '树叶-223'
},
{
value: 120204,
label: '树叶-224'
}
]
},
{
value: 1203,
label: '树-23',
children: [
{
value: 120301,
label: '树叶-231'
},
{
value: 120302,
label: '树叶-232'
},
{
value: 120303,
label: '树叶-233'
},
{
value: 120304,
label: '树叶-234'
}
]
}
]
}
]
break
}
this.openSelect()
},
// 切换点击遮罩关闭
maskCloseableChange(event) {
this.maskCloseable = event.index === 0 ? true : false
this.openSelect()
},
// 点击取消按钮
cancelSelect(event) {
this.$t.messageUtils.toast('点击了取消按钮')
},
// 点击确认按钮
confirmSelect(event) {
console.log(event);
switch (this.mode) {
case 'single':
this.result = event[0]['label']
break
case 'multi':
this.result = ''
if (event.length) {
event.map((item, index) => {
if (index !== 0) this.result += ' - '
this.result += item.label
})
}
break
case 'multi-auto':
this.result = ''
if (event.length) {
event.map((item, index) => {
if (index !== 0) this.result += ' - '
this.result += item.label
})
}
break
}
},
// 打开Select
openSelect() {
this.show = true
},
},
}
</script>
<style lang="scss" scoped>
.select-result {
margin-top: 10rpx;
padding: 10rpx 30rpx;
background-color: $tn-font-holder-color;
text-align: center;
}
</style>
+134
View File
@@ -0,0 +1,134 @@
<template>
<view class="components-toast">
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed :beforeBack="beforeBack">SignBoard签字板</tn-nav-bar>
<!-- 页面内容 -->
<view :style="{paddingTop: vuex_custom_bar_height + 'px'}">
<dynamic-demo-template ref="demoTemplate" :tips="tips" :sectionList="sectionList" :full="true" @click="click">
<view class="tn-flex tn-flex-direction-column tn-flex-col-center tn-flex-row-center">
<view class="image">
<image v-if="imageSrc" :src="imageSrc" mode="heightFix"></image>
</view>
<view class="button">
<tn-button fontColor="tn-color-white" @click="showSignBoard">弹出签字板</tn-button>
</view>
</view>
</dynamic-demo-template>
</view>
<!-- SignBoard -->
<tn-sign-board :show="show" :customBarHeight="vuex_custom_bar_height" :signSelectColor="signSelectColor" :rotate="rotate" @save="saveSign" @closed="closeSign"></tn-sign-board>
</view>
</template>
<script>
import dynamicDemoTemplate from '@/libs/components/dynamic-demo-template.vue'
export default {
components: {dynamicDemoTemplate},
data() {
return {
show: false,
imageSrc: '',
signSelectColor: ['#080808', '#E83A30'],
rotate: true,
tips: ['无需依赖额外的样式文件','使用tn-sign-board组件'],
sectionList: [
{
name: '参数切换',
section: [
{
title: '画笔颜色',
optional: ['默认','自定义'],
methods: 'colorChange'
},
{
title: '旋转签名',
optional: ['不旋转','旋转'],
methods: 'rotateChange',
current: 1
}
]
}
]
}
},
methods: {
click(event) {
this[event.methods] && this[event.methods](event)
},
// 弹出SignBoard
showSignBoard() {
this.show = true
},
// 切换画笔颜色
colorChange(event) {
switch (event.index) {
case 0:
this.signSelectColor = ['#080808', '#E83A30']
break
case 1:
this.signSelectColor = ['#838383', '#01BEFF']
break
}
this.showSignBoard()
},
// 切换旋转内容
rotateChange(event) {
this.rotate = event.index === 0 ? false : true
this.showSignBoard()
},
// 保存签名
saveSign(e) {
// console.log(e);
this.imageSrc = e
this.show = false
},
// 关闭签名板
closeSign() {
this.show = false
},
// 返回前判断是否已经关闭了签名板
beforeBack() {
return new Promise((resolve, reject) => {
if (!this.show) {
resolve()
return
}
this.$t.messageUtils.modal('操作提示','当前已经打开了签名板,是否确认需要关闭', () => {
resolve()
}, true, () => {
reject()
})
})
}
},
}
</script>
<style lang="scss" scoped>
.image {
height: 200rpx;
image {
height: 200rpx;
}
}
.button {
margin-top: 20rpx;
}
</style>
+198
View File
@@ -0,0 +1,198 @@
<template>
<view class="components-slider">
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed>slider滑动条</tn-nav-bar>
<!-- 页面内容 -->
<view :style="{paddingTop: vuex_custom_bar_height + 'px'}">
<dynamic-demo-template ref="demoTemplate" :tips="tips" :sectionList="sectionList" :full="true" @click="click">
<tn-slider
v-if="useSlot"
v-model="value"
:min="min"
:max="max"
:step="step"
:disabled="disabled"
:blockWidth="blockWidth"
:blockColor="blockColor"
:lineHeight="lineHeight"
:activeColor="activeColor"
:inactiveColor="inactiveColor"
>
<view class="tn-slider__custom-block">
{{ value }}
</view>
</tn-slider>
<tn-slider
v-else
v-model="value"
:min="min"
:max="max"
:step="step"
:disabled="disabled"
:blockWidth="blockWidth"
:blockColor="blockColor"
:lineHeight="lineHeight"
:activeColor="activeColor"
:inactiveColor="inactiveColor"
></tn-slider>
<view class="slider-value">
<view class="slider-value__text">当前选值为{{ value }}</view>
</view>
</dynamic-demo-template>
</view>
</view>
</template>
<script>
import dynamicDemoTemplate from '@/libs/components/dynamic-demo-template.vue'
export default {
name: 'componentsSlider',
components: {dynamicDemoTemplate},
data() {
return {
value: 0,
min: 0,
max: 100,
step: 1,
disabled: false,
blockWidth: 30,
blockColor: '#FFFFFF',
lineHeight: 8,
activeColor: '#01BEFF',
inactiveColor: '#E6E6E6',
useSlot: false,
tips: ['无需依赖额外的样式文件','使用tn-slider组件'],
sectionList: [
{
name: '参数切换',
section: [
{
title: '最小最大值',
optional: ['0-100','20-80'],
methods: 'minMaxChange'
},
{
title: '步进值',
optional: ['1','10','30'],
methods: 'stepChange'
},
{
title: '禁用状态',
optional: ['是','否'],
methods: 'disabledChange',
current: 1
},
{
title: '自定义尺寸',
optional: ['默认','自定义'],
methods: 'customSizeChange'
},
{
title: '自定义颜色',
optional: ['默认','自定义'],
methods: 'customColorChange'
},
{
title: '自定义滑块',
optional: ['默认','自定义'],
methods: 'customSliderBlockChange'
}
]
}
]
}
},
methods: {
click(event) {
this[event.methods] && this[event.methods](event)
},
// 切换最大最小值
minMaxChange(event) {
const value = event.name.split('-')
this.min = Number(value[0])
this.max = Number(value[1])
},
// 切换步进值
stepChange(event) {
this.step = Number(event.name)
},
// 切换禁用状态
disabledChange(event) {
this.disabled = event.index === 0 ? true : false
},
// 切换尺寸
customSizeChange(event) {
switch (event.index) {
case 0:
this.blockWidth = 30
this.lineHeight = 8
break
case 1:
this.blockWidth = 50
this.lineHeight = 12
break
}
this.$refs.demoTemplate.updateSectionScrollView()
},
// 切换颜色
customColorChange(event) {
switch (event.index) {
case 0:
this.activeColor = '#01BEFF'
this.inactiveColor = '#E6E6E6'
break
case 1:
this.activeColor = '#2DE88D'
this.inactiveColor = '#AAAAAA'
break
}
},
// 切换滑块
customSliderBlockChange(event) {
this.useSlot = event.index === 0 ? false : true
this.$refs.demoTemplate.updateSectionScrollView()
}
},
}
</script>
<style lang="scss" scoped>
.slider-value {
width: 100%;
display: flex;
align-items: center;
justify-content: center;
margin-top: 30rpx;
&__text {
width: 260rpx;
padding: 20rpx;
border-radius: 10rpx;
text-align: center;
background-color: $tn-font-holder-color;
}
}
.tn-slider__custom-block {
background-color: $tn-color-orange;
width: auto;
height: 40rpx;
line-height: 40rpx;
padding: 0 5rpx;
border-radius: 50%;
text-align: center;
color: #FFFFFF;
}
</style>
+142
View File
@@ -0,0 +1,142 @@
<template>
<view class="components-steps">
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed>Steps步骤条</tn-nav-bar>
<!-- 页面内容 -->
<view :style="{paddingTop: vuex_custom_bar_height + 'px'}">
<dynamic-demo-template ref="demoTemplate" :tips="tips" :sectionList="sectionList" :full="true" @click="click">
<tn-steps :list="list" :current="current" :mode="mode" :direction="direction" :showTitle="showTitle" :activeColor="activeColor" :inActiveColor="inActiveColor"></tn-steps>
</dynamic-demo-template>
</view>
</view>
</template>
<script>
import dynamicDemoTemplate from '@/libs/components/dynamic-demo-template.vue'
export default {
name: 'componentsSteps',
components: {dynamicDemoTemplate},
data() {
return {
list: [
{name: '第一步'},
{name: '第二步', icon: 'trusty', selectIcon: 'trusty-fill'},
{name: '第三步', icon: 'safe', selectIcon: 'safe-fill'},
{name: '第四步', icon: 'vip', selectIcon: 'vip-fill'}
],
current: 0,
mode: 'dot',
direction: 'row',
showTitle: true,
activeColor: '#01BEFF',
inActiveColor: '#AAAAAA',
tips: ['无需依赖额外的样式文件','使用tn-steps组件'],
sectionList: [
{
name: '参数切换',
section: [
{
title: '步骤',
optional: ['上一步','下一步'],
methods: 'currentChange',
current: 1
},
{
title: '模式',
optional: ['点模式','数值模式','图标模式','点图标模式'],
methods: 'modeChange'
},
{
title: '方向',
optional: ['横向','竖直'],
methods: 'directionChange'
},
{
title: '显示标题',
optional: ['显示','隐藏'],
methods: 'showTitleChange'
},
{
title: '自定义颜色',
optional: ['默认','自定义'],
methods: 'colorChange'
}
]
}
]
}
},
methods: {
click(event) {
this[event.methods] && this[event.methods](event)
},
// 切换步骤
currentChange(event) {
let current = this.current
if (event.index === 0) {
current--
this.current = current < 0 ? 0 : current
} else {
current++
this.current = current > this.list.length ? this.list.length : current
}
},
// 切换模式
modeChange(event) {
switch (event.index) {
case 0:
this.mode = 'dot'
break
case 1:
this.mode = 'number'
break
case 2:
this.mode = 'icon'
break
case 3:
this.mode = 'dotIcon'
break
}
this.$refs.demoTemplate.updateSectionScrollView()
},
// 切换方向
directionChange(event) {
this.direction = event.index === 0 ? 'row' : 'column'
this.$refs.demoTemplate.updateSectionScrollView()
},
// 切换标题情况
showTitleChange(event) {
this.showTitle = event.index === 0 ? true : false
this.$refs.demoTemplate.updateSectionScrollView()
},
// 切换颜色样式
colorChange(event) {
switch(event.index) {
case 0:
this.activeColor = '#01BEFF'
this.inActiveColor = '#AAAAAA'
break
case 1:
this.activeColor = '#24F083'
this.inActiveColor = '#E6E6E6'
break
}
}
},
}
</script>
<style lang="scss" scoped>
</style>
+89
View File
@@ -0,0 +1,89 @@
<template>
<view class="components-sticky" style="height: 200vh;">
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed>sticky吸顶</tn-nav-bar>
<!-- 页面内容 -->
<view :style="{paddingTop: vuex_custom_bar_height + 'px'}">
<dynamic-demo-template ref="demoTemplate" :tips="tips" :sectionList="sectionList" :full="true" :fullWindowsScroll="true" @click="click">
<tn-sticky :offsetTop="offsetTop" :enabled="enabled" :customNavHeight="vuex_custom_bar_height" @fixed="fixed" @unfixed="unfixed">
<view class="sticky-content">图鸟科技</view>
</tn-sticky>
</dynamic-demo-template>
</view>
</view>
</template>
<script>
import dynamicDemoTemplate from '@/libs/components/dynamic-demo-template.vue'
export default {
name: 'componentsSticky',
components: {dynamicDemoTemplate},
data() {
return {
offsetTop: 0,
enabled: true,
tips: ['无需依赖额外的样式文件','使用tn-sticky组件'],
sectionList: [
{
name: '参数切换',
section: [
{
title: '吸顶距离',
optional: ['0','20','100'],
methods: 'offsetTopChange'
},
{
title: '状态',
optional: ['允许吸顶', '不吸顶'],
methods: 'enabledChange'
}
]
}
]
}
},
methods: {
click(event) {
this[event.methods] && this[event.methods](event)
},
// 切换吸顶距离
offsetTopChange(event) {
this.offsetTop = Number(event.name)
},
// 切换吸顶状态
enabledChange(event) {
this.enabled = event.index === 0 ? true: false
},
// 监听是否吸顶
fixed() {
this.$t.messageUtils.toast('触发吸顶')
},
unfixed() {
this.$t.messageUtils.toast('取消吸顶')
}
},
}
</script>
<style lang="scss" scoped>
.sticky-content {
height: 80rpx;
padding: 0 80rpx;
margin: 0 10rpx;
line-height: 80rpx;
text-align: center;
background-color: $tn-main-color;
border-radius: 10rpx;
}
</style>
@@ -0,0 +1,226 @@
<template>
<view class="components-index-list">
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed>swipeAction滑动菜单</tn-nav-bar>
<!-- 页面内容 -->
<view :style="{paddingTop: vuex_custom_bar_height + 'px'}">
<tn-swipe-action>
<tn-swipe-action-item :options="options1">
<view class="swipe-action__item tn-flex tn-flex-direction-row tn-flex-col-top tn-flex-row-left">
<view class="swipe-action__item__image">
<image src="https://tnuiimage.tnkjapp.com/shop/card.jpg" mode="scaleToFill"></image>
</view>
<view class="swipe-action__item__info tn-flex tn-flex-direction-column tn-flex-col-top tn-flex-row-right">
<view class="swipe-action__item__info__title">
基本使用
</view>
<view class="swipe-action__item__info__desc">
向左滑动即可看到
</view>
</view>
</view>
</tn-swipe-action-item>
</tn-swipe-action>
<view class="tn-padding-bottom"></view>
<tn-swipe-action>
<tn-swipe-action-item :options="options2">
<view class="swipe-action__item tn-flex tn-flex-direction-row tn-flex-col-top tn-flex-row-left">
<view class="swipe-action__item__image">
<image src="https://tnuiimage.tnkjapp.com/shop/card.jpg" mode="scaleToFill"></image>
</view>
<view class="swipe-action__item__info tn-flex tn-flex-direction-column tn-flex-col-top tn-flex-row-right">
<view class="swipe-action__item__info__title">
多菜单
</view>
<view class="swipe-action__item__info__desc">
向左滑动即可看到
</view>
</view>
</view>
</tn-swipe-action-item>
</tn-swipe-action>
<view class="tn-padding-bottom"></view>
<tn-swipe-action>
<tn-swipe-action-item :options="options3">
<view class="swipe-action__item tn-flex tn-flex-direction-row tn-flex-col-top tn-flex-row-left">
<view class="swipe-action__item__image">
<image src="https://tnuiimage.tnkjapp.com/shop/card.jpg" mode="scaleToFill"></image>
</view>
<view class="swipe-action__item__info tn-flex tn-flex-direction-column tn-flex-col-top tn-flex-row-right">
<view class="swipe-action__item__info__title">
带图标菜单
</view>
<view class="swipe-action__item__info__desc">
向左滑动即可看到
</view>
</view>
</view>
</tn-swipe-action-item>
</tn-swipe-action>
<view class="tn-padding-bottom"></view>
<tn-swipe-action>
<tn-swipe-action-item :options="options4">
<view class="swipe-action__item tn-flex tn-flex-direction-row tn-flex-col-top tn-flex-row-left">
<view class="swipe-action__item__image">
<image src="https://tnuiimage.tnkjapp.com/shop/card.jpg" mode="scaleToFill"></image>
</view>
<view class="swipe-action__item__info tn-flex tn-flex-direction-column tn-flex-col-top tn-flex-row-right">
<view class="swipe-action__item__info__title">
单图标菜单
</view>
<view class="swipe-action__item__info__desc">
向左滑动即可看到
</view>
</view>
</view>
</tn-swipe-action-item>
</tn-swipe-action>
<view class="tn-padding-bottom"></view>
<tn-swipe-action>
<tn-swipe-action-item v-for="(item,index) in 2" :key="index" :name="index" :options="options2">
<view class="swipe-action__item tn-flex tn-flex-direction-row tn-flex-col-top tn-flex-row-left">
<view class="swipe-action__item__image">
<image src="https://tnuiimage.tnkjapp.com/shop/card.jpg" mode="scaleToFill"></image>
</view>
<view class="swipe-action__item__info tn-flex tn-flex-direction-column tn-flex-col-top tn-flex-row-right">
<view class="swipe-action__item__info__title">
关联打开滑动菜单
</view>
<view class="swipe-action__item__info__desc">
向左滑动即可看到同时只能打开一个菜单
</view>
</view>
</view>
</tn-swipe-action-item>
</tn-swipe-action>
<view class="tn-padding-bottom"></view>
<tn-swipe-action :autoClose="false">
<tn-swipe-action-item v-for="(item,index) in 2" :key="index" :name="index" :options="options2">
<view class="swipe-action__item tn-flex tn-flex-direction-row tn-flex-col-top tn-flex-row-left">
<view class="swipe-action__item__image">
<image src="https://tnuiimage.tnkjapp.com/shop/card.jpg" mode="scaleToFill"></image>
</view>
<view class="swipe-action__item__info tn-flex tn-flex-direction-column tn-flex-col-top tn-flex-row-right">
<view class="swipe-action__item__info__title">
非关联打开滑动菜单
</view>
<view class="swipe-action__item__info__desc">
向左滑动即可看到允许同时打开多个菜单
</view>
</view>
</view>
</tn-swipe-action-item>
</tn-swipe-action>
</view>
</view>
</template>
<script>
export default {
name: 'componentsSwipeAction',
data() {
return {
// 滑动菜单
options1: [{
text: '置顶',
style: {
backgroundColor: '#FFA726'
}
}],
options2: [{
text: '置顶',
style: {
backgroundColor: '#FFA726'
}
},
{
text: '删除',
style: {
backgroundColor: '#E83A30'
}
}
],
options3: [{
text: '置顶',
icon: 'star',
style: {
backgroundColor: '#FFA726'
}
},
{
text: '删除',
icon: 'delete',
style: {
backgroundColor: '#E83A30'
}
}
],
options4: [{
icon: 'star',
style: {
backgroundColor: '#FFA726',
width: '80rpx',
height: '80rpx',
margin: '0 12rpx',
borderRadius: '100rpx'
}
},
{
icon: 'delete',
style: {
backgroundColor: '#E83A30',
width: '80rpx',
height: '80rpx',
margin: '0 12rpx',
borderRadius: '100rpx'
}
}
]
}
},
methods: {
}
}
</script>
<style lang="scss" scoped>
.swipe-action__item {
padding: 10rpx 20rpx;
&__image {
image {
width: 80rpx;
height: 80rpx;
border-radius: 20rpx;
}
}
&__info {
margin-left: 20rpx;
&__title {
font-size: 30rpx;
font-weight: bold;
}
&__desc {
margin-top: 5rpx;
font-size: 22rpx;
color: $tn-font-sub-color;
}
}
}
</style>
+224
View File
@@ -0,0 +1,224 @@
<template>
<view class="components-swiper">
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed>Swiper轮播图</tn-nav-bar>
<!-- 页面内容 -->
<view :style="{paddingTop: vuex_custom_bar_height + 'px'}">
<dynamic-demo-template ref="demoTemplate" :tips="tips" :sectionList="sectionList" :full="true" @click="click">
<tn-swiper
:list="list"
:height="height"
:backgroundColor="backgroundColor"
:title="title"
:titleStyle="titleStyle"
:radius="radius"
:mode="mode"
:indicatorPosition="indicatorPosition"
:effect3d="effect3d"
:effect3dPreviousSpacing="effect3dPreviousSpacing"
:interval="interval"
:duration="duration"
:circular="circular"
></tn-swiper>
</dynamic-demo-template>
</view>
<!-- Toast -->
<tn-toast
ref="toast"
@closed="closedToast"
></tn-toast>
</view>
</template>
<script>
import dynamicDemoTemplate from '@/libs/components/dynamic-demo-template.vue'
export default {
name: 'componentsSwiper',
components: {dynamicDemoTemplate},
data() {
return {
list: [
{image: 'https://tnuiimage.tnkjapp.com/swiper/spring.jpg', title: '春天'},
{image: 'https://tnuiimage.tnkjapp.com/swiper/summer.jpg', title: '夏天'},
{image: 'https://tnuiimage.tnkjapp.com/swiper/autumn.jpg', title: '秋天'}
],
height: 250,
backgroundColor: '',
title: false,
titleStyle: {},
radius: 8,
mode: 'round',
indicatorPosition: 'bottomCenter',
effect3d: false,
effect3dPreviousSpacing: 50,
interval: 3000,
duration: 500,
circular: true,
tips: ['无需依赖额外的样式文件','使用tn-swiper组件'],
sectionList: [
{
name: '参数切换',
section: [
{
title: '指示器模式',
optional: ['方形','圆角方形','点','数值','隐藏'],
methods: 'modeChange',
current: 1
},
{
title: '指示器位置',
optional: ['左上','中上','右上','左下','中下','右下'],
methods: 'indicatorPositionChange',
current: 4
},
{
title: '标题',
optional: ['显示','隐藏'],
methods: 'titleChange',
current: 1
},
{
title: '自定义样式',
optional: ['默认','自定义'],
methods: 'styleChange'
},
{
title: '3d切换效果',
optional: ['开启','关闭'],
methods: 'effect3dChange',
current: 1
},
{
title: '切换时间',
optional: ['默认','5000'],
methods: 'intervalChange'
}
]
}
]
}
},
methods: {
click(event) {
this[event.methods] && this[event.methods](event)
},
// 切换指示器模式
modeChange(event) {
switch (event.index) {
case 0:
this.mode = 'rect'
break
case 1:
this.mode = 'round'
break
case 2:
this.mode = 'dot'
break
case 3:
this.mode = 'number'
break
case 4:
this.mode = ''
break
}
},
// 切换指示器位置
indicatorPositionChange(event) {
switch (event.index) {
case 0:
this.indicatorPosition = 'topLeft'
break
case 1:
this.indicatorPosition = 'topCenter'
break
case 2:
this.indicatorPosition = 'topRight'
break
case 3:
this.indicatorPosition = 'bottomLeft'
break
case 4:
this.indicatorPosition = 'bottomCenter'
break
case 5:
this.indicatorPosition = 'bottomRight'
break
}
},
// 切换标题
titleChange(event) {
this.title = event.index === 0 ? true : false
},
// 切换自定义样式
styleChange(event) {
switch (event.index) {
case 0:
this.height = 250
this.backgroundColor = ''
this.titleStyle = {}
this.radius = 8
this.effect3dPreviousSpacing = 50
break
case 1:
this.height = 300
this.backgroundColor = '#E6E6E6'
this.titleStyle = {
color: '#FFFFFF'
}
this.radius = 12
this.effect3dPreviousSpacing = 100
break
}
},
// 切换3d效果
effect3dChange(event) {
this.effect3d = event.index === 0 ? true : false
},
// 切换切换时间
intervalChange(event) {
switch (event.index) {
case 0:
this.interval = 3000
this.duration = 500
break
case 1:
this.interval = 5000
this.duration = 800
break
}
},
// 打开Toast
openToast() {
this.$refs.toast.show({
title: this.title,
content: this.content,
icon: this.icon,
image: this.image,
duration: this.duration
})
},
// 关闭Toast
closedToast() {
this.$t.messageUtils.toast('Toast关闭')
}
},
}
</script>
<style lang="scss" scoped>
</style>
+131
View File
@@ -0,0 +1,131 @@
<template>
<view class="components-switch">
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed>Switch开光</tn-nav-bar>
<!-- 页面内容 -->
<view :style="{paddingTop: vuex_custom_bar_height + 'px'}">
<dynamic-demo-template ref="demoTemplate" :tips="tips" :sectionList="sectionList" :full="false" @click="click">
<tn-switch
v-model="value"
:shape="shape"
:size="size"
:activeColor="color"
:disabled="disabled"
:loading="loading"
:leftIcon="leftIcon"
:rightIcon="rightIcon"
></tn-switch>
</dynamic-demo-template>
</view>
</view>
</template>
<script>
import dynamicDemoTemplate from '@/libs/components/dynamic-demo-template.vue'
export default {
name: 'componentsSwitch',
components: {dynamicDemoTemplate},
data() {
return {
value: false,
shape: 'circle',
color: '',
size: 50,
disabled: false,
loading: false,
leftIcon: '',
rightIcon: '',
tips: ['无需依赖额外的样式文件','使用tn-switch组件'],
sectionList: [
{
name: '参数切换',
section: [
{
title: '形状',
optional: ['圆角','方角'],
methods: 'shapeChange'
},
{
title: '禁用',
optional: ['是','否'],
methods: 'disabledChange',
current: 1
},
{
title: '颜色',
optional: ['默认','#A4E82F','#FFA4A4'],
methods: 'colorChange'
},
{
title: '尺寸',
optional: ['40','50','80'],
methods: 'sizeChange',
current: 1
},
{
title: '加载中',
optional: ['是','否'],
methods: 'loadingChange',
current: 1
},
{
title: '显示图标',
optional: ['是','否'],
methods: 'iconChange',
current: 1
}
]
}
]
}
},
methods: {
click(event) {
this[event.methods] && this[event.methods](event)
},
// 切换形状
shapeChange(event) {
this.shape = event.index === 0 ? 'circle' : 'square'
},
// 切换禁用状态
disabledChange(event) {
this.disabled = event.index === 0 ? true : false
},
// 切换颜色
colorChange(event) {
this.color = event.index === 0 ? '' : event.name
},
// 切换尺寸
sizeChange(event) {
this.size = Number(event.name)
},
// 切换加载状态
loadingChange(event) {
this.loading = event.index === 0 ? true : false
},
// 切换图标状态
iconChange(event) {
if (event.index === 0) {
this.leftIcon = 'sex-female'
this.rightIcon = 'sex-male'
} else if (event.index === 1) {
this.leftIcon = ''
this.rightIcon = ''
}
}
},
}
</script>
<style lang="scss" scoped>
</style>
+251
View File
@@ -0,0 +1,251 @@
<template>
<view class="components-tabs">
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed>tabs标签</tn-nav-bar>
<!-- 页面内容 -->
<view :style="{paddingTop: vuex_custom_bar_height + 'px'}">
<dynamic-demo-template ref="demoTemplate" :tips="tips" :sectionList="sectionList" :full="true" @click="click">
<tn-tabs
v-if="show"
:list="list"
:current="current"
:isScroll="isScroll"
:height="height"
:itemWidth="itemWidth"
:activeColor="activeColor"
:inactiveColor="inactiveColor"
:activeItemStyle="activeItemStyle"
:showBar="showBar"
:barWidth="barWidth"
:barHeight="barHeight"
:barStyle="barStyle"
:gutter="gutter"
:badgeOffset="badgeOffset"
@change="tabChange"
></tn-tabs>
</dynamic-demo-template>
</view>
</view>
</template>
<script>
import dynamicDemoTemplate from '@/libs/components/dynamic-demo-template.vue'
export default {
name: 'componentsTabs',
components: {dynamicDemoTemplate},
data() {
return {
show: true,
data: [
{name: '关注', count: 10},
{name: '推荐'},
{name: '热榜', count: '99+'},
{name: '搞笑'},
{name: '视频'},
{name: '科技'},
{name: '音乐'},
{name: '电影'},
{name: '游戏'}
],
list: [],
current: 0,
isScroll: true,
height: 80,
itemWidth: 'auto',
activeColor: '#01BEFF',
inactiveColor: '#080808',
activeItemStyle: {},
showBar: true,
barWidth: 40,
barHeight: 6,
barStyle: {},
gutter: 30,
badgeOffset: [20, 22],
tips: ['无需依赖额外的样式文件','使用tn-tabs组件'],
sectionList: [
{
name: '参数切换',
section: [
{
title: '模式选择',
optional: ['滑动','非滑动'],
methods: 'modeChange'
},
{
title: '标签数量',
optional: ['2','3','4','5'],
methods: 'countChange',
show: false
},
{
title: '显示底部滑块',
optional: ['显示','隐藏'],
methods: 'showBarChange'
},
{
title: '自定义宽高',
optional: ['默认','自定义'],
methods: 'customWidthHeightChange'
},
{
title: '自定义颜色',
optional: ['默认','自定义'],
methods: 'customColorChange'
},
{
title: '自定义样式',
optional: ['默认','自定义'],
methods: 'customStyleChange'
}
]
}
]
}
},
onLoad() {
this.list = this.data
},
methods: {
click(event) {
this[event.methods] && this[event.methods](event)
},
// 切换模式
modeChange(event) {
this.show = false
this.current = 0
this.isScroll = event.index === 0 ? true : false
if (event.index === 0) {
this.list = this.data
this.badgeOffset = [20, 22]
this.$refs.demoTemplate.updateSectionBtnsState(1, false)
} else if (event.index === 1) {
this.$refs.demoTemplate.updateSectionBtnsState(1, true)
this.$refs.demoTemplate.updateSectionBtnsValue(0, 1, 0)
this.countChange({index: 0, name: 2})
}
this.$nextTick(() => {
this.show = true
})
},
// 切换标签数量
countChange(event) {
this.show = false
this.list = this.data.slice(0, Number(event.name))
switch (event.index) {
case 0:
this.badgeOffset = [20, 120]
break
case 1:
this.badgeOffset = [20, 70]
break
case 2:
this.badgeOffset = [20, 50]
break
case 3:
this.badgeOffset = [20, 22]
break
}
this.$nextTick(() => {
this.show = true
})
},
// 切换底部滑块显示
showBarChange(event) {
this.show = false
this.showBar = event.index === 0 ? true : false
this.$nextTick(() => {
this.show = true
})
},
// 切换自定义宽高
customWidthHeightChange(event) {
this.show = false
switch(event.index) {
case 0:
this.height = 80
this.itemWidth = 'auto'
this.barWidth = 40
this.barHeight = 6
this.gutter = 30
break
case 1:
this.height = 100
this.itemWidth = '40%'
this.barWidth = 130
this.barHeight = 4
this.gutter = 10
break
}
this.$nextTick(() => {
this.show = true
this.$refs.demoTemplate.updateSectionScrollView()
})
},
// 切换颜色
customColorChange(event) {
this.show = false
switch(event.index) {
case 0:
this.activeColor = '#01BEFF'
this.inactiveColor = '#080808'
break
case 1:
this.activeColor = '#31E749'
this.inactiveColor = '#AAAAAA'
break
}
this.$nextTick(() => {
this.show = true
})
},
// 切换自定义样式
customStyleChange(event) {
this.show = false
switch(event.index) {
case 0:
this.activeItemStyle = {}
this.barStyle = {}
break
case 1:
this.activeItemStyle = {
borderTop: '1rpx solid #E6E6E6'
}
this.barStyle = {
boxShadow: `6rpx 6rpx 8rpx ${this.activeColor}`
}
break
}
this.$nextTick(() => {
this.show = true
})
},
// tab选项卡切换
tabChange(index) {
this.current = index
}
},
}
</script>
<style lang="scss" scoped>
</style>
+223
View File
@@ -0,0 +1,223 @@
<template>
<view class="components-time-line">
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed>Timeline时间轴</tn-nav-bar>
<!-- 页面内容 -->
<view :style="{paddingTop: vuex_custom_bar_height + 'px'}">
<view class="time-line__wrap">
<tn-time-line>
<block v-for="(item, index) in expressData" :key="index">
<tn-time-line-item v-if="item.status !== 0" :top="2">
<template slot="node">
<view class="time-line-item__node">
<view v-if="item.status === 1" class="time-line-item__node--icon tn-icon-image-text"></view>
<view v-if="item.status === 2" class="time-line-item__node--icon tn-icon-prize"></view>
<view v-if="item.status === 3" class="time-line-item__node--icon tn-icon-gift"></view>
<view v-if="item.status === 4" class="time-line-item__node--icon tn-icon-logistics"></view>
<view v-if="item.status === 5" class="time-line-item__node--icon tn-icon-my"></view>
<view v-if="item.status === 6" class="time-line-item__node--icon tn-icon-cardbag"></view>
<view v-if="item.status === 7" class="time-line-item__node--icon tn-icon-success"></view>
</view>
</template>
<template slot="content">
<view>
<view v-if="item.status === 1" class="time-line-item__content__title">已下单</view>
<view v-if="item.status === 2" class="time-line-item__content__title">已发货</view>
<view v-if="item.status === 3" class="time-line-item__content__title">已揽件</view>
<view v-if="item.status === 4" class="time-line-item__content__title">运输中</view>
<view v-if="item.status === 5" class="time-line-item__content__title">派送中</view>
<view v-if="item.status === 6" class="time-line-item__content__title">待取件</view>
<view v-if="item.status === 7" class="time-line-item__content__title">已签收</view>
<view class="time-line-item__content__desc">{{ item.info }}</view>
<view class="time-line-item__content__time">{{ item.time }}</view>
</view>
</template>
</tn-time-line-item>
<tn-time-line-item v-else>
<template slot="content">
<view>
<view class="time-line-item__content__desc">{{ item.info }}</view>
<view class="time-line-item__content__time">{{ item.time }}</view>
</view>
</template>
</tn-time-line-item>
</block>
</tn-time-line>
</view>
</view>
</view>
</template>
<script>
export default {
name: 'componentsTimeline',
data() {
return {
expressData: [
{
info: '派送成功',
status: 7,
time: '2021-11-11 17:42'
},
{
info: '[代收点] 您的快件已从XXX顺丰速运代理店取出〖来自代收点〗',
status: 0,
time: '2021-11-11 17:31'
},
{
info: '快件领取成功',
status: 0,
time: '2021-11-11 17:31'
},
{
info: '[代收点] 您的顺丰速运包裹已由XXX顺丰速运代理店代收,代收点地址:XXX, 联系电话:18888888888 〖来自代收点〗',
status: 6,
time: '2021-11-11 17:15'
},
{
info: '快件交给XXX,正在派送途中(联系电话:18888888888,顺丰已开启“安全呼叫”保护您的电话隐私,请放心接听!)(主单总件数:1件)',
status: 5,
time: '2021-11-11 17:07'
},
{
info: '快件到达〖XXX合作点〗',
status: 4,
time: '2021-11-11 16:25'
},
{
info: '快件在〖XXX营业点〗完成分拣,准备发往〖XXX合作点〗',
status: 0,
time: '2021-11-11 13:50'
},
{
info: '快件到达〖XXX营业点〗',
status: 0,
time: '2021-11-11 13:06'
},
{
info: '快件在〖XXX集散点〗完成分拣,准备发往〖XXX营业点〗',
status: 0,
time: '2021-11-11 12:04'
},
{
info: '快件到达〖XXX集散点〗',
status: 0,
time: '2021-11-11 10:14'
},
{
info: '快件在〖XXX中转场〗完成分拣,准备发往〖XXX集散点〗',
status: 0,
time: '2021-11-11 05:52'
},
{
info: '快件到达〖XXX转场〗',
status: 0,
time: '2021-11-11 05:36'
},
{
info: '快件在〖XXX中转场〗完成分拣,准备发往〖XXX中转场〗',
status: 0,
time: '2021-11-10 23:36'
},
{
info: '快件到达〖XXX中转场〗',
status: 0,
time: '2021-11-10 22:34'
},
{
info: '快件在〖XXX营业部〗完成分拣,准备发往〖XXX中转场〗',
status: 0,
time: '2021-11-10 22:01'
},
{
info: '顺丰速运已收取快件',
status: 3,
time: '2021-11-10 21:54'
},
{
info: '包裹正在等待揽收',
status: 1,
time: '2021-11-10 17:41'
},
{
info: '商品已经下单',
status: 1,
time: '2021-11-10 12:17'
}
]
}
},
methods: {
}
}
</script>
<style lang="scss" scoped>
.tn-time-line-class {
.tn-time-line-item-class {
&:first-child {
.tn-time-line-item__node {
.time-line-item__node {
background-color: $tn-main-color !important;
}
}
}
}
}
.time-line {
&__wrap {
padding: 60rpx 30rpx 30rpx 60rpx;
}
&-item {
&__node {
width: 44rpx;
height: 44rpx;
border-radius: 100rpx;
display: flex;
align-items: center;
justify-content: center;
background-color: #AAAAAA;
&--active {
background-color: $tn-main-color;
}
&--icon {
color: #FFFFFF;
font-size: 24rpx;
}
}
&__content {
&__title {
font-weight: bold;
font-size: 32rpx;
}
&__desc {
color: $tn-font-sub-color;
font-size: 28rpx;
margin-bottom: 6rpx;
}
&__time {
color: $tn-font-holder-color;
font-size: 26rpx;
}
}
}
}
</style>
+133
View File
@@ -0,0 +1,133 @@
<template>
<view class="components-tips">
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed>提示信息框</tn-nav-bar>
<!-- 页面内容 -->
<view :style="{paddingTop: vuex_custom_bar_height + 'px'}">
<dynamic-demo-template ref="demoTemplate" :tips="tips" :sectionList="sectionList" :full="false" @click="click">
<tn-button fontColor="tn-color-white" @click="showTips">弹出Tips</tn-button>
</dynamic-demo-template>
</view>
<!-- Tips -->
<tn-tips
ref="tips"
:position="position"
:top="vuex_custom_bar_height"
@close="closeTips"
></tn-tips>
</view>
</template>
<script>
import dynamicDemoTemplate from '@/libs/components/dynamic-demo-template.vue'
export default {
name: 'componentsTips',
components: {dynamicDemoTemplate},
data() {
return {
msg: '这是一条信息',
backgroundColor: '',
fontColor: '',
duration: 2000,
position: '',
tips: ['无需依赖额外的样式文件','使用tn-tips组件'],
sectionList: [
{
name: '参数切换',
section: [
{
title: '自定义颜色',
optional: ['默认','自定义'],
methods: 'colorChange'
},
{
title: '弹出位置',
optional: ['默认','顶部','中间','底部'],
methods: 'positionChange'
},
{
title: '关闭时间',
optional: ['默认','5000'],
methods: 'durationChange'
}
]
}
]
}
},
methods: {
click(event) {
this[event.methods] && this[event.methods](event)
},
// 弹出Tips
showTips() {
this.openTips()
},
// 切换弹出位置
positionChange(event) {
switch(event.index) {
case 0:
this.position = ''
break
case 1:
this.position = 'top'
break
case 2:
this.position = 'center'
break
case 3:
this.position = 'bottom'
break
}
this.openTips()
},
// 切换颜色
colorChange(event) {
if (event.index === 0) {
this.backgroundColor = ''
this.fontColor = ''
} else {
this.backgroundColor = 'tn-bg-gray--light'
this.fontColor = '#E83A30'
}
this.openTips()
},
// 切换Tips关闭时间
durationChange(event) {
this.duration = event.index === 0 ? 2000 : Number(event.name)
this.openTips()
},
// 打开Tips
openTips() {
this.$refs.tips.show({
msg: this.msg,
backgroundColor: this.backgroundColor,
fontColor: this.fontColor,
duration: this.duration
})
},
// 关闭Tips
closeTips() {
this.$t.messageUtils.toast('tips提示框关闭了')
}
},
}
</script>
<style lang="scss" scoped>
</style>
+139
View File
@@ -0,0 +1,139 @@
<template>
<view class="components-toast">
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed>Toast</tn-nav-bar>
<!-- 页面内容 -->
<view :style="{paddingTop: vuex_custom_bar_height + 'px'}">
<dynamic-demo-template ref="demoTemplate" :tips="tips" :sectionList="sectionList" :full="false" @click="click">
<tn-button fontColor="tn-color-white" @click="showToast">弹出Toast</tn-button>
</dynamic-demo-template>
</view>
<!-- Toast -->
<tn-toast
ref="toast"
@closed="closedToast"
></tn-toast>
</view>
</template>
<script>
import dynamicDemoTemplate from '@/libs/components/dynamic-demo-template.vue'
export default {
name: 'componentsToast',
components: {dynamicDemoTemplate},
data() {
return {
title: '提示信息',
content: '欢迎使用图鸟UI',
icon: 'balancecar',
image: '',
duration: 2000,
tips: ['无需依赖额外的样式文件','使用tn-toast组件'],
sectionList: [
{
name: '参数切换',
section: [
{
title: '标题',
optional: ['无标题','有标题'],
methods: 'titleChange',
current: 1
},
{
title: '内容',
optional: ['无内容','有内容'],
methods: 'contentChange',
current: 1
},
{
title: '图标',
optional: ['无图标','balancecar','图片'],
methods: 'iconChange',
current: 1
},
{
title: '关闭时间',
optional: ['默认','5000'],
methods: 'durationChange'
}
]
}
]
}
},
methods: {
click(event) {
this[event.methods] && this[event.methods](event)
},
// 弹出Toast
showToast() {
this.openToast()
},
// 切换Toast标题
titleChange(event) {
this.title = event.index === 0 ? '' : '提示信息'
this.openToast()
},
// 切换Toast内容
contentChange(event) {
this.content = event.index === 0 ? '' : '欢迎使用图鸟UI'
this.openToast()
},
// 切换Toast图标
iconChange(event) {
switch (event.index) {
case 0:
this.icon = ''
this.image = ''
break
case 1:
this.icon = event.name
this.image = ''
break
case 2:
this.icon = ''
this.image = '/static/logo1.png'
break
}
this.openToast()
},
// 切换Toast关闭时间
durationChange(event) {
this.duration = event.index === 0 ? 2000 : Number(event.name)
this.openToast()
},
// 打开Toast
openToast() {
this.$refs.toast.show({
title: this.title,
content: this.content,
icon: this.icon,
image: this.image,
duration: this.duration
})
},
// 关闭Toast
closedToast() {
this.$t.messageUtils.toast('Toast关闭')
}
},
}
</script>
<style lang="scss" scoped>
</style>
@@ -0,0 +1,158 @@
<template>
<view class="components-verification_code">
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed>验证码倒计时</tn-nav-bar>
<!-- 页面内容 -->
<view :style="{paddingTop: vuex_custom_bar_height + 'px'}">
<dynamic-demo-template ref="demoTemplate" :tips="tips" :sectionList="sectionList" :full="true" @click="click">
<view class="tn-flex tn-flex-row-center tn-flex-wrap">
<view style="width: 100%;">
<tn-form :labelWidth="120" :borderBottom="true">
<tn-form-item label="验证码">
<tn-input></tn-input>
<view slot="right">
<tn-button fontColor="tn-color-white" @click="getCode">{{ tips }}</tn-button>
</view>
</tn-form-item>
</tn-form>
</view>
<view style="width: 100%;">
<tn-button width="100%" backgroundColor="tn-bg-red" fontColor="tn-color-white" margin="30rpx 0 0 0" style="width: 100%;" @click="reset">重置</tn-button>
</view>
</view>
</dynamic-demo-template>
</view>
<!-- verification-code -->
<tn-verification-code
ref="code"
:keepRunning="keepRunning"
:seconds="seconds"
:startText="startText"
:countDownText="countDownText"
:endText="endText"
@end="codeEnd"
@start="codeStart"
@change="codeChange"
>
</tn-verification-code>
</view>
</template>
<script>
import dynamicDemoTemplate from '@/libs/components/dynamic-demo-template.vue'
export default {
name: 'componentsVerificationCode',
components: {dynamicDemoTemplate},
data() {
return {
tips: '获取验证码',
keepRunning: true,
seconds: 60,
startText: '获取验证码',
countDownText: 's秒后重新获取',
endText: '重新获取',
tips: ['无需依赖额外的样式文件','使用tn-verification-code组件'],
sectionList: [
{
name: '参数切换',
section: [
{
title: '倒计时间',
optional: ['60s','30s','5s'],
methods: 'secondsChange'
},
{
title: '退出后保持运行',
optional: ['是','否'],
methods: 'keepRunningChange'
},
{
title: '自定义提示语',
optional: ['默认','自定义'],
methods: 'customTitleChange'
}
]
}
]
}
},
methods: {
click(event) {
this[event.methods] && this[event.methods](event)
},
// 切换倒计时间
secondsChange(event) {
this.seconds = Number(event.name.replace('s',''))
},
// 切换是否保持
keepRunningChange(event) {
this.keepRunning = event.index === 0 ? true : false
},
// 切换是否使用自定义提示语
customTitleChange(event) {
switch (event.index) {
case 0:
this.startText = '点击获取验证码'
this.countDownText = '重新获取s秒后'
this.endText = '再次获取'
break
case 1:
this.startText = '获取验证码'
this.countDownText = 's秒后重新获取'
this.endText = '重新获取'
break
}
this.reset()
},
// 获取验证码
getCode() {
if (this.$refs.code.canGetCode) {
this.$t.messageUtils.loading('正在获取验证码')
setTimeout(() => {
this.$t.messageUtils.closeLoading()
this.$t.messageUtils.toast('验证码已经发送')
// 通知组件开始计时
this.$refs.code.start()
}, 2000)
} else {
this.$t.messageUtils.toast(this.$refs.code.secNum + '秒后再重试')
}
},
// 重置验证码
reset() {
this.$refs.code.reset()
},
// 开始倒计时
codeStart() {
this.$t.messageUtils.toast('倒计时开始')
},
// 结束倒计时
codeEnd() {
this.$t.messageUtils.toast('倒计时结束')
},
// 正在倒计时
codeChange(event) {
this.tips = event
}
},
}
</script>
<style lang="scss" scoped>
</style>
+14
View File
@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0" />
<title></title>
<!--preload-links-->
<!--app-context-->
</head>
<body>
<div id="app"><!--app-html--></div>
<script type="module" src="/main.js"></script>
</body>
</html>
+680
View File
@@ -0,0 +1,680 @@
<template>
<view class="dynamic-demo">
<!-- 效果预览窗口 -->
<view 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
}
},
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.colorUtils.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 {
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()
}
}
})
},
// 更新选项滑动容器的高度
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(40rpx + 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>
+169
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-7">
<view class="tn-icon-home-vertical-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/index'
}
},
methods: {
// 跳转回首页
navIndex() {
// 通过判断当前页面的页面栈信息,是否有上一页进行返回,如果没有则跳转到首页
const pages = getCurrentPages()
if (pages && pages.length > 0) {
const indexPath = this.indexPath || '/pages/index/index'
const firstPage = pages[0]
if (!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://tnuiimage.tnkjapp.com/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://tnuiimage.tnkjapp.com/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>
+52
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()
}
}
+33
View File
@@ -0,0 +1,33 @@
/**
* 演示页面mixin
*/
module.exports = {
data() {
return {
}
},
methods: {
// 点击左上角返回按钮时触发事件
goBack() {
// 通过判断当前页面的页面栈信息,是否有上一页进行返回,如果没有则跳转到首页
const pages = getCurrentPages()
if (pages && pages.length > 0) {
const firstPage = pages[0]
if (!firstPage.route || firstPage.route != 'pages/index/index') {
uni.reLaunch({
url: '/pages/index/index'
})
} else {
uni.navigateBack({
delta: 1
})
}
} else {
uni.reLaunch({
url: '/pages/index/index'
})
}
}
}
}
+24
View File
@@ -0,0 +1,24 @@
import App from './App'
import store from './store'
import Vue from 'vue'
Vue.config.productionTip = false
App.mpType = 'app'
// 引入全局TuniaoUI
import TuniaoUI from 'tuniao-ui'
Vue.use(TuniaoUI)
// 引入TuniaoUI提供的vuex简写方法
let vuexStore = require('@/store/$t.mixin.js')
Vue.mixin(vuexStore)
// 引入TuniaoUI对小程序分享的mixin封装
let mpShare = require('tuniao-ui/libs/mixin/mpShare.js')
Vue.mixin(mpShare)
const app = new Vue({
store,
...App
})
app.$mount()
+86
View File
@@ -0,0 +1,86 @@
{
"name" : "TuniaoUI_UniApp_Opensource",
"appid" : "__UNI__C82400B",
"description" : "TuniaoUI 开源版本",
"versionName" : "1.0.0",
"versionCode" : "100",
"transformPx" : false,
/* 5+App */
"app-plus" : {
"usingComponents" : true,
"nvueStyleCompiler" : "uni-app",
"compilerVersion" : 3,
"splashscreen" : {
"alwaysShowBeforeRender" : true,
"waiting" : true,
"autoclose" : true,
"delay" : 0
},
/* */
"modules" : {},
/* */
"distribute" : {
/* android */
"android" : {
"permissions" : [
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
]
},
/* ios */
"ios" : {},
/* SDK */
"sdkConfigs" : {}
}
},
/* */
"quickapp" : {},
/* */
"mp-weixin" : {
"appid" : "wxf3d81a452b88ff4b",
"setting" : {
"urlCheck" : false,
"es6" : true
},
"usingComponents" : true,
"optimization" : {
"subPackages" : true
}
},
"mp-alipay" : {
"usingComponents" : true
},
"mp-baidu" : {
"usingComponents" : true
},
"mp-toutiao" : {
"usingComponents" : true
},
"uniStatistics" : {
"enable" : false
},
"vueVersion" : "2",
"h5" : {
"template" : "template.h5.html",
"title" : "Tuniao UI",
"router" : {
"mode" : "hash"
},
"sdkConfigs" : {
"maps" : {}
}
}
}
+57
View File
@@ -0,0 +1,57 @@
/**
* 页面展示列表数据
*/
export default {
data: [
{
icon: 'menu-more',
title: 'Flex布局',
url: '/basicPage/flex-layout/flex-layout'
},
{
icon: 'menu-circle',
title: 'Grid布局',
url: '/basicPage/grid-layout/grid-layout'
},
{
icon: 'gloves',
title: '配色',
url: '/basicPage/color/color'
},
{
icon: 'topics',
title: '图标',
url: '/basicPage/icon/icon'
},
{
icon: 'circle-fill',
title: '按钮',
url: '/basicPage/button/button'
},
{
icon: 'tag',
title: '标签',
url: '/basicPage/tag/tag'
},
{
icon: 'square',
title: '边框',
url: '/basicPage/border/border'
},
{
icon: 'copy-fill',
title: '阴影',
url: '/basicPage/shadow/shadow'
},
{
icon: 'moon',
title: '微标',
url: '/basicPage/badge/badge'
},
{
icon: 'emoji-good',
title: '头像',
url: '/basicPage/avatar/avatar'
}
]
}
+206
View File
@@ -0,0 +1,206 @@
/**
* 页面展示列表数据
*/
export default {
data: [
{
title: '基础组件',
backgroundColor: 'tn-cool-bg-color-1',
list: [
{
icon: 'signpost',
title: '列表',
url: '/componentsPage/list/list'
},
{
icon: 'circle-arrow',
title: 'Loading加载',
url: '/componentsPage/loading/loading'
},
{
icon: 'share',
title: 'tabs标签',
url: '/componentsPage/tabs/tabs'
},
{
icon: 'receipt',
title: 'sticky吸顶',
url: '/componentsPage/sticky/sticky'
},
{
icon: 'all',
title: 'navBar导航栏',
url: '/componentsPage/nav-bar/nav-bar'
},
{
icon: 'sound',
title: 'noticeBar通知栏',
url: '/componentsPage/notice-bar/notice-bar'
},
{
icon: 'image',
title: 'swiper轮播图',
url: '/componentsPage/swiper/swiper'
},
{
icon: 'server',
title: 'collapse折叠面板',
url: '/componentsPage/collapse/collapse'
},
{
icon: 'more-circle',
title: 'readMore查看更多',
url: '/componentsPage/read-more/read-more'
},
{
icon: 'success-square',
title: 'steps步骤条',
url: '/componentsPage/steps/steps'
},
{
icon: 'clock',
title: 'timeLine时间轴',
url: '/componentsPage/time-line/time-line'
},
{
icon: 'level',
title: 'indexList索引列表',
url: '/componentsPage/index-list/index-list'
},
{
icon: 'group-square',
title: 'scrollList横向滚动',
url: '/componentsPage/scroll-list/scroll-list'
},
{
icon: 'star',
title: 'swipeAction滑动菜单',
url: '/componentsPage/swipe-action/swipe-action'
}
]
},
{
title: '弹框组件',
backgroundColor: 'tn-cool-bg-color-1',
list: [
{
icon: 'prize',
title: '弹出层',
url: '/componentsPage/popup/popup'
},
{
icon: 'bankcard',
title: '模态框',
url: '/componentsPage/modal/modal'
},
{
icon: 'comment',
title: 'Toast',
url: '/componentsPage/toast/toast'
},
{
icon: 'creative',
title: '提示信息框',
url: '/componentsPage/tips/tips'
},
]
},
{
title: '表单组件',
backgroundColor: 'tn-cool-bg-color-1',
list: [
{
icon: 'image-text',
title: 'Form表单',
url: '/componentsPage/form/form'
},
{
icon: 'ticket',
title: 'ActionSheet操作菜单',
url: '/componentsPage/action-sheet/action-sheet'
},
{
icon: 'deploy',
title: 'Picker选择器',
url: '/componentsPage/picker/picker'
},
{
icon: 'organizatio',
title: 'Select列选择器',
url: '/componentsPage/select/select'
},
{
icon: 'data',
title: '验证码倒计时',
url: '/componentsPage/verification-code/verification-code'
},
{
icon: 'power',
title: 'Switch开关',
url: '/componentsPage/switch/switch'
},
{
icon: 'upload',
title: '图片上传',
url: '/componentsPage/image-upload/image-upload'
},
{
icon: 'calendar',
title: '日历',
url: '/componentsPage/calendar/calendar'
},
{
icon: 'edit-write',
title: '签名板',
url: '/componentsPage/sign-board/sign-board'
},
]
},
{
title: '数据组件',
backgroundColor: 'tn-cool-bg-color-1',
list: [
{
icon: 'watercup',
title: 'Progress进度条',
url: '/componentsPage/progress/progress'
},
{
icon: 'star',
title: 'rate评分',
url: '/componentsPage/rate/rate'
},
{
icon: 'light',
title: 'slider滑动条',
url: '/componentsPage/slider/slider'
},
{
icon: 'statistics',
title: 'numberBox步进输入',
url: '/componentsPage/number-box/number-box'
},
{
icon: 'keyboard-circle',
title: 'keyboard键盘',
url: '/componentsPage/keyboard/keyboard'
},
{
icon: 'time',
title: 'countDown倒计时',
url: '/componentsPage/count-down/count-down'
},
{
icon: 'group-circle',
title: 'countTo数字跳转',
url: '/componentsPage/count-to/count-to'
},
{
icon: 'sequence-vertical',
title: 'countScroll数字滚动',
url: '/componentsPage/count-scroll/count-scroll'
}
]
}
]
}
+107
View File
@@ -0,0 +1,107 @@
/**
* 页面展示列表数据
*/
export default {
data: [
{
title: '登录注册',
backgroundColor: 'tn-cool-bg-color-1',
list: [
{
icon: 'order',
title: '火箭登录',
url: '/templatePage/login/demo1/demo1'
},
{
icon: 'order',
title: '粒子登录',
url: '/templatePage/login/demo2/demo2'
}
]
},
{
title: '常用首页',
backgroundColor: 'tn-cool-bg-color-1',
list: [
{
icon: 'order',
title: '音乐首页',
url: '/templatePage/home/music/music'
},
{
icon: 'order',
title: '课程首页',
url: '/templatePage/home/course/course'
},
{
icon: 'order',
title: '设计首页',
url: '/templatePage/home/design/design'
},
{
icon: 'order',
title: '招聘首页',
url: '/templatePage/home/job/job'
},
{
icon: 'order',
title: '投屏首页',
url: '/templatePage/home/screen/screen'
},
{
icon: 'order',
title: '壁纸首页',
url: '/templatePage/home/wallpaper/wallpaper'
},
]
},
{
title: '其他页面',
backgroundColor: 'tn-cool-bg-color-1',
list: [
{
icon: 'order',
title: '健康码',
url: '/templatePage/health/qrcode/qrcode'
},
{
icon: 'order',
title: '全屏轮播',
url: '/templatePage/life/fullpage/fullpage'
},
{
icon: 'order',
title: '浏览器',
url: '/templatePage/life/browser/browser'
}
]
},
{
title: '动效元素',
backgroundColor: 'tn-cool-bg-color-1',
list: [
{
icon: 'order',
title: '加载动画',
url: '/templatePage/animate/loading/loading'
},
{
icon: 'order',
title: '随机粒子',
url: '/templatePage/animate/particle/particle'
},
{
icon: 'order',
title: '相册图集',
url: '/templatePage/animate/photo/photo'
},
{
icon: 'order',
title: '镂空效果',
url: '/templatePage/animate/hollow/hollow'
}
]
}
]
}
+418
View File
@@ -0,0 +1,418 @@
{
"easycom": {
"^tn-(.*)": "@/tuniao-ui/components/tn-$1/tn-$1.vue"
},
"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "Tuniao UI",
"enablePullDownRefresh": false
}
}
],
"subPackages": [{
"root": "basicPage",
"pages": [
{
"path": "test/test",
"style": {
"navigationStyle":"default",
"navigationBarTitleText": "测试页面",
"enablePullDownRefresh": false
}
},
{
"path": "flex-layout/flex-layout",
"style": {
"navigationBarTitleText": "Flex布局",
"enablePullDownRefresh": false
}
}, {
"path": "grid-layout/grid-layout",
"style": {
"navigationBarTitleText": "Grid布局",
"enablePullDownRefresh": false
}
}, {
"path": "color/color",
"style": {
"navigationBarTitleText": "配色",
"enablePullDownRefresh": false
}
}, {
"path": "icon/icon",
"style": {
"navigationBarTitleText": "图标",
"enablePullDownRefresh": false
}
}, {
"path": "button/button",
"style": {
"navigationBarTitleText": "按钮",
"enablePullDownRefresh": false
}
}, {
"path": "tag/tag",
"style": {
"navigationBarTitleText": "标签",
"enablePullDownRefresh": false
}
}, {
"path": "border/border",
"style": {
"navigationBarTitleText": "边框",
"enablePullDownRefresh": false
}
}, {
"path": "shadow/shadow",
"style": {
"navigationBarTitleText": "阴影",
"enablePullDownRefresh": false
}
}, {
"path": "badge/badge",
"style": {
"navigationBarTitleText": "微标",
"enablePullDownRefresh": false
}
}, {
"path": "avatar/avatar",
"style": {
"navigationBarTitleText": "头像",
"enablePullDownRefresh": false
}
}
]
},{
"root": "componentsPage",
"pages": [
{
"path": "list/list",
"style": {
"navigationBarTitleText": "列表",
"enablePullDownRefresh": false
}
}, {
"path": "popup/popup",
"style": {
"navigationBarTitleText": "弹出层",
"enablePullDownRefresh": false
}
}, {
"path": "modal/modal",
"style": {
"navigationBarTitleText": "模态框",
"enablePullDownRefresh": false
}
}, {
"path": "toast/toast",
"style": {
"navigationBarTitleText": "Toast",
"enablePullDownRefresh": false
}
}, {
"path": "tips/tips",
"style": {
"navigationBarTitleText": "提示信息",
"enablePullDownRefresh": false
}
}, {
"path": "form/form",
"style": {
"navigationBarTitleText": "Form表单",
"enablePullDownRefresh": false
}
}, {
"path": "action-sheet/action-sheet",
"style": {
"navigationBarTitleText": "操作菜单",
"enablePullDownRefresh": false
}
}, {
"path": "picker/picker",
"style": {
"navigationBarTitleText": "Picker选择器",
"enablePullDownRefresh": false
}
}, {
"path": "select/select",
"style": {
"navigationBarTitleText": "Select列选择器",
"enablePullDownRefresh": false
}
}, {
"path": "verification-code/verification-code",
"style": {
"navigationBarTitleText": "验证码倒计时",
"enablePullDownRefresh": false
}
}, {
"path": "loading/loading",
"style": {
"navigationBarTitleText": "Loading加载",
"enablePullDownRefresh": false
}
}, {
"path": "switch/switch",
"style": {
"navigationBarTitleText": "Switch开关",
"enablePullDownRefresh": false
}
}, {
"path": "progress/progress",
"style": {
"navigationBarTitleText": "Progress进度条",
"enablePullDownRefresh": false
}
}, {
"path": "image-upload/image-upload",
"style": {
"navigationBarTitleText": "图片上传",
"enablePullDownRefresh": false
}
}, {
"path": "rate/rate",
"style": {
"navigationBarTitleText": "rate评分",
"enablePullDownRefresh": false
}
}, {
"path": "slider/slider",
"style": {
"navigationBarTitleText": "slider滑动条",
"enablePullDownRefresh": false
}
}, {
"path": "number-box/number-box",
"style": {
"navigationBarTitleText": "numberBox步进输入",
"enablePullDownRefresh": false
}
}, {
"path": "keyboard/keyboard",
"style": {
"navigationBarTitleText": "keyboard键盘",
"enablePullDownRefresh": false
}
}, {
"path": "tabs/tabs",
"style": {
"navigationBarTitleText": "tabs标签",
"enablePullDownRefresh": false
}
}, {
"path": "count-down/count-down",
"style": {
"navigationBarTitleText": "countDown倒计时",
"enablePullDownRefresh": false
}
}, {
"path": "count-to/count-to",
"style": {
"navigationBarTitleText": "countTo数字跳转",
"enablePullDownRefresh": false
}
}, {
"path": "count-scroll/count-scroll",
"style": {
"navigationBarTitleText": "countTo数字滚动",
"enablePullDownRefresh": false
}
}, {
"path": "sticky/sticky",
"style": {
"navigationBarTitleText": "sticky吸顶",
"enablePullDownRefresh": false
}
}, {
"path": "nav-bar/nav-bar",
"style": {
"navigationBarTitleText": "navBar导航栏",
"enablePullDownRefresh": false
}
}, {
"path": "notice-bar/notice-bar",
"style": {
"navigationBarTitleText": "noticeBar通知栏",
"enablePullDownRefresh": false
}
}, {
"path": "swiper/swiper",
"style": {
"navigationBarTitleText": "swiper轮播图",
"enablePullDownRefresh": false
}
}, {
"path": "collapse/collapse",
"style": {
"navigationBarTitleText": "collapse折叠面板",
"enablePullDownRefresh": false
}
}, {
"path": "read-more/read-more",
"style": {
"navigationBarTitleText": "readMore查看更多",
"enablePullDownRefresh": false
}
}, {
"path": "steps/steps",
"style": {
"navigationBarTitleText": "steps步骤条",
"enablePullDownRefresh": false
}
}, {
"path": "time-line/time-line",
"style": {
"navigationBarTitleText": "timeLine时间轴",
"enablePullDownRefresh": false
}
}, {
"path": "index-list/index-list",
"style": {
"navigationBarTitleText": "indexList索引列表",
"enablePullDownRefresh": false
}
}, {
"path": "calendar/calendar",
"style": {
"navigationBarTitleText": "calendar日历",
"enablePullDownRefresh": false
}
}, {
"path": "scroll-list/scroll-list",
"style": {
"navigationBarTitleText": "scrollList横向滚动",
"enablePullDownRefresh": false
}
}, {
"path": "swipe-action/swipe-action",
"style": {
"navigationBarTitleText": "swipeAction滑动菜单",
"enablePullDownRefresh": false
}
}, {
"path": "sign-board/sign-board",
"style": {
"navigationBarTitleText": "signBoard签名板",
"enablePullDownRefresh": false
// "pageOrientation": "landscape"
}
}
]
},{
"root":"templatePage",
"pages": [
{
"path": "login/demo1/demo1",
"style": {
"navigationBarTitleText": "火箭登录",
"enablePullDownRefresh": false
}
},{
"path": "login/demo2/demo2",
"style": {
"navigationBarTitleText": "粒子登录",
"enablePullDownRefresh": false
}
}, {
"path": "health/qrcode/qrcode",
"style": {
"navigationBarTitleText": "健康码",
"enablePullDownRefresh": false
}
}, {
"path": "home/course/course",
"style": {
"navigationBarTitleText": "课程首页",
"enablePullDownRefresh": false
}
}, {
"path": "home/music/music",
"style": {
"navigationBarTitleText": "音乐首页",
"enablePullDownRefresh": false
}
},{
"path": "home/design/design",
"style": {
"navigationBarTitleText": "设计首页",
"enablePullDownRefresh": false
}
}, {
"path": "home/job/job",
"style": {
"navigationBarTitleText": "招聘首页",
"enablePullDownRefresh": false
}
}, {
"path": "home/screen/screen",
"style": {
"navigationBarTitleText": "投屏首页",
"enablePullDownRefresh": false
}
}, {
"path": "home/wallpaper/wallpaper",
"style": {
"navigationBarTitleText": "壁纸首页",
"enablePullDownRefresh": false
}
}, {
"path": "life/fullpage/fullpage",
"style": {
"navigationBarTitleText": "全屏轮播",
"enablePullDownRefresh": false
}
},{
"path": "life/plus/plus",
"style": {
"navigationBarTitleText": "会员协议",
"enablePullDownRefresh": false
}
},{
"path": "life/browser/browser",
"style": {
"navigationBarTitleText": "浏览器",
"enablePullDownRefresh": false
}
},{
"path": "animate/loading/loading",
"style": {
"navigationBarTitleText": "加载动效",
"enablePullDownRefresh": false
}
}, {
"path": "animate/particle/particle",
"style": {
"navigationBarTitleText": "随机粒子",
"enablePullDownRefresh": false
}
}, {
"path": "animate/photo/photo",
"style": {
"navigationBarTitleText": "相册图集",
"enablePullDownRefresh": false
}
}, {
"path": "animate/hollow/hollow",
"style": {
"navigationBarTitleText": "镂空效果",
"enablePullDownRefresh": false
}
}
]
}],
"preloadRule": {
"pages/index/index": {
"network":"all",
"packages": ["basicPage","componentsPage","templatePage"]
}
},
"globalStyle": {
"navigationStyle": "custom",
"navigationBarTextStyle": "black",
"navigationBarTitleText": "Tuniao UI",
"navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8"
}
}
+157
View File
@@ -0,0 +1,157 @@
<template>
<view class="basic">
<view class="top-backgroup">
<image src='https://tnuiimage.tnkjapp.com/index_bg/basic_new.jpg' mode='widthFix' class='backgroud-image'></image>
</view>
<view class="nav_title--wrap tn-margin-bottom-sm">
<view class="nav_title tn-cool-bg-color-15"> / / / </view>
</view>
<view class='nav-list tn-margin-bottom'>
<block v-for="(item, index) in navList" :key="index">
<navigator
open-type="navigate"
hover-class='none'
:url="item.url"
class="nav-list-item tn-shadow-blur tn-cool-bg-image"
:class="[
getRandomCoolBg(index)
]"
>
<view class="nav-link">
<view class='title'>{{ item.title }}</view>
</view>
<view class="icon">
<view :class="['tn-icon-' + item.icon]"></view>
</view>
</navigator>
</block>
</view>
</view>
</template>
<script>
import basicListData from '@/mock/basic_page.js'
export default {
name: 'Basic',
data() {
return {
// nav菜单列表
navList: basicListData.data
}
},
methods: {
getRandomCoolBg() {
return this.$t.colorUtils.getRandomCoolBgClass()
}
}
}
</script>
<style lang="scss" scoped>
/* 顶部背景图 start */
.top-backgroup {
height: 450rpx;
z-index: -1;
.backgroud-image {
width: 100%;
height: 667rpx;
}
}
/* 顶部背景图 end */
/* 标题start */
.nav_title {
-webkit-background-clip: text;
color: transparent;
&--wrap {
position: relative;
display: flex;
height: 120rpx;
font-size: 46rpx;
align-items: center;
justify-content: center;
font-weight: bold;
background-image: url(https://tnuiimage.tnkjapp.com/title_bg/title44.png);
background-size: cover;
}
}
/* 标题end */
/* 组件导航列表 start*/
.nav-list {
display: flex;
flex-wrap: wrap;
padding: 0rpx 12rpx 0rpx;
justify-content: space-between;
/* 列表元素 start */
.nav-list-item {
padding: 95rpx 30rpx 5rpx 30rpx;
border-radius: 12rpx;
width: 45%;
margin: 0 18rpx 40rpx;
background-size: cover;
background-position: center;
position: relative;
z-index: 99;
/* 元素标题 start */
.nav-link {
font-size: 32rpx;
text-transform: capitalize;
padding: 0 0 10rpx 0;
position: relative;
.title {
color: #FFFFFF;
margin-top: 30rpx;
text-align: center;
}
}
/* 元素标题 end */
/* 元素图标 start */
.icon {
font-variant: small-caps;
position: absolute;
top: 20rpx;
right: 50rpx;
left: 37%;
width: 90rpx;
height: 90rpx;
line-height: 90rpx;
margin: 0;
padding: 0;
display: inline-flex;
text-align: center;
justify-content: center;
vertical-align: middle;
font-size: 50rpx;
color: #FFFFFF;
white-space: nowrap;
opacity: 0.9;
background-color: rgba(0, 0, 0, 0.05);
background-size: cover;
background-position: 50%;
border-radius: 5000rpx;
}
/* 元素图标 end */
}
/* 列表元素 end */
}
/* 组件导航列表 end*/
</style>
+167
View File
@@ -0,0 +1,167 @@
<template>
<view class="components">
<view class="top-backgroup">
<image src='https://tnuiimage.tnkjapp.com/index_bg/components_new.jpg' mode='widthFix' class='backgroud-image'></image>
</view>
<block v-for="(item, index) in navList" :key="index">
<view class="nav_title--wrap tn-margin-bottom-sm">
<view class="nav_title tn-cool-bg-color-15">{{ item.title | titleFilter}}</view>
</view>
<view class='nav-list'>
<block v-for="(content_item, content_index) in item.list" :key="content_index">
<navigator
open-type="navigate"
hover-class='none'
:url="content_item.url"
class="nav-list-item tn-shadow-blur tn-cool-bg-image tn-flex tn-flex-col-center tn-flex-row-between"
:class="[
getRandomCoolBg(content_index)
]"
>
<view class="nav-link tn-flex-1">
<view class='title'>{{ content_item.title }}</view>
</view>
<view class="icon">
<view :class="['tn-icon-' + content_item.icon]"></view>
</view>
</navigator>
</block>
</view>
</block>
<view class="tn-padding-bottom"></view>
</view>
</template>
<script>
import componentsListData from '@/mock/components_page.js'
export default {
name: 'Components',
filters: {
titleFilter(value) {
if (value.length === 0) {
return ''
}
let newString = ''
for (let i = 0; i < value.length; i++) {
if (i !== 0) {
newString += ' / '
}
newString += value[i]
}
return newString
}
},
data() {
return {
// nav菜单列表
navList: componentsListData.data
}
},
methods: {
getRandomCoolBg() {
return this.$t.colorUtils.getRandomCoolBgClass()
}
}
}
</script>
<style lang="scss" scoped>
/* 顶部背景图 start */
.top-backgroup {
height: 450rpx;
z-index: -1;
.backgroud-image {
width: 100%;
height: 667rpx;
}
}
/* 顶部背景图 end */
/* 标题start */
.nav_title {
-webkit-background-clip: text;
color: transparent;
&--wrap {
position: relative;
display: flex;
height: 120rpx;
font-size: 46rpx;
align-items: center;
justify-content: center;
font-weight: bold;
background-image: url(https://tnuiimage.tnkjapp.com/title_bg/title44.png);
background-size: cover;
}
}
/* 标题end */
/* 组件导航列表 start*/
.nav-list {
display: flex;
flex-wrap: wrap;
padding: 0rpx 12rpx 0rpx;
justify-content: space-between;
/* 列表元素 start */
.nav-list-item {
padding: 30rpx 30rpx 20rpx 30rpx;
border-radius: 12rpx;
width: 45%;
margin: 0 18rpx 40rpx;
background-size: cover;
background-position: 50%;
position: relative;
z-index: 99;
/* 元素标题 start */
.nav-link {
font-size: 32rpx;
line-height: 1.2;
text-transform: capitalize;
padding: 0rpx 10rpx 0rpx 0;
position: relative;
.title {
color: #FFFFFF;
text-align: left;
}
}
/* 元素标题 end */
/* 元素图标 start */
.icon {
font-variant: small-caps;
width: 70rpx;
height: 70rpx;
line-height: 70rpx;
margin: 0;
padding: 0;
display: inline-flex;
text-align: center;
justify-content: center;
vertical-align: middle;
font-size: 45rpx;
color: #FFFFFF;
white-space: nowrap;
opacity: 0.9;
background-color: rgba(0, 0, 0, 0.05);
background-size: cover;
background-position: 50%;
border-radius: 5000rpx;
}
/* 元素图标 end */
}
/* 列表元素 end */
}
/* 组件导航列表 end*/
</style>
+116
View File
@@ -0,0 +1,116 @@
<template>
<view class="index">
<Basic v-if="tabberPageLoadFlag[0]" :style="{display: currentIndex === 0 ? '' : 'none'}" ref="basic"></Basic>
<components v-if="tabberPageLoadFlag[1]" :style="{display: currentIndex === 1 ? '' : 'none'}" ref="components"></components>
<templatePage v-if="tabberPageLoadFlag[2]" :style="{display: currentIndex === 2 ? '' : 'none'}" ref="template"></templatePage>
<tuniao v-if="tabberPageLoadFlag[3]" :style="{display: currentIndex === 3 ? '' : 'none'}" ref="about"></tuniao>
<tn-tabbar
v-model="currentIndex"
:list="tabbarList"
activeColor="#838383"
inactiveColor="#AAAAAA"
activeIconColor="tn-cool-bg-color-7"
:animation="true"
:safeAreaInsetBottom="true"
@change="switchTabbar"
></tn-tabbar>
</view>
</template>
<script>
import Basic from '../basic/basic.vue'
import Components from '../components/components.vue'
import TemplatePage from '../template/template.vue'
import Tuniao from '../tuniao/tuniao.vue'
export default {
components: {
Basic,
Components,
TemplatePage,
Tuniao
},
data() {
return {
// 底部tabbar菜单数据
tabbarList: [
{
title: '元素',
activeIcon: 'count-fill',
inactiveIcon: 'menu'
},
{
title: '组件',
activeIcon: 'honor-fill',
inactiveIcon: 'honor'
},
{
title: '页面',
activeIcon: 'discover',
inactiveIcon: 'discover'
},
{
title: '图鸟',
activeIcon: 'computer-fill',
inactiveIcon: 'computer',
dot: true
}
],
// tabbar当前被选中的序号
currentIndex: 0,
// 自定义底栏对应页面的加载情况
tabberPageLoadFlag: []
}
},
onLoad(options) {
const index = Number(options.index || 0)
// 根据底部tabbar菜单列表设置对应页面的加载情况
this.tabberPageLoadFlag = this.tabbarList.map((item, tabbar_index) => {
return index === tabbar_index
})
this.switchTabbar(index)
},
onPageScroll(e) {
},
onReachBottom() {
},
methods: {
// 切换导航
switchTabbar(index) {
this._switchTabbarPage(index)
},
// 导航页面滚动到底部
tabbarPageScrollLower(e) {
},
// 切换导航页面
_switchTabbarPage(index) {
const selectPageFlag = this.tabberPageLoadFlag[index]
if (selectPageFlag === undefined) {
return
}
if (selectPageFlag === false) {
this.tabberPageLoadFlag[index] = true
}
this.currentIndex = index
}
}
}
</script>
<style lang="scss" scoped>
.index {
overflow: hidden;
height: 100%;
}
.custom-tabbar-page {
height: calc(100vh - (100rpx + env(safe-area-inset-bottom) / 2));
}
</style>
+167
View File
@@ -0,0 +1,167 @@
<template>
<view class="template">
<view class="top-backgroup">
<image src='https://tnuiimage.tnkjapp.com/index_bg/template_new.jpg' mode='widthFix' class='backgroud-image'></image>
</view>
<block v-for="(item, index) in navList" :key="index">
<view class="nav_title--wrap tn-margin-bottom-sm">
<view class="nav_title tn-cool-bg-color-15">{{ item.title | titleFilter}}</view>
</view>
<view class='nav-list'>
<block v-for="(content_item, content_index) in item.list" :key="content_index">
<navigator
open-type="navigate"
hover-class='none'
:url="content_item.url"
class="nav-list-item tn-shadow-blur tn-cool-bg-image"
:class="[
getRandomCoolBg(content_index)
]"
>
<view class="nav-link">
<view class='title'>{{ content_item.title }}</view>
</view>
<view class="icon">
<view :class="['tn-icon-' + content_item.icon]"></view>
</view>
</navigator>
</block>
</view>
</block>
<view class="tn-padding-bottom"></view>
</view>
</template>
<script>
import templateListData from '@/mock/template_page.js'
export default {
name: 'TemplatePage',
filters: {
titleFilter(value) {
if (value.length === 0) {
return ''
}
let newString = ''
for (let i = 0; i < value.length; i++) {
if (i !== 0) {
newString += ' / '
}
newString += value[i]
}
return newString
}
},
data() {
return {
// nav菜单列表
navList: templateListData.data
}
},
methods: {
getRandomCoolBg() {
return this.$t.colorUtils.getRandomCoolBgClass()
}
}
}
</script>
<style lang="scss" scoped>
/* 顶部背景图 start */
.top-backgroup {
height: 450rpx;
z-index: -1;
.backgroud-image {
width: 100%;
height: 667rpx;
}
}
/* 顶部背景图 end */
/* 标题start */
.nav_title {
-webkit-background-clip: text;
color: transparent;
&--wrap {
position: relative;
display: flex;
height: 120rpx;
font-size: 46rpx;
align-items: center;
justify-content: center;
font-weight: bold;
background-image: url(https://tnuiimage.tnkjapp.com/title_bg/title44.png);
background-size: cover;
}
}
/* 标题end */
/* 组件导航列表 start*/
.nav-list {
display: flex;
flex-wrap: wrap;
padding: 0rpx 12rpx 0rpx;
justify-content: space-between;
/* 列表元素 start */
.nav-list-item {
padding: 50rpx 30rpx 36rpx 30rpx;
border-radius: 12rpx;
width: 100%;
margin: 0 18rpx 40rpx;
background-size: cover;
background-position: center;
position: relative;
z-index: 99;
display: flex;
align-items: center;
justify-content: space-between;
/* 元素标题 start */
.nav-link {
flex: 1;
font-size: 32rpx;
text-transform: capitalize;
padding: 10rpx 0 20rpx 0;
position: relative;
.title {
color: #FFFFFF;
text-align: left;
}
}
/* 元素标题 end */
/* 元素图标 start */
.icon {
font-variant: small-caps;
width: 70rpx;
height: 70rpx;
line-height: 70rpx;
margin: 0;
padding: 0;
display: inline-flex;
text-align: center;
justify-content: center;
vertical-align: middle;
font-size: 45rpx;
color: #FFFFFF;
white-space: nowrap;
opacity: 0.9;
background-color: rgba(0, 0, 0, 0.05);
background-size: cover;
background-position: 50%;
border-radius: 5000rpx;
}
/* 元素图标 end */
}
/* 列表元素 end */
}
/* 组件导航列表 end*/
</style>
+336
View File
@@ -0,0 +1,336 @@
<template>
<view class="about">
<view class="top-backgroup">
<image src='https://tnuiimage.tnkjapp.com/index_bg/about_new.jpg' mode='widthFix' class='backgroud-image'></image>
</view>
<view class="about__wrap">
<!-- 头像用户信息 -->
<view class="user-info__container tn-flex tn-flex-direction-column tn-flex-col-center tn-flex-row-center">
<!-- #ifdef H5 -->
<view class="user-info__avatar tn-bg-grey--light tn-flex tn-flex-col-center tn-flex-row-center">
<view class="tn-icon-logo-tuniao" style="font-size: 140rpx;color: #01BEFF;"></view>
</view>
<view class="user-info__nick-name">图鸟科技</view>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN -->
<view class="user-info__avatar">
<open-data type="userAvatarUrl"></open-data>
</view>
<view class="user-info__nick-name" style="height: 50rpx;">
<open-data type="userNickName"></open-data>
</view>
<!-- #endif -->
</view>
<!-- 数据信息 -->
<view class="tn-info__container tn-flex tn-flex-wrap tn-flex-col-center tn-flex-row-between">
<block v-for="(item, index) in tuniaoData" :key="index">
<view class="tn-info__item tn-flex tn-flex-direction-row tn-flex-col-center tn-flex-row-between about-shadow">
<view class="tn-info__item__left tn-flex tn-flex-direction-row tn-flex-col-center tn-flex-row-left">
<view class="tn-info__item__left--icon tn-flex tn-flex-col-center tn-flex-row-center" :class="[`tn-bg-${item.color}--light tn-color-${item.color}`]">
<view :class="[`tn-icon-${item.icon}`]"></view>
</view>
<view class="tn-info__item__left__content">
<view class="tn-info__item__left__content--title">{{ item.title }}</view>
<view class="tn-info__item__left__content--data tn-padding-top-xs">{{ item.value }}</view>
</view>
</view>
<view class="tn-info__item__right">
<view class="tn-info__item__right--icon">
<view class="tn-icon-code"></view>
</view>
</view>
</view>
</block>
</view>
<!-- 更多信息-->
<view class="about-shadow tn-margin-top-lg tn-padding-top-sm tn-padding-bottom-sm">
<tn-list-cell :hover="true" :unlined="true" :radius="true" :fontSize="30" @click="navTuniaoWebsite">
<view class="tn-flex tn-flex-col-center">
<view class="icon1__item--icon tn-flex tn-flex-row-center tn-flex-col-center tn-cool-bg-color-5 tn-color-white" >
<view class="tn-icon-discover-fill"></view>
</view>
<view class="tn-margin-left-sm">图鸟官网</view>
</view>
</tn-list-cell>
<tn-list-cell :hover="true" :unlined="true" :radius="true" :fontSize="30">
<view class="tn-flex tn-flex-col-center">
<view class="icon1__item--icon tn-flex tn-flex-row-center tn-flex-col-center tn-cool-bg-color-1 tn-color-white">
<view class="tn-icon-moon-fill"></view>
</view>
<view class="tn-margin-left-sm tn-flex-1">Gitee地址</view>
<view class="tn-margin-left-sm tn-color-gray">整理文件中</view>
</view>
</tn-list-cell>
<tn-list-cell :hover="true" :unlined="true" :radius="true" :fontSize="30" @click="navPlus">
<view class="tn-flex tn-flex-col-center">
<view class="icon1__item--icon tn-flex tn-flex-row-center tn-flex-col-center tn-cool-bg-color-12 tn-color-white">
<view class="tn-icon-trust-fill"></view>
</view>
<view class="tn-margin-left-sm tn-flex-1">会员协议</view>
<view class="tn-margin-left-sm tn-color-red tn-icon-fire-fill"></view>
</view>
</tn-list-cell>
<tn-list-cell :hover="true" :unlined="true" :radius="true" :fontSize="30">
<view class="tn-flex tn-flex-col-center">
<view class="icon1__item--icon tn-flex tn-flex-row-center tn-flex-col-center tn-cool-bg-color-2 tn-color-white">
<view class="tn-icon-set-fill"></view>
</view>
<view class="tn-margin-left-sm tn-flex-1">更新日志</view>
<view class="tn-margin-left-sm tn-color-gray"></view>
</view>
</tn-list-cell>
</view>
<!-- 更多信息-->
<view class="about-shadow tn-margin-top-lg tn-margin-bottom-lg tn-padding-top-sm tn-padding-bottom-sm">
<tn-list-cell :hover="true" :unlined="true" :radius="true" :fontSize="30">
<button class="tn-flex tn-flex-col-center tn-button--clear-style" open-type="contact">
<view class="icon1__item--icon tn-flex tn-flex-row-center tn-flex-col-center tn-cool-bg-color-9 tn-color-white">
<view class="tn-icon-wechat-fill"></view>
</view>
<view class="tn-margin-left-sm">合作勾搭</view>
</button>
</tn-list-cell>
<tn-list-cell :hover="true" :unlined="true" :radius="true" :fontSize="30">
<button class="tn-flex tn-flex-col-center tn-button--clear-style" open-type="feedback">
<view class="icon1__item--icon tn-flex tn-flex-row-center tn-flex-col-center tn-cool-bg-color-7 tn-color-white">
<view class="tn-icon-comment-fill"></view>
</view>
<view class="tn-margin-left-sm">问题反馈</view>
</button>
</tn-list-cell>
</view>
</view>
<view class="tn-padding-bottom"></view>
</view>
</template>
<script>
export default {
name: 'Tuniao',
data() {
return {
tuniaoData: [
{
title: 'View',
icon: 'eye-fill',
color: 'indigo',
value: '1.22 W'
},
{
title: 'Star',
icon: 'star-fill',
color: 'orange',
value: '406'
},
{
title: 'Fork',
icon: 'group-circle',
color: 'purplered',
value: '129'
},
{
title: 'Version',
icon: 'trusty-fill',
color: 'green',
value: '1.0.0'
}
]
}
},
methods: {
// 跳转到图鸟官网
navTuniaoWebsite() {
uni.navigateToMiniProgram({
appId: 'wxa698b1eee960632f'
})
},
// 跳转到会员协议
navPlus() {
uni.navigateTo({
url: '/templatePage/life/plus/plus'
})
}
}
}
</script>
<style lang="scss" scoped>
/* 顶部背景图 start */
.top-backgroup {
height: 450rpx;
z-index: -1;
.backgroud-image {
width: 100%;
height: 667rpx;
// z-index: -1;
}
}
/* 顶部背景图 end */
/* 页面 start*/
.about-shadow{
border-radius: 15rpx;
box-shadow: 0rpx 0rpx 50rpx 0rpx rgba(0, 0, 0, 0.07);
}
.about {
&__wrap {
position: relative;
z-index: 1;
margin: 20rpx 30rpx;
margin-top: -180rpx;
}
}
/* 页面 end*/
/* 用户信息 start */
.user-info {
&__container {
}
&__avatar {
width: 180rpx;
height: 180rpx;
border: 8rpx solid rgba(255,255,255,0.05);
border-radius: 50%;
overflow: hidden;
box-shadow: 0rpx 0rpx 80rpx 0rpx rgba(0, 0, 0, 0.15);
}
&__nick-name {
margin-top: 26rpx;
font-size: 42rpx;
font-weight: 600;
text-align: center;
}
}
/* 用户信息 end */
/* 信息展示 start */
.tn-info {
&__container {
margin-top: 40rpx;
}
&__item {
width: 48%;
margin: 15rpx 0rpx;
padding: 28rpx;
border-radius: 15rpx;
position: relative;
z-index: 1;
&::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://tnuiimage.tnkjapp.com/cool_bg_image/6.png);
}
&__left {
&--icon {
width: 80rpx;
height: 80rpx;
border-radius: 50%;
font-size: 40rpx;
margin-right: 20rpx;
position: relative;
z-index: 1;
&::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://tnuiimage.tnkjapp.com/cool_bg_image/icon_bg5.png);
}
}
&__content {
font-size: 30rpx;
&--data {
margin-top: 5rpx;
font-weight: bold;
}
}
}
&__right {
&--icon {
font-size: 60rpx;
opacity: 0.15;
}
}
}
}
/* 信息展示 end */
/* 图标容器1 start */
.icon1 {
&__item {
// width: 30%;
background-color: #FFFFFF;
border-radius: 10rpx;
padding: 30rpx;
margin: 20rpx 10rpx;
transform: scale(1);
transition: transform 0.3s linear;
transform-origin: center center;
&--icon {
width: 40rpx;
height: 40rpx;
font-size: 28rpx;
border-radius: 50%;
position: relative;
z-index: 1;
&::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://tnuiimage.tnkjapp.com/cool_bg_image/icon_bg.png);
}
}
}
}
/* 图标容器1 end */
</style>
+193
View File
@@ -0,0 +1,193 @@
/* 顶部 start */
.header {
padding: 80rpx 60rpx 40rpx 60rpx;
.title {
font-size: 36rpx;
color: $tn-font-color;
font-weight: bold;
}
.sub-title {
font-size: 28rpx;
color: $tn-content-color;
padding-top: 18rpx;
}
.tips-title {
font-size: 24rpx;
color: $tn-font-sub-color;
padding-top: 5rpx;
}
}
/* 顶部 end */
/* 展示内容容器 start */
.show-content-container {
/* 标题容器 start */
.title-container {
display: flex;
position: relative;
align-items: center;
justify-content: space-between;
min-height: 100rpx;
// 标题样式
.title {
height: 100%;
max-width: 100%;
margin: 0 20rpx;
font-size: 30rpx;
display: flex;
align-items: center;
justify-content: center;
// 标题前面小点
&:before {
content: " ";
background-color: $tn-main-color;
width: 15rpx;
height: 15rpx;
border-radius: 10rpx;
margin-right: 18rpx;
}
}
}
/* 标题容器 end */
/* 内容 start */
.content {
padding: 20rpx;
}
/* 内容 end */
}
/* 展示内容容器 end */
/* 内容容器 start */
.demo-content-container {
border: 1rpx dashed $tn-main-color;
margin: 20rpx;
margin-top: 0rpx;
position: fixed;
width: 95%;
z-index: 10;
transition: all 0.15s ease-out;
&.top {
width: 100%;
margin: 0;
}
&.no-fixed {
position: relative !important;
}
/* 标题容器 start */
.title-container {
display: flex;
position: relative;
align-items: center;
justify-content: center;
min-height: 100rpx;
// 标题样式
.title {
height: 100%;
max-width: 100%;
margin: 0 30rpx;
font-size: 30rpx;
display: flex;
align-items: center;
justify-content: center;
}
}
/* 标题容器 end */
/* 内容 start */
.content {
padding: 30rpx;
display: flex;
align-items: center;
justify-content: center;
}
/* 内容 end */
}
/* 内容容器 end */
/* 可选项内容容器 start */
.demo-section-container {
margin: 20rpx;
height: 100%;
/* 标题容器 start */
.title-container {
display: flex;
position: relative;
align-items: center;
justify-content: center;
min-height: 100rpx;
margin-bottom: 10rpx;
// 标题样式
.title {
height: 100%;
max-width: 100%;
margin: 0 30rpx;
font-size: 30rpx;
display: flex;
align-items: center;
justify-content: center;
}
&::after {
content: " ";
box-sizing: border-box;
width: 90%;
height: 100%;
position: absolute;
top: 0;
left: 50%;
transform: translateX(-50%);
border-bottom: 1rpx solid $tn-border-solid-color;
}
}
/* 标题容器 end */
/* 参数内容 start*/
.content {
padding: 0 20rpx 10rpx 20rpx;
// 标题样式
.title {
padding-left: 20rpx;
height: 100%;
position: relative;
&::before {
content: " ";
position: absolute;
top: 50%;
left: 0;
width: 4rpx;
height: 90%;
background-color: $tn-main-color;
border-radius: 6rpx;
transform: translateY(-50%);
}
}
// 参数样式
.section {
margin-top: 15rpx;
margin-bottom: 20rpx;
}
}
/* 参数内容 end*/
}
/* 可选项内容容器 end */
@@ -0,0 +1,38 @@
.tn-custom-nav-bar__back {
width: 100%;
height: 100%;
position: relative;
display: flex;
justify-content: space-evenly;
align-items: center;
box-sizing: border-box;
background-color: rgba(0, 0, 0, 0.15);
border-radius: 1000rpx;
border: 1rpx solid rgba(255, 255, 255, 0.5);
color: #FFFFFF;
font-size: 18px;
.icon {
display: block;
flex: 1;
margin: auto;
text-align: center;
}
&:before {
content: " ";
width: 1rpx;
height: 110%;
position: absolute;
top: 22.5%;
left: 0;
right: 0;
margin: auto;
transform: scale(0.5);
transform-origin: 0 0;
pointer-events: none;
box-sizing: border-box;
opacity: 0.7;
background-color: #FFFFFF;
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

+28
View File
@@ -0,0 +1,28 @@
import { mapState } from 'vuex'
import store from '@/store'
// 尝试将用户在根目录中的store/index.js的vuex的state变量加载到全局变量中
let $tStoreKey = []
try {
$tStoreKey = store.state ? Object.keys(store.state) : []
} catch(e) {
}
module.exports = {
beforeCreate() {
// 将vuex方法挂在在$t中
// 使用方法:
// 修改vuex的state中的user.name变量为图鸟小菜 => this.$t.vuex('user.name', '图鸟小菜')
// 修改vuexde state中的version变量为1.0.1 => this.$t.vuex('version', 1.0.1)
this.$t.vuex = (name, value) => {
this.$store.commit('$tStore', {
name, value
})
}
},
computed: {
// 将vuex的state中的变量结构到全局混入mixin中
...mapState($tStoreKey)
}
}
+75
View File
@@ -0,0 +1,75 @@
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
let lifeData = {}
// 尝试获取本地是否存在lifeData变量,第一次启动时不存在
try {
lifeData = uni.getStorageSync('lifeData')
} catch(e) {
}
// 标记需要永久存储的变量,在每次启动时取出,在state中的变量名
let saveStateKeys = ['vuex_user']
// 保存变量到本地存储
const saveLifeData = function(key, value) {
// 判断变量是否在存储数组中
if (saveStateKeys.indexOf(key) != -1) {
// 获取本地存储的lifeData对象,将变量添加到对象中
let tmpLifeData = uni.getStorageSync('lifeData')
// 第一次启动时不存在,则放一个空对象
tmpLifeData = tmpLifeData ? tmpLifeData : {},
tmpLifeData[key] = value
// 将变量再次放回本地存储中
uni.setStorageSync('lifeData', tmpLifeData)
}
}
const store = new Vuex.Store({
state: {
// 如果上面从本地获取的lifeData对象下有对应的属性,就赋值给state中对应的变量
// 加上vuex_前缀,是防止变量名冲突,也让人一目了然
vuex_user: lifeData.vuex_user ? lifeData.vuex_user : {name: '图鸟'},
// 如果vuex_version无需保存到本地永久存储,无需lifeData.vuex_version方式
// app版本
vuex_version: "1.0.0",
// 是否使用自定义导航栏
vuex_custom_nav_bar: true,
// 状态栏高度
vuex_status_bar_height: 0,
// 自定义导航栏的高度
vuex_custom_bar_height: 0
},
mutations: {
$tStore(state, payload) {
// 判断是否多层调用,state中为对象存在的情况,例如user.info.score = 1
let nameArr = payload.name.split('.')
let saveKey = ''
let len = nameArr.length
if (len >= 2) {
let obj = state[nameArr[0]]
for (let i= 1; i < len - 1; i++) {
obj = obj[nameArr[i]]
}
obj[nameArr[len - 1]] = payload.value
saveKey = nameArr[0]
} else {
// 单层级变量
state[payload.name] = payload.value
saveKey = payload.name
}
// 保存变量到本地中
saveLifeData(saveKey, state[saveKey])
}
},
actions: {
}
})
export default store
+38
View File
@@ -0,0 +1,38 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link rel="shortcut icon" type="image/x-icon" href="./static/favicon.ico">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<title>
<%= htmlWebpackPlugin.options.title %>
</title>
<style>
::-webkit-scrollbar {
display: none;
}
</style>
<!-- 正式发布的时候使用,开发期间不启用。↑ -->
<script>
document.addEventListener('DOMContentLoaded', function() {
document.documentElement.style.fontSize = document.documentElement.clientWidth / 20 + 'px'
})
</script>
<link rel="stylesheet" href="<%= BASE_URL %>static/index.css" />
</head>
<body>
<!-- 该文件为 H5 平台的模板 HTML,并非应用入口。 -->
<!-- 请勿在此文件编写页面代码或直接运行此文件。 -->
<!-- 详见文档:https://uniapp.dcloud.io/collocation/manifest?id=h5-template -->
<noscript>
<strong>本站点必须要开启JavaScript才能运行</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
<script>
/*BAIDU_STAT*/
</script>
</body>
</html>
+148
View File
@@ -0,0 +1,148 @@
<template>
<view class="template-hollow">
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed alpha customBack>
<view slot="back" class='tn-custom-nav-bar__back'
@click="goBack">
<text class='icon tn-icon-left'></text>
<text class='icon tn-icon-home-capsule-fill'></text>
</view>
</tn-nav-bar>
<view class="" :style="{paddingTop: vuex_custom_bar_height + 'px;margin-top:250rpx'}">
<view class="tn-flex tn-flex-row-between tn-margin-xl">
<view class="justify-content-item" style="margin-top: 50rpx;">
<view class="tn-radius tn-margin-bottom-xl">
<view class="image-pic" style="background-image:url('https://tnuiimage.tnkjapp.com/blogger/avatar_3.jpeg')">
<view class="image-hollow">
</view>
</view>
<view class="tn-text-center tn-text-bold tn-padding-top-xs">Jaylen</view>
</view>
<view class="tn-radius tn-margin-bottom">
<view class="image-pic" style="background-image:url('https://tnuiimage.tnkjapp.com/blogger/avatar_2.jpeg')">
<view class="image-hollow">
</view>
</view>
<view class="tn-text-center tn-text-bold tn-padding-top-xs">浅浅遇</view>
</view>
</view>
<view class="justify-content-item">
<view class="tn-radius tn-margin-bottom-xl">
<view class="image-pic" style="background-image:url('https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg')">
<view class="image-hollow">
</view>
</view>
<view class="tn-text-center tn-text-bold tn-padding-top-xs">可我会像</view>
</view>
<view class="tn-radius tn-margin-bottom">
<view class="image-pic" style="background-image:url('https://tnuiimage.tnkjapp.com/blogger/blogger_beibei.jpg')">
<view class="image-hollow">
</view>
</view>
<view class="tn-text-center tn-text-bold tn-padding-top-xs">北北同学</view>
</view>
</view>
<view class="justify-content-item" style="margin-top: 50rpx;">
<view class="tn-radius tn-margin-bottom-xl">
<view class="image-pic" style="background-image:url('https://tnuiimage.tnkjapp.com/blogger/avatar_4.jpeg')">
<view class="image-hollow">
</view>
</view>
<view class="tn-text-center tn-text-bold tn-padding-top-xs">福哥</view>
</view>
<view class="tn-radius tn-margin-bottom">
<view class="image-pic" style="background-image:url('https://tnuiimage.tnkjapp.com/blogger/content_1.jpeg')">
<view class="image-hollow">
</view>
</view>
<view class="tn-text-center tn-text-bold tn-padding-top-xs">锋哥</view>
</view>
</view>
</view>
</view>
<view class="bottom-backgroup">
<image src='https://tnuiimage.tnkjapp.com/animate/hollow.jpg' mode='widthFix' class='backgroud-image'></image>
</view>
<view class="hollow">
<view class="tn-text-xxl">
<text class="">Hi</text>
<open-data type="userNickName"></open-data>
</view>
<view class="tn-text-xl tn-padding-top">
技术的友情有你真好
</view>
<view class="tn-text-xl tn-padding-top">
TnUI感谢一路陪伴与支持
</view>
</view>
</view>
</template>
<script>
import template_page_mixin from '@/libs/mixin/template_page_mixin.js'
export default {
name: 'TemplateHollow',
mixins: [template_page_mixin],
data(){
return {}
},
methods: {
}
}
</script>
<style lang="scss" scoped>
@import '@/static/css/templatePage/custom_nav_bar.scss';
/* 背景图 start */
.bottom-backgroup {
height: 700rpx;
z-index: -1;
.backgroud-image {
border-radius: 60rpx 60rpx 0 0;
width: 100%;
height: 3373rpx;
// z-index: -1;
}
}
/* 背景图 end */
/* 镂空 start*/
.hollow {
position: fixed;
text-align: center;
width: 87%;
padding: 30rpx;
margin: 0 6.5%;
top: 180rpx;
font-weight: bold;
z-index: 1000;
background: rgba(255, 255, 255, 0.95);
color: #000;
border-radius: 20rpx;
/* overlay; difference;lighten;hue;这些都是参数值,但东东觉得lighten好看点*/
mix-blend-mode: lighten;
}
/* 效果布局 start*/
.image-hollow{
width: 200rpx;
height: 400rpx;
font-size: 40rpx;
font-weight: 300;
position: relative;
}
.image-pic{
height: 100%;
background-size: cover;
background-repeat:no-repeat;
// background-attachment:fixed;
background-position:top;
border-radius: 10rpx;
}
</style>
+265
View File
@@ -0,0 +1,265 @@
<template>
<view class="template-loading">
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed alpha customBack>
<view slot="back" class='tn-custom-nav-bar__back'
@click="goBack">
<text class='icon tn-icon-left'></text>
<text class='icon tn-icon-home-capsule-fill'></text>
</view>
</tn-nav-bar>
<!-- 页面内容 -->
<view class="bg-contaniner">
</view>
<view class="container-content hex-border">
<view class="hexagons">
<view class="hexagon"></view>
<view class="hexagon"></view>
<view class="hexagon"></view>
<view class="hexagon"></view>
<view class="hexagon"></view>
<view class="hexagon"></view>
<view class="hexagon"></view>
</view>
</view>
</view>
</template>
<script>
import template_page_mixin from '@/libs/mixin/template_page_mixin.js'
export default {
name: 'TemplateLoading',
mixins: [template_page_mixin],
data(){
return {}
},
methods: {
}
}
</script>
<style lang="scss" scoped>
@import '@/static/css/templatePage/custom_nav_bar.scss';
/* 移动背景部分 */
.bg-contaniner {
position: fixed;
top: -0rpx;
left: -300rpx;
--text-color: hsl(0 95% 60%);
--bg-color: hsl(0 0% 100%);
--bg-size: 200px;
height: 100%;
display: grid;
place-items: center;
place-content: center;
/* grid-template-areas: "body"; */
overflow: hidden;
font-family: "Dela Gothic One", sans-serif;
background-color: var(--bg-color);
z-index: -1;
}
.bg-contaniner::before {
--size: 150vmax;
grid-area: body;
content: "";
inline-size: var(--size);
block-size: var(--size);
background-image: url("https://tnuiimage.tnkjapp.com/animate/animate1.jpg");
background-size: var(--bg-size);
background-repeat: repeat;
transform: rotate(45deg);
opacity: 0.25;
animation: bg 6s linear infinite;
}
@media (prefers-reduced-motion: reduce) {
.bg-contaniner::before {
animation-duration: 0s;
}
}
@keyframes bg {
to {
background-position: 0 calc(var(--bg-size) * -1);
}
}
/* 加载部分 */
.components-anloading {
margin: 0;
width: 100%;
height: 100vh;
color: #fff;
/* background: linear-gradient(45deg, #0fd850, #f9f047); */
}
.hex-border {
position: absolute;
transform: translate(-50%, -50%);
left: 50%;
top: 50%;
width: 170px;
height: 170px;
border: 2px solid rgba(235, 237, 241, 0.8);
border-radius: 100%;
}
.hex-border::before {
content: "";
position: absolute;
width: 174px;
height: 174px;
border: 2px solid #F4B4C4;
border-radius: 100%;
box-sizing: border-box;
clip-path: inset(0px 135px 135px 0px);
-webkit-clip-path: inset(0px 135px 135px 0px);
top: -4px;
left: -4px;
animation: rotateSmall 2s linear infinite;
z-index: 2;
}
.hex-border::after {
content: "";
position: absolute;
width: 174px;
height: 174px;
border: 2px solid #F4B4C4;
border-radius: 100%;
box-sizing: border-box;
top: -4px;
left: -4px;
clip-path: inset(0px 30px 30px 0px);
-webkit-clip-path: inset(0px 30px 30px 0px);
animation: rotateLarge 1.6s linear infinite;
}
.hexagons {
position: relative;
border-radius: 100%;
padding: 5%;
top: 30px;
left: 35px;
}
.hexagon {
position: absolute;
width: 40px;
height: 23px;
background-color: #F4B4C4;
transform: scale(1.02);
transform-origin: center;
}
.hexagon::before {
content: "";
position: absolute;
top: -11.5px;
left: 0;
width: 0;
height: 0;
border-left: 20px solid transparent;
border-right: 20px solid transparent;
border-bottom: 11.5px solid #F4B4C4;
}
.hexagon::after {
content: "";
position: absolute;
top: 23px;
left: 0;
width: 0;
height: 0;
border-left: 20px solid transparent;
border-right: 20px solid transparent;
border-top: 11.5px solid #F4B4C4;
}
.hexagon:nth-child(1) {
animation: animateHex 3s infinite;
}
.hexagon:nth-child(2) {
left: 53px;
animation: animateHex 3s 0.2s infinite;
}
.hexagon:nth-child(3) {
left: -13px;
top: 46px;
animation: animateHex 3s 1s infinite;
}
.hexagon:nth-child(4) {
left: 31px;
top: 46px;
animation: animateHex 3s 1.2s infinite;
}
.hexagon:nth-child(5) {
left: 75px;
top: 46px;
animation: animateHex 3s 0.4s infinite;
}
.hexagon:nth-child(6) {
top: 84px;
animation: animateHex 3s 0.8s infinite;
}
.hexagon:nth-child(7) {
left: 53px;
top: 84px;
animation: animateHex 3s 0.6s infinite;
}
@keyframes rotateSmall {
100% {
transform: rotate(1turn);
}
}
@keyframes rotateLarge {
0% {
clip-path: inset(0px 30px 30px 0px);
-webkit-clip-path: inset(0px 30px 30px 0px);
}
50% {
clip-path: inset(0px 150px 150px 0px);
-webkit-clip-path: inset(0px 150px 150px 0px);
}
100% {
transform: rotate(1turn);
clip-path: inset(0px 30px 30px 0px);
-webkit-clip-path: inset(0px 30px 30px 0px);
}
}
@keyframes animateHex {
0% {
transform: scale(1.02);
}
20%,
50% {
transform: scale(0.6);
opacity: 0;
}
65% {
transform: scale(1.02);
opacity: 1;
}
}
</style>
+149
View File
@@ -0,0 +1,149 @@
<template>
<view class="template-particle">
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed alpha customBack>
<view slot="back" class='tn-custom-nav-bar__back'
@click="goBack">
<text class='icon tn-icon-left'></text>
<text class='icon tn-icon-home-capsule-fill'></text>
</view>
</tn-nav-bar>
<canvas canvas-id="star_canvas" class="mycanvas" :style="'width:' + screenWidth + 'px;height:' + screenHeight + 'px;'"></canvas>
</view>
</template>
<script>
import template_page_mixin from '@/libs/mixin/template_page_mixin.js'
const Point = class {
constructor(x, y) {
this.x = x
this.y = y
this.r = 1 + Math.random() * 2
this.sx = Math.random() * 2 - 1
this.sy = Math.random() * 2 - 1
}
draw(ctx) {
ctx.beginPath()
ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI)
ctx.closePath()
ctx.fillStyle = '#fff'
ctx.fill()
}
move(w, h) {
this.x += this.sx
this.y += this.sy
if (this.x > w || this.x < 0) this.sx = -this.sx
if (this.y > h || this.y < 0) this.sy = -this.sy
}
drawLine(ctx, p) {
const dx = this.x - p.x
const dy = this.y - p.y
const d = Math.sqrt(dx * dx + dy * dy)
if (d < 100) {
var alpha = (100 - d) / 300 * 1
ctx.beginPath()
ctx.moveTo(this.x, this.y)
ctx.lineTo(p.x, p.y)
ctx.closePath()
ctx.strokeStyle = 'rgba(255, 255, 255, ' + alpha + ')'
ctx.strokeWidth = 1
ctx.stroke()
}
}
}
const sysinfo = uni.getSystemInfoSync()
const w = 400
const h = 1000
export default {
name: 'TemplateParticle',
mixins: [template_page_mixin],
data(){
return {
ctx: null,
screenWidth: sysinfo.screenWidth,
screenHeight: sysinfo.screenHeight,
timer: null,
points: []
}
},
onLoad(options) {
this.from = options.from || ''
for (let i = 0; i < 80; i++) {
this.points.push(new Point(Math.random() * w, Math.random() * h))
}
this.ctx = uni.createCanvasContext('star_canvas')
// console.log(points)
this.gameloop() //进行
// this.ctx.setFillStyle('red')
// this.ctx.fillRect(200, 300, 50, 50)
// this.ctx.draw()
},
onUnload() {
clearTimeout(this.timer)
},
methods: {
/**粒子进行*/
gameloop() {
this.timer = setTimeout(this.gameloop, 100);
// console.log('gameloop')
this.paint();
},
/**清空画布*/
paint() {
this.ctx.clearRect(0, 0, w, h)
for (var i = 0; i < this.points.length; i++) {
this.points[i].move(w, h)
this.points[i].draw(this.ctx)
for (var j = i + 1; j < this.points.length; j++) {
this.points[i].drawLine(this.ctx, this.points[j])
}
}
this.ctx.draw();
}
}
}
</script>
<style lang="scss" scoped>
@import '@/static/css/templatePage/custom_nav_bar.scss';
.template-particle {
background: -webkit-gradient(linear, left top, right top, from(#892FE8), to(#3D7EFF));
background: linear-gradient(90deg, #892FE8, #3D7EFF);
min-height: 100vh
}
.template-particle:before {
content: "";
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
-webkit-mask-image: -webkit-gradient(linear, left top, left bottom, from(transparent), to(black));
-webkit-mask-image: linear-gradient(to bottom, transparent, black);
mask-image: -webkit-gradient(linear, left top, left bottom, from(transparent), to(black));
mask-image: linear-gradient(to bottom, transparent, black);
background: -webkit-gradient(linear, left top, right top, from(#E72F8C), to(#892FE8));
background: linear-gradient(90deg, #E72F8C, #892FE8);
}
.mycanvas {
background-size: cover;
width: 100vw;
height: 100vh;
justify-content: center;
flex-direction: column;
color: #fff;
}
</style>
+264
View File
@@ -0,0 +1,264 @@
<template>
<view class="template-photo">
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed alpha customBack>
<view slot="back" class='tn-custom-nav-bar__back'
@click="goBack">
<text class='icon tn-icon-left'></text>
<text class='icon tn-icon-home-capsule-fill'></text>
</view>
</tn-nav-bar>
<!-- 页面内容 -->
<view class="slideshow">
<view class="slideshow-image" style="background-image: url('https://tnuiimage.tnkjapp.com/shop/cup1.jpg')"></view>
<view class="slideshow-image" style="background-image: url('https://tnuiimage.tnkjapp.com/shop/phonecase1.jpg')"></view>
<view class="slideshow-image" style="background-image: url('https://tnuiimage.tnkjapp.com/shop/card.jpg')"></view>
<view class="slideshow-image" style="background-image: url('https://tnuiimage.tnkjapp.com/shop/watch1.jpg')"></view>
</view>
</view>
</template>
<script>
import template_page_mixin from '@/libs/mixin/template_page_mixin.js'
export default {
name: 'TemplatePhoto',
mixins: [template_page_mixin],
data(){
return {}
},
methods: {
}
}
</script>
<style lang="scss" scoped>
@import '@/static/css/templatePage/custom_nav_bar.scss';
.template-photo {
margin: 0;
width: 100%;
height: 100vh;
color: #fff;
overflow: hidden;
}
/* 相册 start*/
.slideshow {
top: 0;
position: absolute;
width: 100vw;
height: 100vh;
overflow: hidden;
}
.slideshow-image {
position: absolute;
width: 100%;
height: 100%;
background: no-repeat 50% 50%;
background-size: cover;
-webkit-animation-name: kenburns;
animation-name: kenburns;
-webkit-animation-timing-function: linear;
animation-timing-function: linear;
-webkit-animation-iteration-count: infinite;
animation-iteration-count: infinite;
-webkit-animation-duration: 16s;
animation-duration: 16s;
opacity: 1;
transform: scale(1.2);
}
.slideshow-image:nth-child(1) {
-webkit-animation-name: kenburns-1;
animation-name: kenburns-1;
z-index: 3;
}
.slideshow-image:nth-child(2) {
-webkit-animation-name: kenburns-2;
animation-name: kenburns-2;
z-index: 2;
}
.slideshow-image:nth-child(3) {
-webkit-animation-name: kenburns-3;
animation-name: kenburns-3;
z-index: 1;
}
.slideshow-image:nth-child(4) {
-webkit-animation-name: kenburns-4;
animation-name: kenburns-4;
z-index: 0;
}
@-webkit-keyframes kenburns-1 {
0% {
opacity: 1;
transform: scale(1.2);
}
1.5625% {
opacity: 1;
}
23.4375% {
opacity: 1;
}
26.5625% {
opacity: 0;
transform: scale(1);
}
100% {
opacity: 0;
transform: scale(1.2);
}
98.4375% {
opacity: 0;
transform: scale(1.2117647059);
}
100% {
opacity: 1;
}
}
@keyframes kenburns-1 {
0% {
opacity: 1;
transform: scale(1.2);
}
1.5625% {
opacity: 1;
}
23.4375% {
opacity: 1;
}
26.5625% {
opacity: 0;
transform: scale(1);
}
100% {
opacity: 0;
transform: scale(1.2);
}
98.4375% {
opacity: 0;
transform: scale(1.2117647059);
}
100% {
opacity: 1;
}
}
@-webkit-keyframes kenburns-2 {
23.4375% {
opacity: 1;
transform: scale(1.2);
}
26.5625% {
opacity: 1;
}
48.4375% {
opacity: 1;
}
51.5625% {
opacity: 0;
transform: scale(1);
}
100% {
opacity: 0;
transform: scale(1.2);
}
}
@keyframes kenburns-2 {
23.4375% {
opacity: 1;
transform: scale(1.2);
}
26.5625% {
opacity: 1;
}
48.4375% {
opacity: 1;
}
51.5625% {
opacity: 0;
transform: scale(1);
}
100% {
opacity: 0;
transform: scale(1.2);
}
}
@-webkit-keyframes kenburns-3 {
48.4375% {
opacity: 1;
transform: scale(1.2);
}
51.5625% {
opacity: 1;
}
73.4375% {
opacity: 1;
}
76.5625% {
opacity: 0;
transform: scale(1);
}
100% {
opacity: 0;
transform: scale(1.2);
}
}
@keyframes kenburns-3 {
48.4375% {
opacity: 1;
transform: scale(1.2);
}
51.5625% {
opacity: 1;
}
73.4375% {
opacity: 1;
}
76.5625% {
opacity: 0;
transform: scale(1);
}
100% {
opacity: 0;
transform: scale(1.2);
}
}
@-webkit-keyframes kenburns-4 {
73.4375% {
opacity: 1;
transform: scale(1.2);
}
76.5625% {
opacity: 1;
}
98.4375% {
opacity: 1;
}
100% {
opacity: 0;
transform: scale(1);
}
}
@keyframes kenburns-4 {
73.4375% {
opacity: 1;
transform: scale(1.2);
}
76.5625% {
opacity: 1;
}
98.4375% {
opacity: 1;
}
100% {
opacity: 0;
transform: scale(1);
}
}
/* 相册 end*/
</style>
+519
View File
@@ -0,0 +1,519 @@
<template>
<view class="template-screen">
<!-- 顶部自定义导航 -->
<!-- <tn-nav-bar fixed alpha customBack>
<view slot="back" class='tn-custom-nav-bar__back'
@click="goBack">
<text class='icon tn-icon-left'></text>
<text class='icon tn-icon-home-capsule-fill'></text>
</view>
</tn-nav-bar> -->
<!-- 顶部自定义导航 -->
<tn-nav-bar :isBack="false" :bottomShadow="false" backgroundColor="none">
<view class="custom-nav tn-flex tn-flex-col-center tn-flex-row-left" @tap.stop="goBack">
<!-- 返回按钮 -->
<view class="custom-nav__back">
<view class="tn-icon-backspace tn-color-white" style="font-size: 60rpx;"></view>
</view>
<!-- -->
<view class="custom-nav__search tn-flex tn-flex-col-center tn-flex-row-center ">
<view class="custom-nav__search__box tn-flex tn-flex-col-center tn-flex-row-center tn-color-white">
<text class="tn-text-bold tn-text-xl">健康码</text>
</view>
</view>
</view>
</tn-nav-bar>
<!-- 页面内容 -->
<view class="bg-contaniner">
</view>
<view class="">
<view class="tn-margin-top" :style="{paddingTop: vuex_custom_bar_height + 'px'}">
<view class="tn-bg-white tn-margin tn-text-center" style="border-radius: 20rpx">
<view class="tn-flex tn-flex-row-around tn-padding-sm tn-bg-blue--light" style="border-radius: 20rpx 20rpx 0 0;">
<view class="justify-content-item">广州 <text class="tn-icon-down-triangle"></text> </view>
<view class="justify-content-item">*</view>
<view class="justify-content-item">添加成员</view>
</view>
<view class="">
<view class="tn-text-bold tn-margin-top-xl" style="font-size: 60rpx;">12-1 17:01:42</view>
<view class="tn-icon-qr-beibei tn-color-orange" style="font-size: 450rpx;">
</view>
<view class="tn-border-solid-top tn-padding">
<text class="tn-icon-qr-code tn-padding-right-sm"></text>
<text>不敢弄太真实万一坏人拿去了放黄码</text>
</view>
</view>
</view>
</view>
<!-- 方式12 start-->
<view class="tn-flex tn-margin-xs">
<view class="tn-flex-1 screen-shadow tn-bg-white" style="margin: 30rpx 20rpx;padding: 40rpx 0;">
<view class="tn-flex tn-flex-direction-column tn-flex-row-center tn-flex-col-center">
<view class="icon12__item--icon tn-flex tn-flex-row-center tn-flex-col-center tn-main-gradient-cyan--light tn-color-cyan--dark">
<view class="tn-icon-safe-fill tn-three"></view>
</view>
<view class="tn-text-center">
<view class="tn-text-ellipsis tn-text-xl tn-color-teal--dark">核酸阴性</view>
<view class="tn-text-ellipsis tn-color-gray--dark tn-padding-top-sm">2021-06-13 08:38</view>
</view>
</view>
</view>
<view class="tn-flex-1 screen-shadow tn-bg-white" style="margin: 30rpx 20rpx;padding: 40rpx 0;">
<view class="tn-flex tn-flex-direction-column tn-flex-row-center tn-flex-col-center">
<view class="icon12__item--icon tn-flex tn-flex-row-center tn-flex-col-center tn-main-gradient-cyan--light tn-color-cyan--dark">
<view class="tn-icon-trusty-fill tn-three"></view>
</view>
<view class="tn-text-center">
<view class="tn-text-ellipsis tn-text-xl tn-color-teal--dark">已完成全程接种</view>
<view class="tn-text-ellipsis tn-color-gray--dark tn-padding-top-sm">2021-11-15</view>
</view>
</view>
</view>
</view>
<view class="tn-bg-white" style="border-radius: 50rpx 50rpx 0 0;">
<!-- 方式12 start-->
<view class="tn-flex tn-flex-row-center tn-radius tn-padding-top">
<view class="tn-padding-sm tn-margin-xs tn-radius">
<view class="tn-flex tn-flex-direction-column tn-flex-row-center tn-flex-col-center">
<view class="icon12__item--icon tn-flex tn-flex-row-center tn-flex-col-center tn-main-gradient-orange--light tn-color-orange">
<view class="tn-icon-honor tn-three"></view>
</view>
<view class="tn-color-black tn-text-center">
<text class="tn-text-ellipsis">通关凭证</text>
</view>
</view>
</view>
<view class="tn-padding-sm tn-margin-xs tn-radius">
<view class="tn-flex tn-flex-direction-column tn-flex-row-center tn-flex-col-center">
<view class="icon12__item--icon tn-flex tn-flex-row-center tn-flex-col-center tn-main-gradient-purple--light tn-color-purple">
<view class="tn-icon-chemistry tn-three"></view>
</view>
<view class="tn-color-black tn-text-center">
<text class="tn-text-ellipsis">核酸检测</text>
</view>
</view>
</view>
<view class="tn-padding-sm tn-margin-xs tn-radius">
<view class="tn-flex tn-flex-direction-column tn-flex-row-center tn-flex-col-center">
<view class="icon12__item--icon tn-flex tn-flex-row-center tn-flex-col-center tn-main-gradient-blue--light tn-color-blue">
<view class="tn-icon-edit-form tn-three"></view>
</view>
<view class="tn-color-black tn-text-center">
<text class="tn-text-ellipsis">健康申报</text>
</view>
</view>
</view>
<view class="tn-padding-sm tn-margin-xs tn-radius">
<view class="tn-flex tn-flex-direction-column tn-flex-row-center tn-flex-col-center">
<view class="icon12__item--icon tn-flex tn-flex-row-center tn-flex-col-center tn-main-gradient-purplered--light tn-color-purplered">
<view class="tn-icon-identity tn-three"></view>
</view>
<view class="tn-color-black tn-text-center">
<text class="tn-text-ellipsis">通信行程</text>
</view>
</view>
</view>
</view>
<!-- 方式12 end-->
</view>
<!-- 图文 -->
<view class="tn-bg-white tn-flex tn-flex-direction-column" style="padding: 0 0 60rpx 0;">
<block v-for="(item,index) in content" :key="index">
<view class="tn-blogger-content__wrap">
<view class="">
<!-- 方式一 -->
<!-- <view class="tn-shadow-blur image-pic" :style="'background-image:url(' + item.mainImage + ')'">
<view class="image-qrcode">
</view>
</view> -->
<!-- 方式二 -->
<image
class="tn-blogger-content__main-image tn-blogger-content__main-image--1 tn-margin-bottom"
:src="item.mainImage"
mode="aspectFill"
></image>
</view>
<view class="tn-blogger-content__label tn-text-justify">
<text class="tn-blogger-content__label__desc tn-text-lg tn-text-bold tn-padding">{{ item.desc }}</text>
</view>
<view class="tn-flex tn-flex-row-between tn-flex-col-center tn-margin-top-xs">
<view class="justify-content-item tn-flex tn-flex-col-center">
<view style="margin-right: 10rpx;margin-left: 0rpx;">
<view class="tn-color-gray tn-padding">
<text class="tn-blogger-content__count-icon tn-icon-flower"></text>
<text class="tn-padding-right">{{ item.collectionCount }}</text>
<text class="tn-blogger-content__count-icon tn-icon-message"></text>
<text class="tn-padding-right">{{ item.commentCount }}</text>
<text class="tn-blogger-content__count-icon tn-icon-like"></text>
<text class="">{{ item.likeCount }}</text>
</view>
</view>
</view>
<view class="justify-content-item tn-text-center">
<view v-for="(label_item,label_index) in item.label" :key="label_index" class="tn-blogger-content__label__item tn-float-left tn-margin-right tn-bg-gray--light tn-round tn-text-sm tn-text-bold">
<text class="tn-blogger-content__label__item--prefix">#</text> {{ label_item }}
</view>
</view>
</view>
</view>
</block>
</view>
</view>
</view>
</template>
<script>
import template_page_mixin from '@/libs/mixin/template_page_mixin.js'
export default {
name: 'TemplateScreen',
mixins: [template_page_mixin],
data(){
return {
content: [
{
userAvatar: 'https://tnuiimage.tnkjapp.com/blogger/avatar_4.jpeg',
userName: '可我会像',
date: '2021年12月20日',
label: ['开源','创意'],
desc: '免费开源可商用组件',
mainImage:[
'https://tnuiimage.tnkjapp.com/shop/prototype1.jpg',
],
viewUser: {
latestUserAvatar: [
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_2.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_3.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_4.jpeg'},
],
viewUserCount: 65
},
collectionCount: 265,
commentCount: 22,
likeCount: 62
},
{
userAvatar: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg',
userName: '可我会像',
date: '2021年12月20日',
label: ['开源','创意'],
desc: '免费开源可商用组件',
mainImage:[
'https://tnuiimage.tnkjapp.com/shop/prototype2.jpg',
],
viewUser: {
latestUserAvatar: [
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_2.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_3.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_4.jpeg'},
],
viewUserCount: 65
},
collectionCount: 265,
commentCount: 22,
likeCount: 62
},
{
userAvatar: 'https://tnuiimage.tnkjapp.com/blogger/avatar_2.jpeg',
userName: '可我会像',
date: '2021年12月20日',
label: ['开源','创意'],
desc: '免费开源可商用组件',
mainImage:[
'https://tnuiimage.tnkjapp.com/shop/computer2.jpg',
],
viewUser: {
latestUserAvatar: [
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_2.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_3.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_4.jpeg'},
],
viewUserCount: 65
},
collectionCount: 265,
commentCount: 22,
likeCount: 62
},
{
userAvatar: 'https://tnuiimage.tnkjapp.com/blogger/avatar_3.jpeg',
userName: '可我会像',
date: '2021年12月20日',
label: ['站点','链接'],
desc: 'https://www.yuque.com/tuniao',
mainImage:[
'https://tnuiimage.tnkjapp.com/shop/pillow2.jpg',
],
viewUser: {
latestUserAvatar: [
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_2.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_3.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_4.jpeg'},
],
viewUserCount: 65
},
collectionCount: 265,
commentCount: 22,
likeCount: 62
},
{
userAvatar: 'https://tnuiimage.tnkjapp.com/blogger/blogger_beibei.jpg',
userName: '可我会像',
date: '2021年12月20日',
label: ['开源','创意'],
desc: '免费开源可商用组件',
mainImage:[
'https://tnuiimage.tnkjapp.com/blogger/blogger_beibei.jpg',
],
viewUser: {
latestUserAvatar: [
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_2.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_3.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_4.jpeg'},
],
viewUserCount: 65
},
collectionCount: 265,
commentCount: 22,
likeCount: 62
}
]
}
},
methods: {
}
}
</script>
<style lang="scss" scoped>
@import '@/static/css/templatePage/custom_nav_bar.scss';
/* 自定义导航栏内容 start */
.custom-nav {
height: 100%;
&__back {
margin: auto 5rpx;
font-size: 40rpx;
margin-right: 10rpx;
margin-left: 30rpx;
flex-basis: 5%;
}
&__search {
flex-basis: 71%;
width: 100%;
height: 100%;
&__box {
width: 100%;
height: 70%;
padding: 10rpx 0;
margin: 0 30rpx;
border-radius: 60rpx 60rpx 60rpx 0;
font-size: 24rpx;
// background-color: rgba(255,255,255,0.1);
}
&__icon {
padding-right: 10rpx;
margin-left: 20rpx;
font-size: 30rpx;
}
&__text {
}
}
}
/* 自定义导航栏内容 end */
.screen-shadow{
box-shadow: 0rpx 0rpx 80rpx 0rpx rgba(0, 0, 0, 0.07);
border-radius: 20rpx;
}
/* 图标容器12 start */
.icon12 {
&__item {
width: 30%;
background-color: #FFFFFF;
border-radius: 10rpx;
padding: 30rpx;
margin: 20rpx 10rpx;
transform: scale(1);
transition: transform 0.3s linear;
transform-origin: center center;
&--icon {
width: 100rpx;
height: 100rpx;
font-size: 60rpx;
border-radius: 50%;
margin-bottom: 18rpx;
position: relative;
z-index: 1;
&::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://tnuiimage.tnkjapp.com/cool_bg_image/icon_bg.png);
}
}
}
}
/* 文章内容 start*/
.tn-blogger-content {
&__wrap {
box-shadow: 0rpx 0rpx 80rpx 0rpx rgba(0, 0, 0, 0.09);
border-radius: 20rpx;
margin: 30rpx;
}
&__info {
&__btn {
margin-right: -12rpx;
opacity: 0.5;
}
}
&__label {
&__item {
line-height: 45rpx;
padding: 0 20rpx;
margin: 5rpx 18rpx 0 0;
&--prefix {
color: #00FFC8;
padding-right: 10rpx;
}
}
&__desc {
line-height: 55rpx;
}
}
&__main-image {
border-radius: 16rpx 16rpx 0 0;
&--1 {
max-width: 690rpx;
min-width: 690rpx;
max-height: 400rpx;
min-height: 400rpx;
}
&--2 {
max-width: 260rpx;
max-height: 260rpx;
}
&--3 {
height: 212rpx;
width: 100%;
}
}
&__count-icon {
font-size: 40rpx;
padding-right: 5rpx;
}
}
.image-qrcode{
padding: 180rpx 0rpx;
font-size: 40rpx;
font-weight: 300;
position: relative;
}
.image-pic{
background-size: cover;
background-repeat:no-repeat;
// background-attachment:fixed;
background-position:top;
border-radius: 10rpx;
}
/* 文章内容 end*/
/* 移动背景部分 start*/
.bg-contaniner {
position: fixed;
top: 0rpx;
left: 0rpx;
--text-color: hsl(0 95% 60%);
--bg-color: hsl(0 0% 100%);
--bg-size: 750rpx;
height: 100%;
display: grid;
place-items: center;
place-content: center;
overflow: hidden;
background-color: #4392F4;
z-index: -1;
}
.bg-contaniner::before {
--size: 150vmax;
grid-area: body;
content: "";
inline-size: var(--size);
block-size: var(--size);
background-image: url("https://tnuiimage.tnkjapp.com/animate/health.png");
background-size: var(--bg-size);
background-repeat: repeat;
transform: rotate(0deg);
opacity: 0.15;
animation: bg 6s linear infinite;
}
@media (prefers-reduced-motion: reduce) {
.bg-contaniner::before {
animation-duration: 0s;
}
}
@keyframes bg {
to {
background-position: 0 calc(var(--bg-size) * -1);
}
}
/* 移动背景部分 end*/
</style>
+647
View File
@@ -0,0 +1,647 @@
<template>
<view class="template-course">
<!-- 顶部自定义导航 -->
<!-- <tn-nav-bar fixed alpha customBack>
<view slot="back" class='tn-custom-nav-bar__back'
@click="goBack">
<text class='icon tn-icon-left'></text>
<text class='icon tn-icon-home-capsule-fill'></text>
</view>
</tn-nav-bar> -->
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed :isBack="false" :bottomShadow="false" backgroundColor="#FFFFFF">
<view class="custom-nav tn-flex tn-flex-col-center tn-flex-row-left">
<!-- 图标logo -->
<view class="custom-nav__back">
<view class="logo-pic tn-shadow-blur" style="background-image:url('https://tnuiimage.tnkjapp.com/logo/logo2.png')">
<view class="logo-image">
</view>
</view>
<!-- <view class="tn-icon-left"></view> -->
</view>
<!-- 搜索框 -->
<view class="custom-nav__search tn-flex tn-flex-col-center tn-flex-row-center ">
<view class="custom-nav__search__box tn-flex tn-flex-col-center tn-flex-row-left tn-color-gray--dark tn-bg-gray--light">
<view class="custom-nav__search__icon tn-icon-search"></view>
<view class="custom-nav__search__text tn-padding-left-xs">搜搜学习资料</view>
</view>
</view>
</view>
</tn-nav-bar>
<!-- 页面内容 -->
<view class="tn-margin" :style="{paddingTop: vuex_custom_bar_height + 'px'}">
<tn-swiper :list="banner" :height="350" :effect3d="false" mode="dot"></tn-swiper>
</view>
<view class="tn-padding-top-xs">
<!-- 方式15 start-->
<view class="tn-flex tn-margin tn-flex-row-center tn-bg-white course-shadow course-radius">
<view class="tn-padding-sm tn-margin-xs">
<view class="tn-flex tn-flex-direction-column tn-flex-row-center tn-flex-col-center">
<view class="icon15__item--icon tn-flex tn-flex-row-center tn-flex-col-center tn-shadow-blur tn-bg-orange tn-color-white">
<view class="tn-icon-calendar"></view>
</view>
<view class="tn-text-center">
<text class="tn-text-ellipsis">课程安排</text>
</view>
</view>
</view>
<view class="tn-padding-sm tn-margin-xs">
<view class="tn-flex tn-flex-direction-column tn-flex-row-center tn-flex-col-center">
<view class="icon15__item--icon tn-flex tn-flex-row-center tn-flex-col-center tn-shadow-blur tn-bg-bluepurple tn-color-white">
<view class="tn-icon-trophy"></view>
</view>
<view class="tn-text-center">
<text class="tn-text-ellipsis">获奖公告</text>
</view>
</view>
</view>
<view class="tn-padding-sm tn-margin-xs">
<view class="tn-flex tn-flex-direction-column tn-flex-row-center tn-flex-col-center">
<view class="icon15__item--icon tn-flex tn-flex-row-center tn-flex-col-center tn-shadow-blur tn-bg-indigo tn-color-white">
<view class="tn-icon-company"></view>
</view>
<view class="tn-text-center">
<text class="tn-text-ellipsis">校园活动</text>
</view>
</view>
</view>
<view class="tn-padding-sm tn-margin-xs">
<view class="tn-flex tn-flex-direction-column tn-flex-row-center tn-flex-col-center">
<view class="icon15__item--icon tn-flex tn-flex-row-center tn-flex-col-center tn-shadow-blur tn-bg-purplered tn-color-white">
<view class="tn-icon-comment"></view>
</view>
<view class="tn-text-center">
<text class="tn-text-ellipsis">家长反馈</text>
</view>
</view>
</view>
</view>
<!-- 方式15 end-->
<view class="tn-flex tn-flex-row-between tn-margin-sm tn-padding-top">
<view class="justify-content-item tn-text-bold tn-text-xl">
<text class="tn-icon-title "></text>
<text class="">教育专栏</text>
</view>
<view class="justify-content-item tn-text-lg">
<text class="tn-padding-xs">更多</text>
<text class="tn-icon-right"></text>
</view>
</view>
<view class="tn-info__container tn-flex tn-flex-wrap tn-flex-col-center tn-flex-row-between tn-margin-left tn-margin-right">
<block v-for="(item, index) in tuniaoData" :key="index">
<view class="tn-info__item tn-flex tn-flex-direction-row tn-flex-col-center tn-flex-row-between tn-color-white tn-bg-blue--light tn-shadow-blur">
<view class="tn-info__item__left tn-flex tn-flex-direction-row tn-flex-col-center tn-flex-row-left">
<view class="tn-info__item__left--icon tn-flex tn-flex-col-center tn-flex-row-center tn-color-white" :class="[`tn-bg-${item.color}--disabled`]">
<view :class="[`tn-icon-${item.icon}`]"></view>
</view>
<view class="tn-info__item__left__content">
<view class="tn-info__item__left__content--title tn-text-xl tn-color-aquablue--dark">{{ item.title }}</view>
<!-- <view class="tn-info__item__left__content--data tn-padding-top-xs tn-color-black">
{{ item.value }}
<text class="tn-icon-right tn-padding-left-xs"></text>
</view> -->
</view>
</view>
<!-- <view class="tn-info__item__right">
<view class="tn-info__item__right--icon">
<view :class="[`tn-icon-${item.icon}`]"></view>
</view>
</view> -->
</view>
</block>
</view>
<view class="tn-flex tn-flex-row-between tn-margin-sm">
<view class="justify-content-item tn-text-bold tn-text-xl">
<text class="tn-icon-title "></text>
<text class="">学习交流</text>
</view>
<view class="justify-content-item tn-text-lg">
<text class="tn-padding-xs">更多</text>
<text class="tn-icon-right"></text>
</view>
</view>
<!-- 比例 start-->
<view class="tn-flex tn-flex-wrap tn-margin-sm tn-padding-bottom-xl">
<block v-for="(item, index) in content" :key="index">
<view class="" style="width: 50%;">
<view class="tn-blogger-content__wrap">
<view class="image-pic" :style="'background-image:url(' + item.mainImage + ')'">
<view class="image-music">
</view>
</view>
<view class="tn-blogger-content__label tn-text-justify tn-padding-sm">
<text class="tn-blogger-content__label__desc">{{ item.desc }}</text>
</view>
<view class="tn-flex tn-flex-row-between tn-flex-col-center tn-padding-left-sm tn-padding-right-sm tn-padding-bottom-sm">
<view class="justify-content-item tn-flex tn-flex-col-center">
<view style="margin-right: 10rpx;margin-left: 20rpx;">
<tn-avatar-group :lists="item.viewUser.latestUserAvatar" size="sm"></tn-avatar-group>
</view>
<text class="tn-color-gray">{{ item.viewUser.viewUserCount }}</text>
</view>
</view>
</view>
</view>
</block>
</view>
<!-- 比例 end-->
</view>
<!-- 回到首页悬浮按钮-->
<nav-index-button></nav-index-button>
</view>
</template>
<script>
import template_page_mixin from '@/libs/mixin/template_page_mixin.js'
import NavIndexButton from '@/libs/components/nav-index-button.vue'
export default {
name: 'TemplateCourse',
mixins: [template_page_mixin],
components: { NavIndexButton },
data(){
return {
banner: [{
image: 'https://tnuiimage.tnkjapp.com/swiper/tnbanner1.jpg'
}, {
image: 'https://tnuiimage.tnkjapp.com/swiper/tnbanner2.jpg'
}, {
image: 'https://tnuiimage.tnkjapp.com/swiper/tnbanner3.jpg'
}, {
image: 'https://tnuiimage.tnkjapp.com/swiper/tnbanner4.jpg'
}],
tuniaoData: [
{
title: '热门专栏',
icon: 'fire-fill',
color: 'red',
value: '我就看看'
},
{
title: '优秀讲师',
icon: 'praise-fill',
color: 'blue',
value: '我就看看'
},
{
title: '必看攻略',
icon: 'cardbag-fill',
color: 'orange',
value: '我就看看'
},
{
title: '课程排行',
icon: 'honor-fill',
color: 'purple',
value: '我就看看'
}
],
content: [
{
userAvatar: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg',
userName: '可我会像',
date: '2021年12月20日',
label: ['烤肉','烤肉'],
desc: '免费开源可商用组件',
mainImage: 'https://tnuiimage.tnkjapp.com/shop/prototype2.jpg',
viewUser: {
latestUserAvatar: [
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_2.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_3.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_4.jpeg'},
],
viewUserCount: 129
},
collectionCount: 999,
commentCount: 999,
likeCount: 999
},
{
userAvatar: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg',
userName: '可我会像',
date: '2021年12月20日',
label: ['炸串','火锅'],
desc: '免费开源可商用组件',
mainImage: 'https://tnuiimage.tnkjapp.com/shop/prototype1.jpg',
viewUser: {
latestUserAvatar: [
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_2.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_3.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_4.jpeg'},
],
viewUserCount: 129
},
collectionCount: 265,
commentCount: 22,
likeCount: 62
},
{
userAvatar: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg',
userName: '可我会像',
date: '2021年12月20日',
label: ['烤肉','烤肉'],
desc: '免费开源可商用组件',
mainImage: 'https://tnuiimage.tnkjapp.com/shop/computer2.jpg',
viewUser: {
latestUserAvatar: [
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_2.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_3.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_4.jpeg'},
],
viewUserCount: 129
},
collectionCount: 265,
commentCount: 22,
likeCount: 62
},
{
userAvatar: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg',
userName: '可我会像',
date: '2021年12月20日',
label: ['烤肉','烤肉'],
desc: '免费开源可商用组件',
mainImage: 'https://tnuiimage.tnkjapp.com/shop/phonecase1.jpg',
viewUser: {
latestUserAvatar: [
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_2.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_3.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_4.jpeg'},
],
viewUserCount: 129
},
collectionCount: 265,
commentCount: 22,
likeCount: 62
},
{
userAvatar: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg',
userName: '可我会像',
date: '2021年12月20日',
label: ['烤肉','烤肉'],
desc: '免费开源可商用组件',
mainImage: 'https://tnuiimage.tnkjapp.com/shop/phonecase2.jpg',
viewUser: {
latestUserAvatar: [
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_2.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_3.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_4.jpeg'},
],
viewUserCount: 129
},
collectionCount: 265,
commentCount: 22,
likeCount: 62
},
{
userAvatar: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg',
userName: '可我会像',
date: '2021年12月20日',
label: ['烤肉','烤肉'],
desc: '我们都是好孩子',
mainImage: 'https://tnuiimage.tnkjapp.com/shop/watch1.jpg',
viewUser: {
latestUserAvatar: [
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_2.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_3.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_4.jpeg'},
],
viewUserCount: 129
},
collectionCount: 265,
commentCount: 22,
likeCount: 62
},
{
userAvatar: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg',
userName: '可我会像',
date: '2021年12月20日',
label: ['烤肉','烤肉'],
desc: '免费开源可商用组件',
mainImage: 'https://tnuiimage.tnkjapp.com/shop/sticker.jpg',
viewUser: {
latestUserAvatar: [
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_2.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_3.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_4.jpeg'},
],
viewUserCount: 129
},
collectionCount: 265,
commentCount: 22,
likeCount: 62
},
{
userAvatar: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg',
userName: '可我会像',
date: '2021年12月20日',
label: ['烤肉','烤肉'],
desc: '免费开源可商用组件',
mainImage: 'https://tnuiimage.tnkjapp.com/shop/card.jpg',
viewUser: {
latestUserAvatar: [
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_2.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_3.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_4.jpeg'},
],
viewUserCount: 129
},
collectionCount: 265,
commentCount: 22,
likeCount: 62
}
]
}
},
methods: {
}
}
</script>
<style lang="scss" scoped>
@import '@/static/css/templatePage/custom_nav_bar.scss';
/* 自定义导航栏内容 start */
.custom-nav {
height: 100%;
&__back {
margin: auto 5rpx;
font-size: 40rpx;
margin-right: 10rpx;
margin-left: 30rpx;
flex-basis: 5%;
}
&__search {
flex-basis: 60%;
width: 100%;
height: 100%;
&__box {
width: 100%;
height: 70%;
padding: 10rpx 0;
margin: 0 30rpx;
border-radius: 60rpx 60rpx 0 60rpx;
font-size: 24rpx;
}
&__icon {
padding-right: 10rpx;
margin-left: 20rpx;
font-size: 30rpx;
}
&__text {
color: #AAAAAA;
}
}
}
/*logo start */
.logo-image{
width: 65rpx;
height: 65rpx;
position: relative;
}
.logo-pic{
background-size: cover;
background-repeat:no-repeat;
// background-attachment:fixed;
background-position:top;
border-radius: 50%;
}
/* 自定义导航栏内容 end */
/* 内容布局 start*/
.course-shadow{
box-shadow: 0rpx 0rpx 80rpx 0rpx rgba(0, 0, 0, 0.07);
}
.course-radius{
border-radius: 15rpx;
}
/* 图标容器15 start */
.icon15 {
&__item {
width: 30%;
background-color: #FFFFFF;
border-radius: 10rpx;
padding: 30rpx;
margin: 20rpx 10rpx;
transform: scale(1);
transition: transform 0.3s linear;
transform-origin: center center;
&--icon {
width: 100rpx;
height: 100rpx;
font-size: 60rpx;
border-radius: 50%;
margin-bottom: 18rpx;
position: relative;
z-index: 1;
&::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%;
}
}
}
}
/* 业务展示 start */
.tn-info {
&__container {
margin-top: 10rpx;
margin-bottom: 50rpx;
}
&__item {
width: 48%;
margin: 15rpx 0rpx;
padding: 40rpx 30rpx;
border-radius: 15rpx;
position: relative;
z-index: 1;
&::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://tnuiimage.tnkjapp.com/cool_bg_image/3.png);
}
&__left {
&--icon {
width: 80rpx;
height: 80rpx;
border-radius: 30%;
font-size: 50rpx;
margin-right: 20rpx;
position: relative;
z-index: 1;
&::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://tnuiimage.tnkjapp.com/cool_bg_image/icon_bg5.png);
}
}
&__content {
font-size: 30rpx;
&--data {
margin-top: 5rpx;
font-weight: bold;
}
}
}
&__right {
&--icon {
position: absolute;
right: 0upx;
top: 50upx;
font-size: 100upx;
width: 108upx;
height: 108upx;
text-align: center;
line-height: 60upx;
opacity: 0.15;
}
}
}
}
/* 业务展示 end */
/* 文章内容 start*/
.tn-blogger-content {
&__wrap {
box-shadow: 0rpx 0rpx 80rpx 0rpx rgba(0, 0, 0, 0.07);
border-radius: 20rpx;
margin: 15rpx;
}
&__info {
&__btn {
margin-right: -12rpx;
opacity: 0.5;
}
}
&__label {
&__item {
line-height: 45rpx;
padding: 0 20rpx;
margin: 5rpx 18rpx 0 0;
&--prefix {
color: #82B2FF;
padding-right: 10rpx;
}
}
&__desc {
line-height: 35rpx;
}
}
&__main-image {
border-radius: 16rpx 16rpx 0 0;
&--1 {
max-width: 690rpx;
min-width: 690rpx;
max-height: 400rpx;
min-height: 400rpx;
}
&--2 {
max-width: 260rpx;
max-height: 260rpx;
}
&--3 {
height: 212rpx;
width: 100%;
}
}
&__count-icon {
font-size: 30rpx;
padding-right: 5rpx;
}
}
.image-music{
padding: 100rpx 0rpx;
font-size: 16rpx;
font-weight: 300;
position: relative;
}
.image-pic{
background-size: cover;
background-repeat:no-repeat;
// background-attachment:fixed;
background-position:top;
border-radius: 20rpx 20rpx 0 0;
}
/* 文章内容 end*/
</style>
+527
View File
@@ -0,0 +1,527 @@
<template>
<view class="template-design">
<!-- 顶部自定义导航 -->
<!-- <tn-nav-bar fixed alpha customBack>
<view slot="back" class='tn-custom-nav-bar__back'
@click="goBack">
<text class='icon tn-icon-left'></text>
<text class='icon tn-icon-home-capsule-fill'></text>
</view>
</tn-nav-bar> -->
<!-- 页面内容 -->
<view>
<tn-swiper :list="banner" :height="1000" :effect3d="false" mode="number"></tn-swiper>
</view>
<!-- 方式10 start-->
<view class="tn-flex tn-margin-top">
<view class="tn-flex-1 tn-padding-sm tn-margin-xs tn-radius">
<view class="tn-flex tn-flex-direction-column tn-flex-row-center tn-flex-col-center">
<view class="icon10__item--icon tn-flex tn-flex-row-center tn-flex-col-center tn-shadow-blur tn-bg-blue tn-color-white">
<view class="tn-icon-image-fill"></view>
</view>
<view class="tn-color-black tn-text-lg tn-text-center">
<text class="tn-text-ellipsis">相册</text>
</view>
</view>
</view>
<view class="tn-flex-1 tn-padding-sm tn-margin-xs tn-radius">
<view class="tn-flex tn-flex-direction-column tn-flex-row-center tn-flex-col-center">
<view class="icon10__item--icon tn-flex tn-flex-row-center tn-flex-col-center tn-shadow-blur tn-bg-red tn-color-white">
<view class="tn-icon-live-stream-fill"></view>
</view>
<view class="tn-color-black tn-text-lg tn-text-center">
<text class="tn-text-ellipsis">视频</text>
</view>
</view>
</view>
<view class="tn-flex-1 tn-padding-sm tn-margin-xs tn-radius">
<view class="tn-flex tn-flex-direction-column tn-flex-row-center tn-flex-col-center">
<view class="icon10__item--icon tn-flex tn-flex-row-center tn-flex-col-center tn-shadow-blur tn-bg-orange tn-color-white">
<view class="tn-icon-image-text-fill"></view>
</view>
<view class="tn-color-black tn-text-lg tn-text-center">
<text class="tn-text-ellipsis">日志</text>
</view>
</view>
</view>
<view class="tn-flex-1 tn-padding-sm tn-margin-xs tn-radius">
<view class="tn-flex tn-flex-direction-column tn-flex-row-center tn-flex-col-center">
<view class="icon10__item--icon tn-flex tn-flex-row-center tn-flex-col-center tn-shadow-blur tn-bg-purple tn-color-white">
<view class="tn-icon-topics-fill"></view>
</view>
<view class="tn-color-black tn-text-lg tn-text-center">
<text class="tn-text-ellipsis">话题</text>
</view>
</view>
</view>
<view class="tn-flex-1 tn-padding-sm tn-margin-xs tn-radius">
<view class="tn-flex tn-flex-direction-column tn-flex-row-center tn-flex-col-center">
<view class="icon10__item--icon tn-flex tn-flex-row-center tn-flex-col-center tn-shadow-blur tn-bg-cyan tn-color-white">
<view class="tn-icon-discover-fill"></view>
</view>
<view class="tn-color-black tn-text-lg tn-text-center">
<text class="tn-text-ellipsis">发现</text>
</view>
</view>
</view>
</view>
<!-- 方式10 end-->
<!-- 图文 -->
<view class="tn-flex tn-flex-direction-column tn-margin-bottom">
<block v-for="(item,index) in content" :key="index">
<view class="tn-blogger-content__wrap">
<view class="tn-padding-top-xs">
<!-- 方式一 -->
<view class="tn-shadow-blur image-pic" :style="'background-image:url(' + item.mainImage + ')'">
<view class="image-design">
</view>
</view>
<!-- 方式二 -->
<!-- <image
class="tn-blogger-content__main-image tn-shadow tn-blogger-content__main-image--1 tn-margin-bottom-sm"
:src="item.mainImage"
mode="aspectFill"
></image> -->
</view>
<view class="tn-blogger-content__label tn-text-justify tn-margin-top tn-margin-bottom-sm">
<text class="tn-blogger-content__label__desc tn-text-bold tn-text-xl">{{ item.desc }}</text>
</view>
<view class="tn-flex tn-flex-row-between tn-flex-col-center tn-margin-top-xs">
<view class="justify-content-item tn-flex tn-flex-col-center">
<view style="margin-right: 10rpx;margin-left: 0rpx;">
<view class="tn-color-gray">
<text class="tn-blogger-content__count-icon tn-icon-flower"></text>
<text class="tn-padding-right">{{ item.collectionCount }}</text>
<text class="tn-blogger-content__count-icon tn-icon-message"></text>
<text class="tn-padding-right">{{ item.commentCount }}</text>
<text class="tn-blogger-content__count-icon tn-icon-like"></text>
<text class="">{{ item.likeCount }}</text>
</view>
</view>
</view>
<view class="justify-content-item tn-text-center">
<view v-for="(label_item,label_index) in item.label" :key="label_index" class="tn-blogger-content__label__item tn-float-left tn-margin-right tn-bg-gray--light tn-round tn-text-sm tn-text-bold">
<text class="tn-blogger-content__label__item--prefix">#</text> {{ label_item }}
</view>
</view>
</view>
</view>
<!-- 边距间隔 -->
<view class="tn-strip-bottom" v-if="index != content.length - 1"></view>
</block>
</view>
<!-- 底部tabbar start-->
<view class="tabbar footerfixed">
<view class="action">
<view class="bar-icon">
<!-- <view class="tn-icon-home-smile">
</view> -->
<image class="" src='https://tnuiimage.tnkjapp.com/tabbar/home_tnnew.png'></image>
</view>
<view class="tn-color-black">首页</view>
</view>
<view class="action">
<view class="bar-icon">
<!-- <view class="tn-icon-discover">
</view> -->
<image class="" src='https://tnuiimage.tnkjapp.com/tabbar/information_tn.png'></image>
</view>
<view class="tn-color-gray">圈子</view>
</view>
<view class="action">
<view class="bar-icon">
<!-- <view class="tn-icon-image-text">
</view> -->
<image class="" src='https://tnuiimage.tnkjapp.com/tabbar/case_tn.png'></image>
</view>
<view class="tn-color-gray">案例</view>
</view>
<view class="action">
<view class="bar-icon">
<!-- <view class="tn-icon-my">
</view> -->
<image class="" src='https://tnuiimage.tnkjapp.com/tabbar/my_tn.png'></image>
</view>
<view class="tn-color-gray">我的</view>
</view>
</view>
<!-- 回到首页悬浮按钮-->
<nav-index-button></nav-index-button>
</view>
</template>
<script>
import template_page_mixin from '@/libs/mixin/template_page_mixin.js'
import NavIndexButton from '@/libs/components/nav-index-button.vue'
export default {
name: 'TemplateDesign',
mixins: [template_page_mixin],
components: { NavIndexButton },
data(){
return {
banner: [{
image: 'https://tnuiimage.tnkjapp.com/swiper/swiper1.jpg'
}, {
image: 'https://tnuiimage.tnkjapp.com/swiper/swiper2.jpg'
}, {
image: 'https://tnuiimage.tnkjapp.com/swiper/swiper3.jpg'
}, {
image: 'https://tnuiimage.tnkjapp.com/swiper/swiper4.jpg'
}],
content: [
{
userAvatar: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg',
userName: '可我会像',
date: '2021年12月20日',
label: ['开源','创意'],
desc: '免费开源可商用组件',
mainImage: 'https://tnuiimage.tnkjapp.com/shop/prototype2.jpg',
viewUser: {
latestUserAvatar: [
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_2.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_3.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_4.jpeg'},
],
viewUserCount: 129
},
collectionCount: 999,
commentCount: 999,
likeCount: 999
},
{
userAvatar: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg',
userName: '可我会像',
date: '2021年12月20日',
label: ['开源','创意'],
desc: '免费开源可商用组件',
mainImage: 'https://tnuiimage.tnkjapp.com/shop/prototype1.jpg',
viewUser: {
latestUserAvatar: [
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_2.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_3.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_4.jpeg'},
],
viewUserCount: 129
},
collectionCount: 265,
commentCount: 22,
likeCount: 62
},
{
userAvatar: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg',
userName: '可我会像',
date: '2021年12月20日',
label: ['开源','创意'],
desc: '免费开源可商用组件',
mainImage: 'https://tnuiimage.tnkjapp.com/shop/computer2.jpg',
viewUser: {
latestUserAvatar: [
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_2.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_3.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_4.jpeg'},
],
viewUserCount: 129
},
collectionCount: 265,
commentCount: 22,
likeCount: 62
},
{
userAvatar: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg',
userName: '可我会像',
date: '2021年12月20日',
label: ['开源','创意'],
desc: '免费开源可商用组件',
mainImage: 'https://tnuiimage.tnkjapp.com/shop/phonecase1.jpg',
viewUser: {
latestUserAvatar: [
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_2.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_3.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_4.jpeg'},
],
viewUserCount: 129
},
collectionCount: 265,
commentCount: 22,
likeCount: 62
},
{
userAvatar: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg',
userName: '可我会像',
date: '2021年12月20日',
label: ['开源','创意'],
desc: '免费开源可商用组件',
mainImage: 'https://tnuiimage.tnkjapp.com/shop/phonecase2.jpg',
viewUser: {
latestUserAvatar: [
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_2.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_3.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_4.jpeg'},
],
viewUserCount: 129
},
collectionCount: 265,
commentCount: 22,
likeCount: 62
},
{
userAvatar: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg',
userName: '可我会像',
date: '2021年12月20日',
label: ['开源','创意'],
desc: '我们都是好孩子',
mainImage: 'https://tnuiimage.tnkjapp.com/shop/watch1.jpg',
viewUser: {
latestUserAvatar: [
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_2.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_3.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_4.jpeg'},
],
viewUserCount: 129
},
collectionCount: 265,
commentCount: 22,
likeCount: 62
},
{
userAvatar: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg',
userName: '可我会像',
date: '2021年12月20日',
label: ['开源','创意'],
desc: '免费开源可商用组件',
mainImage: 'https://tnuiimage.tnkjapp.com/shop/sticker.jpg',
viewUser: {
latestUserAvatar: [
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_2.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_3.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_4.jpeg'},
],
viewUserCount: 129
},
collectionCount: 265,
commentCount: 22,
likeCount: 62
},
{
userAvatar: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg',
userName: '可我会像',
date: '2021年12月20日',
label: ['开源','创意'],
desc: '免费开源可商用组件',
mainImage: 'https://tnuiimage.tnkjapp.com/shop/card.jpg',
viewUser: {
latestUserAvatar: [
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_2.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_3.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_4.jpeg'},
],
viewUserCount: 129
},
collectionCount: 265,
commentCount: 22,
likeCount: 62
}
]
}
},
methods: {
}
}
</script>
<style lang="scss" scoped>
@import '@/static/css/templatePage/custom_nav_bar.scss';
.template-design{
margin-bottom: calc(110rpx + env(safe-area-inset-bottom) / 2);;
}
/* 图标容器10 start */
.icon10 {
&__item {
width: 30%;
background-color: #FFFFFF;
border-radius: 10rpx;
padding: 30rpx;
margin: 20rpx 10rpx;
transform: scale(1);
transition: transform 0.3s linear;
transform-origin: center center;
&--icon {
width: 84rpx;
height: 65rpx;
font-size: 45rpx;
border-radius: 200rpx;
margin-bottom: 18rpx;
position: relative;
z-index: 1;
&::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://tnuiimage.tnkjapp.com/cool_bg_image/icon_bg6.png);
}
}
}
}
/* 图标容器10 end */
/* 文章内容 start*/
.tn-blogger-content {
&__wrap {
padding: 30rpx;
}
&__info {
&__btn {
margin-right: -12rpx;
opacity: 0.5;
}
}
&__label {
&__item {
line-height: 45rpx;
padding: 0 20rpx;
margin: 5rpx 18rpx 0 0;
&--prefix {
color: #00FFC8;
padding-right: 10rpx;
}
}
&__desc {
line-height: 55rpx;
}
}
&__main-image {
box-shadow: 0rpx 5rpx 40rpx 0rpx rgba(43, 158, 246, 0.2);
border-radius: 16rpx;
&--1 {
max-width: 690rpx;
min-width: 690rpx;
max-height: 400rpx;
min-height: 400rpx;
}
&--2 {
max-width: 260rpx;
max-height: 260rpx;
}
&--3 {
height: 212rpx;
width: 100%;
}
}
&__count-icon {
font-size: 40rpx;
padding-right: 5rpx;
}
}
.image-design{
padding: 180rpx 0rpx;
font-size: 40rpx;
font-weight: 300;
position: relative;
}
.image-pic{
background-size: cover;
background-repeat:no-repeat;
// background-attachment:fixed;
background-position:top;
border-radius: 10rpx;
}
/* 文章内容 end*/
/* 间隔线 start*/
.tn-strip-bottom {
width: 100%;
border-bottom: 20rpx solid rgba(241, 241, 241, 0.3);
}
/* 间隔线 end*/
/* 底部tabbar start*/
.footerfixed{
position: fixed;
width: 100%;
bottom: 0;
z-index: 999;
background-color: #FFFFFF;
box-shadow: 0rpx 0rpx 30rpx 0rpx rgba(0, 0, 0, 0.07);
}
.tabbar {
display: flex;
align-items: center;
min-height: 110rpx;
justify-content: space-between;
padding: 0;
height: calc(110rpx + env(safe-area-inset-bottom) / 2);
padding-bottom: calc(env(safe-area-inset-bottom) / 2);
}
.tabbar .action {
font-size: 22rpx;
position: relative;
flex: 1;
text-align: center;
padding: 0;
display: block;
height: auto;
line-height: 1;
margin: 0;
overflow: initial;
}
.tabbar .action .bar-icon {
width: 100rpx;
position: relative;
display: block;
height: auto;
margin: 0 auto 10rpx;
text-align: center;
font-size: 42rpx;
}
.tabbar .action .bar-icon image {
width: 50rpx;
height: 50rpx;
display: inline-block;
}
</style>
+439
View File
@@ -0,0 +1,439 @@
<template>
<view class="template-job">
<!-- 顶部自定义导航 -->
<!-- <tn-nav-bar fixed alpha customBack>
<view slot="back" class='tn-custom-nav-bar__back'
@click="goBack">
<text class='icon tn-icon-left'></text>
<text class='icon tn-icon-home-capsule-fill'></text>
</view>
</tn-nav-bar> -->
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed :isBack="false" :bottomShadow="false" backgroundColor="#FFFFFF">
<view class="custom-nav tn-flex tn-flex-col-center tn-flex-row-left">
<!-- 返回按钮 -->
<view class="custom-nav__back">
<view class="logo-pic tn-shadow-blur" style="background-image:url('https://tnuiimage.tnkjapp.com/logo/logo2.png')">
<view class="logo-image">
</view>
</view>
<!-- <view class="tn-icon-left"></view> -->
</view>
<!-- 搜索框 -->
<view class="custom-nav__search tn-flex tn-flex-col-center tn-flex-row-center ">
<view class="custom-nav__search__box tn-flex tn-flex-col-center tn-flex-row-left tn-color-gray--dark tn-bg-gray--light">
<view class="custom-nav__search__icon tn-icon-search"></view>
<view class="custom-nav__search__text tn-padding-left-xs">好想搜点什么</view>
</view>
</view>
</view>
</tn-nav-bar>
<view class="tn-margin-top" :style="{paddingTop: vuex_custom_bar_height + 'px'}">
<tn-swiper :list="banner" :height="350" :effect3d="true" mode="round"></tn-swiper>
</view>
<!-- 数据信息 -->
<view class="tn-info__container tn-flex tn-flex-wrap tn-flex-col-center tn-flex-row-between tn-margin">
<block v-for="(item, index) in tuniaoData" :key="index">
<view class="tn-info__item tn-flex tn-flex-direction-row tn-flex-col-center tn-flex-row-between job-shadow">
<view class="tn-info__item__left tn-flex tn-flex-direction-row tn-flex-col-center tn-flex-row-left">
<view class="tn-info__item__left--icon tn-flex tn-flex-col-center tn-flex-row-center tn-color-white" :class="[`tn-bg-${item.color}`]">
<view :class="[`tn-icon-${item.icon}`]"></view>
</view>
<view class="tn-info__item__left__content">
<view class="tn-info__item__left__content--title">{{ item.title }}</view>
<view class="tn-info__item__left__content--data tn-padding-top-xs">{{ item.value }}</view>
</view>
</view>
<view class="tn-info__item__right">
<view class="tn-info__item__right--icon">
<view class="tn-icon-right"></view>
</view>
</view>
</view>
</block>
</view>
<!-- 方式16 start-->
<view class="tn-flex tn-flex-wrap tn-margin job-shadow tn-margin-bottom-xl">
<block v-for="(item, index) in icons" :key="index">
<view class=" " style="width: 25%;">
<view class="tn-flex tn-flex-direction-column tn-flex-row-center tn-flex-col-center tn-padding-xl">
<view class="icon16__item--icon tn-flex tn-flex-row-center tn-flex-col-center">
<view class="tn-cool-color-icon16" :class="[$t.colorUtils.getRandomCoolBgClass(index) + ' tn-icon-' + item.icon]"></view>
</view>
<view class="tn-color-black tn-text-lg tn-text-center">
<text class="tn-text-ellipsis">{{item.title}}</text>
</view>
</view>
</view>
</block>
</view>
<!-- 方式16 end-->
<!-- 回到首页悬浮按钮-->
<nav-index-button></nav-index-button>
</view>
</template>
<script>
import template_page_mixin from '@/libs/mixin/template_page_mixin.js'
import NavIndexButton from '@/libs/components/nav-index-button.vue'
export default {
name: 'TemplateJob',
mixins: [template_page_mixin],
components: { NavIndexButton },
data(){
return {
banner: [{
image: 'https://tnuiimage.tnkjapp.com/swiper/tnbanner1.jpg'
}, {
image: 'https://tnuiimage.tnkjapp.com/swiper/tnbanner2.jpg'
}, {
image: 'https://tnuiimage.tnkjapp.com/swiper/tnbanner3.jpg'
}, {
image: 'https://tnuiimage.tnkjapp.com/swiper/tnbanner4.jpg'
}],
tuniaoData: [
{
title: '职位推荐',
icon: 'praise',
color: 'purplered',
value: '32'
},
{
title: '课程专区',
icon: 'discover',
color: 'green',
value: '65'
},
{
title: '精选专题',
icon: 'topics',
color: 'orange',
value: '26'
},
{
title: '在线简历',
icon: 'honor',
color: 'indigo',
value: '6'
}
],
icons: [
{
icon: "shop",
title: "电商",
},
{
icon: "video",
title: "直播",
},
{
icon: "company",
title: "建筑",
},
{
icon: "computer",
title: "互联网",
},
{
icon: "focus",
title: "猎头",
},
{
icon: "sing",
title: "音乐",
},
{
icon: "code",
title: "软件开发",
},
{
icon: "medical",
title: "医疗",
},
{
icon: "biology",
title: "生物",
},
{
icon: "pharmacy",
title: "制药",
},
{
icon: "chemistry",
title: "化学",
},
{
icon: "creative",
title: "教师",
},
{
icon: "gloves",
title: "行政文秘",
},
{
icon: "caring",
title: "通信技术",
},
{
icon: "refund",
title: "外贸",
},
{
icon: "level",
title: "土木",
},
{
icon: "deploy",
title: "机械",
},
{
icon: "server",
title: "电气",
},
{
icon: "hardware",
title: "电子",
},
{
icon: "group-circle",
title: "化工",
},
{
icon: "cube",
title: "材料",
},
{
icon: "safe",
title: "保险",
},
{
icon: "coupon",
title: "证券",
},
{
icon: "funds",
title: "银行",
},
{
icon: "map",
title: "会展",
},
{
icon: "service",
title: "客服",
},
{
icon: "trophy",
title: "销售",
},
{
icon: "image-text",
title: "编辑运营",
},
{
icon: "brand",
title: "投行",
},
{
icon: "trusty",
title: "法务",
},
{
icon: "comment",
title: "咨询",
},
{
icon: "logistics",
title: "快递物流",
},
{
icon: "moon",
title: "艺术设计",
},
{
icon: "bankcard",
title: "财务",
},
{
icon: "trust",
title: "人力",
},
{
icon: "flag",
title: "市场营销",
},
{
icon: "signpost",
title: "其他",
}
],
}
},
methods: {
}
}
</script>
<style lang="scss" scoped>
@import '@/static/css/templatePage/custom_nav_bar.scss';
/* 自定义导航栏内容 start */
.custom-nav {
height: 100%;
&__back {
margin: auto 5rpx;
font-size: 40rpx;
margin-right: 10rpx;
margin-left: 30rpx;
flex-basis: 5%;
}
&__search {
flex-basis: 60%;
width: 100%;
height: 100%;
&__box {
width: 100%;
height: 70%;
padding: 10rpx 0;
margin: 0 30rpx;
border-radius: 60rpx 60rpx 0 60rpx;
font-size: 24rpx;
background-color: rgba(255,255,255,0.2);
}
&__icon {
padding-right: 10rpx;
margin-left: 20rpx;
font-size: 30rpx;
}
&__text {
}
}
}
/* 自定义导航栏内容 end */
/*logo start */
.logo-image{
width: 65rpx;
height: 65rpx;
position: relative;
}
.logo-pic{
background-size: cover;
background-repeat:no-repeat;
// background-attachment:fixed;
background-position:top;
border-radius: 50%;
}
/* 信息展示 start */
.tn-info {
&__container {
margin-top: 40rpx;
}
&__item {
width: 48%;
margin: 15rpx 0rpx;
padding: 38rpx 28rpx;
border-radius: 10rpx;
&__left {
&--icon {
width: 80rpx;
height: 80rpx;
border-radius: 50%;
font-size: 40rpx;
margin-right: 20rpx;
position: relative;
z-index: 1;
&::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://tnuiimage.tnkjapp.com/cool_bg_image/icon_bg3.png);
}
}
&__content {
font-size: 30rpx;
&--data {
margin-top: 5rpx;
font-weight: bold;
}
}
}
&__right {
&--icon {
font-size: 30rpx;
opacity: 0.5;
}
}
}
}
.job-shadow{
box-shadow: 0rpx 0rpx 80rpx 0rpx rgba(0, 0, 0, 0.07);
border-radius: 20rpx;
}
/* 信息展示 end */
/* 图标容器16 start */
.tn-cool-color-icon16{
// background-image: -webkit-linear-gradient(135deg, #ED1C24, #FECE12); 16
// background-image: linear-gradient(135deg, #ED1C24, #FECE12);
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
text-fill-color: transparent;
}
.icon16 {
&__item {
// width: 30%;
background-color: #FFFFFF;
border-radius: 10rpx;
padding: 0rpx;
margin: 0rpx;
transform: scale(1);
transition: transform 0.3s linear;
transform-origin: center center;
&--icon {
width: 100rpx;
height: 100rpx;
font-size: 70rpx;
border-radius: 50%;
margin-bottom: 18rpx;
position: relative;
z-index: 1;
}
}
}
/* 图标容器16 end */
</style>
+704
View File
@@ -0,0 +1,704 @@
<template>
<view class="template-music">
<!-- 顶部自定义导航 -->
<!-- <tn-nav-bar fixed alpha customBack>
<view slot="back" class='tn-custom-nav-bar__back'
@click="goBack">
<text class='icon tn-icon-left'></text>
<text class='icon tn-icon-home-capsule-fill'></text>
</view>
</tn-nav-bar> -->
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed :isBack="false" :bottomShadow="false" backgroundColor="#FFFFFF">
<view class="custom-nav tn-flex tn-flex-col-center tn-flex-row-left">
<!-- 返回按钮 -->
<view class="custom-nav__back">
<view class="tn-icon-sing" style="font-size: 60rpx;"></view>
</view>
<!-- 搜索框 -->
<view class="custom-nav__search tn-flex tn-flex-col-center tn-flex-row-center ">
<view class="custom-nav__search__box tn-flex tn-flex-col-center tn-flex-row-center tn-color-gray--dark tn-bg-gray--light">
<view class="custom-nav__search__icon tn-icon-search"></view>
<view class="custom-nav__search__text tn-padding-right">Craigie Hill 北北推荐吖</view>
</view>
</view>
</view>
</tn-nav-bar>
<view class="tn-margin-left tn-margin-right tn-margin-top-lg" :style="{paddingTop: vuex_custom_bar_height + 'px'}">
<tn-swiper :list="banner" :height="300" :effect3d="false" mode="round"></tn-swiper>
</view>
<!-- 方式12 start-->
<view class="tn-flex tn-margin-sm">
<view class="tn-flex-1 tn-padding-sm tn-margin-xs tn-radius">
<view class="tn-flex tn-flex-direction-column tn-flex-row-center tn-flex-col-center">
<view class="icon12__item--icon tn-flex tn-flex-row-center tn-flex-col-center tn-shadow-blur tn-main-gradient-purplered--light tn-color-purplered">
<view class="tn-icon-like-fill tn-three"></view>
</view>
<view class="tn-color-black tn-text-center">
<text class="tn-text-ellipsis">心动模式</text>
</view>
</view>
</view>
<view class="tn-flex-1 tn-padding-sm tn-margin-xs tn-radius">
<view class="tn-flex tn-flex-direction-column tn-flex-row-center tn-flex-col-center">
<view class="icon12__item--icon tn-flex tn-flex-row-center tn-flex-col-center tn-shadow-blur tn-main-gradient-indigo--light tn-color-indigo">
<view class="tn-icon-live-stream-fill tn-three"></view>
</view>
<view class="tn-color-black tn-text-center">
<text class="tn-text-ellipsis">优质MV</text>
</view>
</view>
</view>
<view class="tn-flex-1 tn-padding-sm tn-margin-xs tn-radius">
<view class="tn-flex tn-flex-direction-column tn-flex-row-center tn-flex-col-center">
<view class="icon12__item--icon tn-flex tn-flex-row-center tn-flex-col-center tn-shadow-blur tn-main-gradient-purple--light tn-color-purple">
<view class="tn-icon-moon-fill tn-three"></view>
</view>
<view class="tn-color-black tn-text-center">
<text class="tn-text-ellipsis">动听单曲</text>
</view>
</view>
</view>
<view class="tn-flex-1 tn-padding-sm tn-margin-xs tn-radius">
<view class="tn-flex tn-flex-direction-column tn-flex-row-center tn-flex-col-center">
<view class="icon12__item--icon tn-flex tn-flex-row-center tn-flex-col-center tn-shadow-blur tn-main-gradient-orange--light tn-color-orange">
<view class="tn-icon-statistics-fill tn-three"></view>
</view>
<view class="tn-color-black tn-text-center">
<text class="tn-text-ellipsis">排行榜</text>
</view>
</view>
</view>
</view>
<!-- 方式12 end-->
<!-- 图文 -->
<!-- 比例 start-->
<view class="tn-flex tn-flex-wrap tn-margin-sm">
<block v-for="(item, index) in content" :key="index">
<view class="" style="width: 50%;">
<view class="tn-blogger-content__wrap">
<view class="image-pic" :style="'background-image:url(' + item.mainImage + ')'">
<view class="image-music">
</view>
</view>
<view class="tn-blogger-content__label tn-text-justify tn-padding-sm">
<text class="tn-blogger-content__label__desc">{{ item.desc }}</text>
</view>
<view class="tn-flex tn-flex-row-between tn-flex-col-center tn-padding-left-sm tn-padding-right-sm tn-padding-bottom-sm">
<view class="justify-content-item tn-flex tn-flex-col-center">
<view>
<view class="tn-color-gray">
<text class="tn-blogger-content__count-icon tn-icon-flower"></text>
<text class="tn-padding-right-sm">{{ item.collectionCount }}</text>
<text class="tn-blogger-content__count-icon tn-icon-message"></text>
<text class="tn-padding-right-sm">{{ item.commentCount }}</text>
<text class="tn-blogger-content__count-icon tn-icon-like"></text>
<text class="">{{ item.likeCount }}</text>
</view>
</view>
</view>
<!-- <view class="justify-content-item tn-text-center">
<view v-for="(label_item,label_index) in item.label" :key="label_index" class="tn-blogger-content__label__item tn-float-left tn-margin-right tn-bg-gray--light tn-round tn-text-sm tn-text-bold">
<text class="tn-blogger-content__label__item--prefix">#</text> {{ label_item }}
</view>
</view> -->
</view>
</view>
</view>
</block>
</view>
<!-- 比例 end-->
<view class="tn-bg-white tn-flex tn-flex-direction-column tn-padding-bottom tn-margin-sm">
<block v-for="(item,index) in content" :key="index">
<view class="tn-blogger-content__wrap">
<view class="">
<!-- 方式一 -->
<view class="tn-shadow-blur image-pic" :style="'background-image:url(' + item.mainImage + ')'">
<view class="image-music">
</view>
</view>
<!-- 方式二 -->
<!-- <image
class="tn-blogger-content__main-image tn-blogger-content__main-image--1 tn-margin-bottom"
:src="item.mainImage"
mode="aspectFill"
></image> -->
</view>
<view class="tn-blogger-content__label tn-text-justify tn-margin">
<text class="tn-blogger-content__label__desc tn-text-lg tn-text-bold">{{ item.desc }}</text>
</view>
<view class="tn-flex tn-flex-row-between tn-flex-col-center tn-margin-top-xs">
<view class="justify-content-item tn-flex tn-flex-col-center">
<view style="margin-right: 10rpx;margin-left: 0rpx;">
<view class="tn-color-gray tn-padding-left tn-padding-right tn-padding-bottom">
<text class="tn-blogger-content__count-icon tn-icon-flower"></text>
<text class="tn-padding-right-sm">{{ item.collectionCount }}</text>
<text class="tn-blogger-content__count-icon tn-icon-message"></text>
<text class="tn-padding-right-sm">{{ item.commentCount }}</text>
<text class="tn-blogger-content__count-icon tn-icon-like"></text>
<text class="">{{ item.likeCount }}</text>
</view>
</view>
</view>
<view class="justify-content-item tn-text-center tn-padding-bottom">
<view v-for="(label_item,label_index) in item.label" :key="label_index" class="tn-blogger-content__label__item tn-float-left tn-margin-right tn-bg-gray--light tn-round tn-text-sm tn-text-bold">
<text class="tn-blogger-content__label__item--prefix">#</text> {{ label_item }}
</view>
</view>
</view>
</view>
</block>
</view>
<view class="tabbar footerfixed">
<view class="action navbar__item -blue">
<view class="bar-icon">
<view class="tn-icon-home-capsule navbar__icon">
</view>
</view>
<view class="-blue bar-text">
<text style="margin-bottom:-100rpx;font-size:20rpx;color:#303030;">首页</text>
</view>
</view>
<view class="action navbar__item -orange">
<view class="bar-icon">
<view class="tn-icon-discover-planet navbar__icon">
</view>
</view>
<view class="-orange bar-text">
<text style="margin-bottom:-100rpx;font-size:20rpx;color:#303030;">圈子</text>
</view>
</view>
<view class="action navbar__item -yellow">
<view class="bar-icon">
<view class="tn-icon-honor navbar__icon">
</view>
</view>
<view class="-yellow bar-text">
<text style="margin-bottom:-100rpx;font-size:20rpx;color:#303030;">榜单</text>
</view>
</view>
<view class="action navbar__item -purple">
<view class="bar-icon">
<view class="tn-icon-my navbar__icon">
<!-- <tn-badge :absolute="true">99+</tn-badge> -->
</view>
</view>
<view class="-purple bar-text">
<text style="margin-bottom:-100rpx;font-size:20rpx;color:#303030;">我的</text>
</view>
</view>
</view>
<!-- 回到首页悬浮按钮-->
<nav-index-button></nav-index-button>
</view>
</template>
<script>
import template_page_mixin from '@/libs/mixin/template_page_mixin.js'
import NavIndexButton from '@/libs/components/nav-index-button.vue'
export default {
name: 'TemplateMusic',
mixins: [template_page_mixin],
components: { NavIndexButton },
data(){
return {
banner: [{
image: 'https://tnuiimage.tnkjapp.com/swiper/tnbanner1.jpg'
}, {
image: 'https://tnuiimage.tnkjapp.com/swiper/tnbanner2.jpg'
}, {
image: 'https://tnuiimage.tnkjapp.com/swiper/tnbanner3.jpg'
}, {
image: 'https://tnuiimage.tnkjapp.com/swiper/tnbanner4.jpg'
}],
content: [
{
userAvatar: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg',
userName: '可我会像',
date: '2021年12月20日',
label: ['开源','创意'],
desc: '免费开源可商用组件',
mainImage: 'https://tnuiimage.tnkjapp.com/shop/prototype2.jpg',
viewUser: {
latestUserAvatar: [
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_2.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_3.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_4.jpeg'},
],
viewUserCount: 129
},
collectionCount: 999,
commentCount: 999,
likeCount: 999
},
{
userAvatar: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg',
userName: '可我会像',
date: '2021年12月20日',
label: ['开源','创意'],
desc: '免费开源可商用组件',
mainImage: 'https://tnuiimage.tnkjapp.com/shop/prototype1.jpg',
viewUser: {
latestUserAvatar: [
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_2.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_3.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_4.jpeg'},
],
viewUserCount: 129
},
collectionCount: 265,
commentCount: 22,
likeCount: 62
},
{
userAvatar: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg',
userName: '可我会像',
date: '2021年12月20日',
label: ['开源','创意'],
desc: '免费开源可商用组件',
mainImage: 'https://tnuiimage.tnkjapp.com/shop/computer2.jpg',
viewUser: {
latestUserAvatar: [
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_2.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_3.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_4.jpeg'},
],
viewUserCount: 129
},
collectionCount: 265,
commentCount: 22,
likeCount: 62
},
{
userAvatar: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg',
userName: '可我会像',
date: '2021年12月20日',
label: ['开源','创意'],
desc: '免费开源可商用组件',
mainImage: 'https://tnuiimage.tnkjapp.com/shop/phonecase1.jpg',
viewUser: {
latestUserAvatar: [
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_2.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_3.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_4.jpeg'},
],
viewUserCount: 129
},
collectionCount: 265,
commentCount: 22,
likeCount: 62
},
{
userAvatar: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg',
userName: '可我会像',
date: '2021年12月20日',
label: ['开源','创意'],
desc: '免费开源可商用组件',
mainImage: 'https://tnuiimage.tnkjapp.com/shop/phonecase2.jpg',
viewUser: {
latestUserAvatar: [
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_2.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_3.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_4.jpeg'},
],
viewUserCount: 129
},
collectionCount: 265,
commentCount: 22,
likeCount: 62
},
{
userAvatar: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg',
userName: '可我会像',
date: '2021年12月20日',
label: ['开源','创意'],
desc: '我们都是好孩子',
mainImage: 'https://tnuiimage.tnkjapp.com/shop/watch1.jpg',
viewUser: {
latestUserAvatar: [
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_2.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_3.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_4.jpeg'},
],
viewUserCount: 129
},
collectionCount: 265,
commentCount: 22,
likeCount: 62
},
{
userAvatar: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg',
userName: '可我会像',
date: '2021年12月20日',
label: ['开源','创意'],
desc: '免费开源可商用组件',
mainImage: 'https://tnuiimage.tnkjapp.com/shop/sticker.jpg',
viewUser: {
latestUserAvatar: [
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_2.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_3.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_4.jpeg'},
],
viewUserCount: 129
},
collectionCount: 265,
commentCount: 22,
likeCount: 62
},
{
userAvatar: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg',
userName: '可我会像',
date: '2021年12月20日',
label: ['开源','创意'],
desc: '免费开源可商用组件',
mainImage: 'https://tnuiimage.tnkjapp.com/shop/card.jpg',
viewUser: {
latestUserAvatar: [
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_2.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_3.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_4.jpeg'},
],
viewUserCount: 129
},
collectionCount: 265,
commentCount: 22,
likeCount: 62
}
]
}
},
methods: {
}
}
</script>
<style lang="scss" scoped>
@import '@/static/css/templatePage/custom_nav_bar.scss';
.template-music{
margin-bottom: calc(110rpx + env(safe-area-inset-bottom) / 2);;
}
/* 自定义导航栏内容 start */
.custom-nav {
height: 100%;
&__back {
margin: auto 5rpx;
font-size: 40rpx;
margin-right: 10rpx;
margin-left: 30rpx;
flex-basis: 5%;
}
&__search {
flex-basis: 60%;
width: 100%;
height: 100%;
&__box {
width: 100%;
height: 70%;
padding: 10rpx 0;
margin: 0 30rpx;
border-radius: 60rpx 60rpx 0 60rpx;
font-size: 24rpx;
background-color: rgba(255,255,255,0.2);
}
&__icon {
padding-right: 10rpx;
margin-left: 20rpx;
font-size: 30rpx;
}
&__text {
}
}
}
/* 自定义导航栏内容 end */
/* 图标容器12 start */
.tn-three{
position: absolute;
top: 50%;
right: 50%;
bottom: 50%;
left: 50%;
transform: translate(-38rpx, -16rpx) rotateX(30deg) rotateY(20deg) rotateZ(-30deg);
text-shadow: -1rpx 2rpx 0 #f0f0f0, -2rpx 4rpx 0 #f0f0f0, -10rpx 20rpx 30rpx rgba(0, 0, 0, 0.2);
}
.icon12 {
&__item {
width: 30%;
background-color: #FFFFFF;
border-radius: 10rpx;
padding: 30rpx;
margin: 20rpx 10rpx;
transform: scale(1);
transition: transform 0.3s linear;
transform-origin: center center;
&--icon {
width: 100rpx;
height: 100rpx;
font-size: 60rpx;
border-radius: 50%;
margin-bottom: 18rpx;
position: relative;
z-index: 1;
&::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://tnuiimage.tnkjapp.com/cool_bg_image/icon_bg.png);
}
}
}
}
/* 文章内容 start*/
.tn-blogger-content {
&__wrap {
box-shadow: 0rpx 0rpx 50rpx 0rpx rgba(0, 0, 0, 0.12);
border-radius: 20rpx;
margin: 15rpx;
}
&__info {
&__btn {
margin-right: -12rpx;
opacity: 0.5;
}
}
&__label {
&__item {
line-height: 45rpx;
padding: 0 20rpx;
margin: 5rpx 18rpx 0 0;
&--prefix {
color: #82B2FF;
padding-right: 10rpx;
}
}
&__desc {
line-height: 35rpx;
}
}
&__main-image {
border-radius: 16rpx 16rpx 0 0;
&--1 {
max-width: 690rpx;
min-width: 690rpx;
max-height: 400rpx;
min-height: 400rpx;
}
&--2 {
max-width: 260rpx;
max-height: 260rpx;
}
&--3 {
height: 212rpx;
width: 100%;
}
}
&__count-icon {
font-size: 30rpx;
padding-right: 5rpx;
}
}
.image-music{
padding: 150rpx 0rpx;
font-size: 16rpx;
font-weight: 300;
position: relative;
}
.image-pic{
background-size: cover;
background-repeat:no-repeat;
// background-attachment:fixed;
background-position:top;
border-radius: 20rpx 20rpx 0 0;
}
/* 文章内容 end*/
/* 底部tabbar start*/
.footerfixed{
position: fixed;
width: 100%;
bottom: 0;
z-index: 999;
background-color: #FFFFFF;
box-shadow: 0rpx 0rpx 30rpx 0rpx rgba(0, 0, 0, 0.07);
}
.tabbar {
display: flex;
align-items: center;
min-height: 110rpx;
justify-content: space-between;
padding: 0;
height: calc(110rpx + env(safe-area-inset-bottom) / 2);
padding-bottom: calc(env(safe-area-inset-bottom) / 2);
}
.tabbar .action {
font-size: 22rpx;
position: relative;
flex: 1;
text-align: center;
padding: 0;
display: block;
height: auto;
line-height: 1;
margin: 0;
overflow: initial;
}
.tabbar .action .bar-icon {
width: 100rpx;
position: relative;
display: block;
height: auto;
margin: 0 auto 10rpx;
text-align: center;
font-size: 42rpx;
}
.tabbar .action .bar-icon image {
width: 50rpx;
height: 50rpx;
display: inline-block;
}
/* 底部标签栏动画 */
.navbar__item .bar-text {
font-variant: small-caps;
margin: 0;
padding: 0;
display: inline-flex;
text-align: center;
justify-content: center;
align-items: center;
white-space: nowrap;
position: relative;
width: 50rpx;
height: 50rpx;
background-size: cover;
background-position: center;
vertical-align: middle;
background-color: currentColor;
border-radius: 50%;
transform: scale(0.8);
opacity: 0;
transition: all 0.55s cubic-bezier(0.71, 0.03, 0.23, 0.95);
}
.navbar__item.-blue {
color: #06b8ff;
}
.navbar__item.-orange {
color: #f2704d;
}
.navbar__item.-yellow {
color: #f8cd4b;
}
.navbar__item.-purple {
color: #8444d6;
}
.bar-text.-blue {
color: #06b8ff;
}
.bar-text.-orange {
color: #f2704d;
}
.bar-text.-yellow {
color: #f8cd4b;
}
.bar-text.-purple {
color: #8444d6;
}
.navbar__item:hover .bar-text {
transform: translateY(-74rpx) scale(1.4);
opacity: 1;
box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.1),
-1px -1px 5px rgba(255, 255, 255, 1);
}
.navbar__item:hover::before {
opacity: 1;
}
.navbar__item:hover::after {
opacity: 0.4;
}
.navbar__item:hover .navbar__icon {
transform: translateY(-42rpx) scale(1);
color: #fff;
transition-delay: 0.1s, 0.1s;
}
.navbar__icon {
bottom: -26rpx;
transition: all 0.5s cubic-bezier(0.71, 0.03, 0.23, 0.95);
transition-delay: 0.1s;
display: inline-block;
position: relative;
z-index: 2;
}
</style>
+604
View File
@@ -0,0 +1,604 @@
<template>
<view class="template-screen">
<!-- 顶部自定义导航 -->
<!-- <tn-nav-bar fixed alpha customBack>
<view slot="back" class='tn-custom-nav-bar__back'
@click="goBack">
<text class='icon tn-icon-left'></text>
<text class='icon tn-icon-home-capsule-fill'></text>
</view>
</tn-nav-bar> -->
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed :isBack="false" :bottomShadow="false" backgroundColor="#3D7EFF80">
<view class="custom-nav tn-flex tn-flex-col-center tn-flex-row-left">
<!-- 按钮 -->
<view class="custom-nav__back">
<view class="tn-icon-caring tn-color-white" style="font-size: 60rpx;"></view>
</view>
<!-- 搜索框 -->
<view class="custom-nav__search tn-flex tn-flex-col-center tn-flex-row-center ">
<view class="custom-nav__search__box tn-flex tn-flex-col-center tn-flex-row-left tn-color-white">
<view class="custom-nav__search__icon tn-icon-search"></view>
<view class="custom-nav__search__text tn-padding-left-xs">试试搜索电影投屏</view>
</view>
</view>
</view>
</tn-nav-bar>
<!-- 页面内容 -->
<view class="bg-contaniner tn-bg-blue">
</view>
<view class="tn-margin-top-lg" style="padding-bottom: 120rpx;">
<view class="tn-padding" :style="{paddingTop: vuex_custom_bar_height + 'px'}">
<tn-swiper :list="banner" :height="350" :effect3d="false" mode="dot"></tn-swiper>
</view>
<!-- 方式15 start-->
<view class="tn-flex tn-margin-sm tn-flex-row-center tn-radius">
<view class="tn-padding-sm tn-margin-xs tn-radius">
<view class="tn-flex tn-flex-direction-column tn-flex-row-center tn-flex-col-center">
<view class="icon15__item--icon tn-flex tn-flex-row-center tn-flex-col-center tn-color-white" style="background-color: rgba(255,255,255,0.1);">
<view class="tn-icon-scan"></view>
</view>
<view class="tn-color-white tn-text-center">
<text class="tn-text-ellipsis">扫码投屏</text>
</view>
</view>
</view>
<view class="tn-padding-sm tn-margin-xs tn-radius">
<view class="tn-flex tn-flex-direction-column tn-flex-row-center tn-flex-col-center">
<view class="icon15__item--icon tn-flex tn-flex-row-center tn-flex-col-center tn-color-white" style="background-color: rgba(255,255,255,0.1);">
<view class="tn-icon-share-circle"></view>
</view>
<view class="tn-color-white tn-text-center">
<text class="tn-text-ellipsis">邀请投屏</text>
</view>
</view>
</view>
<view class="tn-padding-sm tn-margin-xs tn-radius">
<view class="tn-flex tn-flex-direction-column tn-flex-row-center tn-flex-col-center">
<view class="icon15__item--icon tn-flex tn-flex-row-center tn-flex-col-center tn-color-white" style="background-color: rgba(255,255,255,0.1);">
<view class="tn-icon-star"></view>
</view>
<view class="tn-color-white tn-text-center">
<text class="tn-text-ellipsis">收藏投屏</text>
</view>
</view>
</view>
<view class="tn-padding-sm tn-margin-xs tn-radius">
<view class="tn-flex tn-flex-direction-column tn-flex-row-center tn-flex-col-center">
<view class="icon15__item--icon tn-flex tn-flex-row-center tn-flex-col-center tn-color-white" style="background-color: rgba(255,255,255,0.1);">
<view class="tn-icon-set"></view>
</view>
<view class="tn-color-white tn-text-center">
<text class="tn-text-ellipsis">投屏设置</text>
</view>
</view>
</view>
</view>
<!-- 方式15 end-->
</view>
<view class="tn-bg-white" style="margin-top: -100rpx;border-radius: 50rpx 50rpx 0 0;">
<!-- 方式7 start-->
<view class="tn-flex tn-margin-xs tn-padding-top-xl">
<view class="tn-flex-1 screen-shadow" style="margin: 30rpx 20rpx;padding: 60rpx 0;">
<view class="tn-flex tn-flex-direction-column tn-flex-row-center tn-flex-col-center">
<view class="icon7__item--icon tn-flex tn-flex-row-center tn-flex-col-center">
<image class="" src='https://tnuiimage.tnkjapp.com/icon/5.jpg' mode='aspectFit'></image>
</view>
<view class="tn-text-center">
<view class="tn-text-ellipsis tn-color-black tn-text-lg ">资料投屏</view>
<view class="tn-text-ellipsis tn-color-gray--dark">选择资料投屏</view>
</view>
</view>
</view>
<view class="tn-flex-1 screen-shadow" style="margin: 30rpx 20rpx;padding: 60rpx 0;">
<view class="tn-flex tn-flex-direction-column tn-flex-row-center tn-flex-col-center">
<view class="icon7__item--icon tn-flex tn-flex-row-center tn-flex-col-center">
<image class="" src='https://tnuiimage.tnkjapp.com/icon/6.jpg' mode='aspectFit'></image>
</view>
<view class="tn-text-center">
<view class="tn-text-ellipsis tn-color-black tn-text-lg ">文件投屏</view>
<view class="tn-text-ellipsis tn-color-gray--dark">选择文件投屏</view>
</view>
</view>
</view>
</view>
<view class="tn-flex tn-margin-xs" style="margin-top: -10rpx;">
<view class="tn-flex-1 screen-shadow" style="margin: 10rpx 20rpx;padding: 60rpx 0;">
<view class="tn-flex tn-flex-direction-column tn-flex-row-center tn-flex-col-center">
<view class="icon7__item--icon tn-flex tn-flex-row-center tn-flex-col-center">
<image class="" src='https://tnuiimage.tnkjapp.com/icon/7.jpg' mode='aspectFit'></image>
</view>
<view class="tn-text-center">
<view class="tn-text-ellipsis tn-color-black tn-text-lg ">电脑投屏</view>
<view class="tn-text-ellipsis tn-color-gray--dark">匹配电脑投屏</view>
</view>
</view>
</view>
<view class="tn-flex-1 screen-shadow" style="margin: 10rpx 20rpx;padding: 60rpx 0;">
<view class="tn-flex tn-flex-direction-column tn-flex-row-center tn-flex-col-center">
<view class="icon7__item--icon tn-flex tn-flex-row-center tn-flex-col-center">
<image class="" src='https://tnuiimage.tnkjapp.com/icon/8.jpg' mode='aspectFit'></image>
</view>
<view class="tn-text-center">
<view class="tn-text-ellipsis tn-color-black tn-text-lg ">文档投屏</view>
<view class="tn-text-ellipsis tn-color-gray--dark">选择文档投屏</view>
</view>
</view>
</view>
</view>
<!-- 方式7 end-->
<!-- 图文 -->
<view class="tn-bg-white tn-flex tn-flex-direction-column tn-padding-bottom">
<block v-for="(item,index) in content" :key="index">
<view class="tn-blogger-content__wrap">
<view class="">
<!-- 方式一 -->
<!-- <view class="tn-shadow-blur image-pic" :style="'background-image:url(' + item.mainImage + ')'">
<view class="image-screen">
</view>
</view> -->
<!-- 方式二 -->
<image
class="tn-blogger-content__main-image tn-blogger-content__main-image--1 tn-margin-bottom"
:src="item.mainImage"
mode="aspectFill"
></image>
</view>
<view class="tn-blogger-content__label tn-text-justify">
<text class="tn-blogger-content__label__desc tn-text-lg tn-text-bold tn-padding">{{ item.desc }}</text>
</view>
<view class="tn-flex tn-flex-row-between tn-flex-col-center tn-margin-top-xs">
<view class="justify-content-item tn-flex tn-flex-col-center">
<view style="margin-right: 10rpx;margin-left: 0rpx;">
<view class="tn-color-gray tn-padding">
<text class="tn-blogger-content__count-icon tn-icon-flower"></text>
<text class="tn-padding-right">{{ item.collectionCount }}</text>
<text class="tn-blogger-content__count-icon tn-icon-message"></text>
<text class="tn-padding-right">{{ item.commentCount }}</text>
<text class="tn-blogger-content__count-icon tn-icon-like"></text>
<text class="">{{ item.likeCount }}</text>
</view>
</view>
</view>
<view class="justify-content-item tn-text-center">
<view v-for="(label_item,label_index) in item.label" :key="label_index" class="tn-blogger-content__label__item tn-float-left tn-margin-right tn-bg-gray--light tn-round tn-text-sm tn-text-bold">
<text class="tn-blogger-content__label__item--prefix">#</text> {{ label_item }}
</view>
</view>
</view>
</view>
</block>
</view>
</view>
<!-- 回到首页悬浮按钮-->
<nav-index-button></nav-index-button>
</view>
</template>
<script>
import template_page_mixin from '@/libs/mixin/template_page_mixin.js'
import NavIndexButton from '@/libs/components/nav-index-button.vue'
export default {
name: 'TemplateScreen',
mixins: [template_page_mixin],
components: { NavIndexButton },
data(){
return {
banner: [{
image: 'https://tnuiimage.tnkjapp.com/shop/banner1.jpg'
}, {
image: 'https://tnuiimage.tnkjapp.com/shop/banner2.jpg'
}, {
image: 'https://tnuiimage.tnkjapp.com/shop/banner1.jpg'
}, {
image: 'https://tnuiimage.tnkjapp.com/shop/banner2.jpg'
}],
content: [
{
userAvatar: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg',
userName: '可我会像',
date: '2021年12月20日',
label: ['开源','创意'],
desc: '免费开源可商用组件',
mainImage: 'https://tnuiimage.tnkjapp.com/shop/prototype2.jpg',
viewUser: {
latestUserAvatar: [
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_2.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_3.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_4.jpeg'},
],
viewUserCount: 129
},
collectionCount: 999,
commentCount: 999,
likeCount: 999
},
{
userAvatar: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg',
userName: '可我会像',
date: '2021年12月20日',
label: ['开源','创意'],
desc: '免费开源可商用组件',
mainImage: 'https://tnuiimage.tnkjapp.com/shop/prototype1.jpg',
viewUser: {
latestUserAvatar: [
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_2.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_3.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_4.jpeg'},
],
viewUserCount: 129
},
collectionCount: 265,
commentCount: 22,
likeCount: 62
},
{
userAvatar: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg',
userName: '可我会像',
date: '2021年12月20日',
label: ['开源','创意'],
desc: '免费开源可商用组件',
mainImage: 'https://tnuiimage.tnkjapp.com/shop/computer2.jpg',
viewUser: {
latestUserAvatar: [
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_2.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_3.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_4.jpeg'},
],
viewUserCount: 129
},
collectionCount: 265,
commentCount: 22,
likeCount: 62
},
{
userAvatar: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg',
userName: '可我会像',
date: '2021年12月20日',
label: ['开源','创意'],
desc: '免费开源可商用组件',
mainImage: 'https://tnuiimage.tnkjapp.com/shop/phonecase1.jpg',
viewUser: {
latestUserAvatar: [
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_2.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_3.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_4.jpeg'},
],
viewUserCount: 129
},
collectionCount: 265,
commentCount: 22,
likeCount: 62
},
{
userAvatar: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg',
userName: '可我会像',
date: '2021年12月20日',
label: ['开源','创意'],
desc: '免费开源可商用组件',
mainImage: 'https://tnuiimage.tnkjapp.com/shop/phonecase2.jpg',
viewUser: {
latestUserAvatar: [
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_2.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_3.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_4.jpeg'},
],
viewUserCount: 129
},
collectionCount: 265,
commentCount: 22,
likeCount: 62
},
{
userAvatar: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg',
userName: '可我会像',
date: '2021年12月20日',
label: ['开源','创意'],
desc: '我们都是好孩子',
mainImage: 'https://tnuiimage.tnkjapp.com/shop/watch1.jpg',
viewUser: {
latestUserAvatar: [
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_2.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_3.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_4.jpeg'},
],
viewUserCount: 129
},
collectionCount: 265,
commentCount: 22,
likeCount: 62
},
{
userAvatar: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg',
userName: '可我会像',
date: '2021年12月20日',
label: ['开源','创意'],
desc: '免费开源可商用组件',
mainImage: 'https://tnuiimage.tnkjapp.com/shop/sticker.jpg',
viewUser: {
latestUserAvatar: [
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_2.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_3.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_4.jpeg'},
],
viewUserCount: 129
},
collectionCount: 265,
commentCount: 22,
likeCount: 62
},
{
userAvatar: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg',
userName: '可我会像',
date: '2021年12月20日',
label: ['开源','创意'],
desc: '免费开源可商用组件',
mainImage: 'https://tnuiimage.tnkjapp.com/shop/card.jpg',
viewUser: {
latestUserAvatar: [
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_2.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_3.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_4.jpeg'},
],
viewUserCount: 129
},
collectionCount: 265,
commentCount: 22,
likeCount: 62
}
]
}
},
methods: {
}
}
</script>
<style lang="scss" scoped>
@import '@/static/css/templatePage/custom_nav_bar.scss';
/* 自定义导航栏内容 start */
.custom-nav {
height: 100%;
&__back {
margin: auto 5rpx;
font-size: 40rpx;
margin-right: 10rpx;
margin-left: 30rpx;
flex-basis: 5%;
}
&__search {
flex-basis: 60%;
width: 100%;
height: 100%;
&__box {
width: 100%;
height: 70%;
padding: 10rpx 0;
margin: 0 30rpx;
border-radius: 60rpx 60rpx 60rpx 0;
font-size: 24rpx;
background-color: rgba(255,255,255,0.1);
}
&__icon {
padding-right: 10rpx;
margin-left: 20rpx;
font-size: 30rpx;
}
&__text {
}
}
}
/* 自定义导航栏内容 end */
.screen-shadow{
box-shadow: 0rpx 0rpx 80rpx 0rpx rgba(0, 0, 0, 0.07);
border-radius: 20rpx;
}
/* 图标容器15 start */
.icon15 {
&__item {
width: 30%;
background-color: #FFFFFF;
border-radius: 10rpx;
padding: 30rpx;
margin: 20rpx 10rpx;
transform: scale(1);
transition: transform 0.3s linear;
transform-origin: center center;
&--icon {
width: 100rpx;
height: 100rpx;
font-size: 60rpx;
border-radius: 50%;
margin-bottom: 18rpx;
position: relative;
z-index: 1;
&::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%;
}
}
}
}
/* 图标容器7 start */
.icon7 {
&__item {
width: 30%;
background-color: #FFFFFF;
border-radius: 10rpx;
padding: 10rpx;
margin: 20rpx 10rpx;
transform: scale(1);
transition: transform 0.3s linear;
transform-origin: center center;
&--icon {
width: 100rpx;
height: 100rpx;
font-size: 60rpx;
border-radius: 0;
margin-bottom: 18rpx;
position: relative;
z-index: 1;
}
}
}
/* 文章内容 start*/
.tn-blogger-content {
&__wrap {
box-shadow: 0rpx 0rpx 80rpx 0rpx rgba(0, 0, 0, 0.09);
border-radius: 20rpx;
margin: 30rpx;
}
&__info {
&__btn {
margin-right: -12rpx;
opacity: 0.5;
}
}
&__label {
&__item {
line-height: 45rpx;
padding: 0 20rpx;
margin: 5rpx 18rpx 0 0;
&--prefix {
color: #00FFC8;
padding-right: 10rpx;
}
}
&__desc {
line-height: 55rpx;
}
}
&__main-image {
border-radius: 16rpx 16rpx 0 0;
&--1 {
max-width: 690rpx;
min-width: 690rpx;
max-height: 400rpx;
min-height: 400rpx;
}
&--2 {
max-width: 260rpx;
max-height: 260rpx;
}
&--3 {
height: 212rpx;
width: 100%;
}
}
&__count-icon {
font-size: 40rpx;
padding-right: 5rpx;
}
}
.image-screen{
padding: 180rpx 0rpx;
font-size: 40rpx;
font-weight: 300;
position: relative;
}
.image-pic{
background-size: cover;
background-repeat:no-repeat;
// background-attachment:fixed;
background-position:top;
border-radius: 10rpx;
}
/* 文章内容 end*/
/* 移动背景部分 start*/
.bg-contaniner {
position: fixed;
top: -0rpx;
left: -300rpx;
--text-color: hsl(0 95% 60%);
--bg-color: hsl(0 0% 100%);
--bg-size: 200px;
height: 100%;
display: grid;
place-items: center;
place-content: center;
overflow: hidden;
background-color: var(--bg-color);
z-index: -1;
}
.bg-contaniner::before {
--size: 150vmax;
content: "";
inline-size: var(--size);
block-size: var(--size);
background-image: url("https://tnuiimage.tnkjapp.com/animate/animate3.png");
background-size: var(--bg-size);
background-repeat: repeat;
transform: rotate(45deg);
opacity: 0.25;
animation: bg 6s linear infinite;
}
@media (prefers-reduced-motion: reduce) {
.bg-contaniner::before {
animation-duration: 0s;
}
}
@keyframes bg {
to {
background-position: 0 calc(var(--bg-size) * -1);
}
}
/* 移动背景部分 end*/
</style>
+534
View File
@@ -0,0 +1,534 @@
<template>
<view class="template-wallpaper" style="background-color: #343434;">
<!-- 顶部自定义导航 -->
<!-- <tn-nav-bar fixed alpha customBack>
<view slot="back" class='tn-custom-nav-bar__back'
@click="goBack">
<text class='icon tn-icon-left'></text>
<text class='icon tn-icon-home-capsule-fill'></text>
</view>
</tn-nav-bar> -->
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed :isBack="false" :bottomShadow="false" backgroundColor="#343434">
<view class="custom-nav tn-flex tn-flex-col-center tn-flex-row-left">
<!-- 返回按钮 -->
<view class="custom-nav__back">
<view class="logo-pic" style="background-image:url('https://tnuiimage.tnkjapp.com/logo/logo2.png')">
<view class="logo-image">
</view>
</view>
<!-- <view class="tn-icon-left"></view> -->
</view>
<!-- -->
<view class="custom-nav__search tn-flex tn-flex-col-center tn-flex-row-center ">
<view class="custom-nav__search__box tn-flex tn-flex-col-center tn-flex-row-center tn-color-white">
<text class="tn-text-bold tn-text-xxl">北北壁纸库</text>
</view>
</view>
</view>
</tn-nav-bar>
<!-- 页面内容-->
<view class="">
<view class="tn-margin" :style="{paddingTop: vuex_custom_bar_height + 'px'}">
<tn-swiper :list="banner" :height="350" :effect3d="false" mode="rect"></tn-swiper>
</view>
<!-- 方式12 start-->
<view class="tn-flex tn-margin-sm">
<view class="tn-flex-1 tn-padding-sm tn-margin-xs tn-radius">
<view class="tn-flex tn-flex-direction-column tn-flex-row-center tn-flex-col-center">
<view class="icon12__item--icon tn-flex tn-flex-row-center tn-flex-col-center tn-main-gradient-orange--light tn-color-orange">
<view class="tn-icon-moon-fill tn-three"></view>
</view>
<view class="tn-color-white tn-text-center">
<text class="tn-text-ellipsis">高清壁纸</text>
</view>
</view>
</view>
<view class="tn-flex-1 tn-padding-sm tn-margin-xs tn-radius">
<view class="tn-flex tn-flex-direction-column tn-flex-row-center tn-flex-col-center">
<view class="icon12__item--icon tn-flex tn-flex-row-center tn-flex-col-center tn-main-gradient-purple--light tn-color-purple">
<view class="tn-icon-light-fill tn-three"></view>
</view>
<view class="tn-color-white tn-text-center">
<text class="tn-text-ellipsis">热门排行</text>
</view>
</view>
</view>
<view class="tn-flex-1 tn-padding-sm tn-margin-xs tn-radius">
<view class="tn-flex tn-flex-direction-column tn-flex-row-center tn-flex-col-center">
<view class="icon12__item--icon tn-flex tn-flex-row-center tn-flex-col-center tn-main-gradient-indigo--light tn-color-indigo">
<view class="tn-icon-star-fill tn-three"></view>
</view>
<view class="tn-color-white tn-text-center">
<text class="tn-text-ellipsis">文艺可爱</text>
</view>
</view>
</view>
<view class="tn-flex-1 tn-padding-sm tn-margin-xs tn-radius">
<view class="tn-flex tn-flex-direction-column tn-flex-row-center tn-flex-col-center">
<view class="icon12__item--icon tn-flex tn-flex-row-center tn-flex-col-center tn-main-gradient-purplered--light tn-color-purplered">
<view class="tn-icon-like-fill tn-three"></view>
</view>
<view class="tn-color-white tn-text-center">
<text class="tn-text-ellipsis">精选壁纸</text>
</view>
</view>
</view>
</view>
<!-- 方式12 end-->
<!-- banner start-->
<view class="tn-flex tn-flex-wrap tn-margin-xs">
<view class=" " style="width: 100%;">
<view class="image-pic tn-margin-sm" style="background-image:url('https://tnuiimage.tnkjapp.com/shop/phonecase1.jpg')">
<view class="image-wallpaper">
</view>
</view>
</view>
</view>
<!-- banner end-->
<!-- 比例 start-->
<view class="tn-flex tn-flex-wrap tn-margin-xs">
<block v-for="(item, index) in pic" :key="index">
<view class=" " style="width: 50%;">
<view class="image-pic tn-margin-sm" :style="'background-image:url(' + item.image + ')'">
<view class="image-wallpaper">
</view>
</view>
</view>
</block>
</view>
<!-- 比例 end-->
<!-- 图文 -->
<view class="tn-flex tn-flex-direction-column tn-padding-bottom">
<block v-for="(item,index) in content" :key="index">
<view class="tn-blogger-content__wrap">
<view class="">
<image
class="tn-blogger-content__main-image tn-blogger-content__main-image--1 tn-margin-bottom tn-margin-top"
:src="item.mainImage"
mode="aspectFill"
></image>
</view>
<view class="tn-blogger-content__label tn-text-justify">
<text class="tn-blogger-content__label__desc tn-text-lg tn-text-bold tn-color-white">{{ item.desc }}</text>
</view>
<view class="tn-flex tn-flex-row-between tn-flex-col-center tn-margin-top-xs">
<view class="justify-content-item tn-flex tn-flex-col-center">
<view style="margin-right: 10rpx;margin-left: 0rpx;">
<view class="tn-color-gray">
<text class="tn-blogger-content__count-icon tn-icon-flower"></text>
<text class="tn-padding-right">{{ item.collectionCount }}</text>
<text class="tn-blogger-content__count-icon tn-icon-message"></text>
<text class="tn-padding-right">{{ item.commentCount }}</text>
<text class="tn-blogger-content__count-icon tn-icon-like"></text>
<text class="">{{ item.likeCount }}</text>
</view>
</view>
</view>
<view class="justify-content-item tn-text-center">
<view v-for="(label_item,label_index) in item.label" :key="label_index" class="tn-blogger-content__label__item tn-float-left tn-margin-right tn-bg-gray--light tn-round tn-text-sm tn-text-bold">
<text class="tn-blogger-content__label__item--prefix">#</text> {{ label_item }}
</view>
</view>
</view>
</view>
</block>
</view>
</view>
<!-- 回到首页悬浮按钮-->
<nav-index-button></nav-index-button>
</view>
</template>
<script>
import template_page_mixin from '@/libs/mixin/template_page_mixin.js'
import NavIndexButton from '@/libs/components/nav-index-button.vue'
export default {
name: 'TemplateWallpaper',
mixins: [template_page_mixin],
components: { NavIndexButton },
data(){
return {
banner: [{
image: 'https://tnuiimage.tnkjapp.com/shop/banner2.jpg'
}, {
image: 'https://tnuiimage.tnkjapp.com/shop/banner1.jpg'
}, {
image: 'https://tnuiimage.tnkjapp.com/shop/banner2.jpg'
}, {
image: 'https://tnuiimage.tnkjapp.com/shop/banner1.jpg'
}],
pic: [{
image: 'https://tnuiimage.tnkjapp.com/shop/prototype2.jpg'
}, {
image: 'https://tnuiimage.tnkjapp.com/shop/computer2.jpg'
},{
image: 'https://tnuiimage.tnkjapp.com/shop/pillow.jpg'
}, {
image: 'https://tnuiimage.tnkjapp.com/shop/pillow2.jpg'
}, {
image: 'https://tnuiimage.tnkjapp.com/shop/cup1.jpg'
}, {
image: 'https://tnuiimage.tnkjapp.com/shop/bag2.jpg'
}],
content: [
{
userAvatar: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg',
userName: '可我会像',
date: '2021年12月20日',
label: ['开源','创意'],
desc: '免费开源可商用组件',
mainImage: 'https://tnuiimage.tnkjapp.com/shop/prototype2.jpg',
viewUser: {
latestUserAvatar: [
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_2.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_3.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_4.jpeg'},
],
viewUserCount: 129
},
collectionCount: 999,
commentCount: 999,
likeCount: 999
},
{
userAvatar: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg',
userName: '可我会像',
date: '2021年12月20日',
label: ['开源','创意'],
desc: '免费开源可商用组件',
mainImage: 'https://tnuiimage.tnkjapp.com/shop/prototype1.jpg',
viewUser: {
latestUserAvatar: [
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_2.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_3.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_4.jpeg'},
],
viewUserCount: 129
},
collectionCount: 265,
commentCount: 22,
likeCount: 62
},
{
userAvatar: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg',
userName: '可我会像',
date: '2021年12月20日',
label: ['开源','创意'],
desc: '免费开源可商用组件',
mainImage: 'https://tnuiimage.tnkjapp.com/shop/computer2.jpg',
viewUser: {
latestUserAvatar: [
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_2.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_3.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_4.jpeg'},
],
viewUserCount: 129
},
collectionCount: 265,
commentCount: 22,
likeCount: 62
},
{
userAvatar: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg',
userName: '可我会像',
date: '2021年12月20日',
label: ['开源','创意'],
desc: '免费开源可商用组件',
mainImage: 'https://tnuiimage.tnkjapp.com/shop/phonecase1.jpg',
viewUser: {
latestUserAvatar: [
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_2.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_3.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_4.jpeg'},
],
viewUserCount: 129
},
collectionCount: 265,
commentCount: 22,
likeCount: 62
},
{
userAvatar: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg',
userName: '可我会像',
date: '2021年12月20日',
label: ['开源','创意'],
desc: '免费开源可商用组件',
mainImage: 'https://tnuiimage.tnkjapp.com/shop/phonecase2.jpg',
viewUser: {
latestUserAvatar: [
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_2.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_3.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_4.jpeg'},
],
viewUserCount: 129
},
collectionCount: 265,
commentCount: 22,
likeCount: 62
},
{
userAvatar: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg',
userName: '可我会像',
date: '2021年12月20日',
label: ['开源','创意'],
desc: '我们都是好孩子',
mainImage: 'https://tnuiimage.tnkjapp.com/shop/watch1.jpg',
viewUser: {
latestUserAvatar: [
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_2.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_3.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_4.jpeg'},
],
viewUserCount: 129
},
collectionCount: 265,
commentCount: 22,
likeCount: 62
},
{
userAvatar: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg',
userName: '可我会像',
date: '2021年12月20日',
label: ['开源','创意'],
desc: '免费开源可商用组件',
mainImage: 'https://tnuiimage.tnkjapp.com/shop/sticker.jpg',
viewUser: {
latestUserAvatar: [
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_2.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_3.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_4.jpeg'},
],
viewUserCount: 129
},
collectionCount: 265,
commentCount: 22,
likeCount: 62
},
{
userAvatar: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg',
userName: '可我会像',
date: '2021年12月20日',
label: ['开源','创意'],
desc: '免费开源可商用组件',
mainImage: 'https://tnuiimage.tnkjapp.com/shop/card.jpg',
viewUser: {
latestUserAvatar: [
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_1.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_2.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_3.jpeg'},
{src: 'https://tnuiimage.tnkjapp.com/blogger/avatar_4.jpeg'},
],
viewUserCount: 129
},
collectionCount: 265,
commentCount: 22,
likeCount: 62
}
]
}
},
methods: {
}
}
</script>
<style lang="scss" scoped>
@import '@/static/css/templatePage/custom_nav_bar.scss';
/* 自定义导航栏内容 start */
.custom-nav {
height: 100%;
&__back {
margin: auto 5rpx;
font-size: 40rpx;
margin-right: 10rpx;
margin-left: 30rpx;
flex-basis: 5%;
}
&__search {
flex-basis: 70%;
width: 100%;
height: 100%;
&__box {
width: 100%;
height: 70%;
padding: 10rpx 0;
margin: 0 30rpx;
}
&__icon {
padding-right: 10rpx;
margin-left: 20rpx;
font-size: 30rpx;
}
&__text {
color: #AAAAAA;
}
}
}
/* 自定义导航栏内容 end */
/*logo start */
.logo-image{
width: 65rpx;
height: 65rpx;
position: relative;
}
.logo-pic{
background-size: cover;
background-repeat:no-repeat;
// background-attachment:fixed;
background-position:top;
border-radius: 50%;
}
/* 图标容器12 start */
.tn-three{
position: absolute;
top: 50%;
right: 50%;
bottom: 50%;
left: 50%;
transform: translate(-38rpx, -16rpx) rotateX(30deg) rotateY(20deg) rotateZ(-30deg);
text-shadow: -1rpx 2rpx 0 #f0f0f0, -2rpx 4rpx 0 #f0f0f0, -10rpx 20rpx 30rpx rgba(0, 0, 0, 0.2);
}
.icon12 {
&__item {
width: 30%;
background-color: #FFFFFF;
border-radius: 10rpx;
padding: 30rpx;
margin: 20rpx 10rpx;
transform: scale(1);
transition: transform 0.3s linear;
transform-origin: center center;
&--icon {
width: 100rpx;
height: 100rpx;
font-size: 60rpx;
border-radius: 50%;
margin-bottom: 18rpx;
position: relative;
z-index: 1;
&::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://tnuiimage.tnkjapp.com/cool_bg_image/icon_bg.png);
}
}
}
}
/* 文章内容 start*/
.tn-blogger-content {
&__wrap {
margin: 30rpx;
}
&__info {
&__btn {
margin-right: -12rpx;
opacity: 0.5;
}
}
&__label {
&__item {
line-height: 45rpx;
padding: 0 20rpx;
margin: 5rpx 18rpx 0 0;
&--prefix {
color: #00FFC8;
padding-right: 10rpx;
}
}
&__desc {
line-height: 55rpx;
}
}
&__main-image {
border-radius: 16rpx;
&--1 {
max-width: 690rpx;
min-width: 690rpx;
max-height: 400rpx;
min-height: 400rpx;
}
&--2 {
max-width: 260rpx;
max-height: 260rpx;
}
&--3 {
height: 212rpx;
width: 100%;
}
}
&__count-icon {
font-size: 40rpx;
padding-right: 5rpx;
}
}
.image-wallpaper{
padding: 160rpx 0rpx;
font-size: 40rpx;
font-weight: 300;
position: relative;
}
.image-pic{
background-size: cover;
background-repeat:no-repeat;
// background-attachment:fixed;
background-position:top;
border-radius: 10rpx;
}
/* 文章内容 end*/
</style>
+238
View File
@@ -0,0 +1,238 @@
<template>
<view class="template-browser">
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed alpha customBack>
<view slot="back" class='tn-custom-nav-bar__back'
@click="goBack">
<text class='icon tn-icon-left'></text>
<text class='icon tn-icon-home-capsule-fill'></text>
</view>
</tn-nav-bar>
<swiper class="card-swiper" :indicator-dots="true" :circular="true" :autoplay="false" interval="10000"
duration="500" @change="cardSwiper" indicator-color="#666" indicator-active-color="#000"
style="margin-top: 300rpx;">
<swiper-item v-for="(item,index) in swiperList" :key="index" :class="cardCur==index?'cur swiper-item1--active':'swiper-item1'">
<view class="swiper-item image-banner" style="border-radius: 20rpx 20rpx 22rpx 22rpx;">
<image class="" :src="item.url" v-if="item.type=='image'" mode="aspectFill"></image>
</view>
</swiper-item>
</swiper>
<view class="tn-text-center tn-color-black">
测试未写完
</view>
<!-- 底部tabbar start-->
<view class="tabbar footerfixed">
<view class="action">
<view class="bar-icon">
<view class="tn-icon-home-smile tn-color-black">
</view>
</view>
<view class="tn-color-black">首页</view>
</view>
<view class="action">
<view class="bar-icon">
<view class="tn-icon-discover tn-color-gray--dark">
</view>
</view>
<view class="tn-color-gray--dark">圈子</view>
</view>
<view class="action">
<view class="bar-icon">
<view class="tn-icon-image-text tn-color-gray--dark">
</view>
</view>
<view class="tn-color-gray--dark">案例</view>
</view>
<view class="action">
<view class="bar-icon">
<view class="tn-icon-my tn-color-gray--dark">
<tn-badge :absolute="true">99+</tn-badge>
</view>
</view>
<view class="tn-color-gray--dark">我的</view>
</view>
</view>
</view>
</template>
<script>
import template_page_mixin from '@/libs/mixin/template_page_mixin.js'
export default {
name: 'TemplateBrowser',
mixins: [template_page_mixin],
data(){
return {
cardCur: 0,
swiperList: [{
id: 0,
type: 'image',
name: '总有你想不到的创意',
text: '海量分享',
url: 'https://tnuiimage.tnkjapp.com/swiper/fullbg4.jpg',
pngurl: 'https://tnuiimage.tnkjapp.com/swiper/c4d1.png'
}, {
id: 1,
type: 'image',
name: '寻找一起成长的小伙伴',
text: '愉快玩耍',
url: 'https://tnuiimage.tnkjapp.com/swiper/fullbg5.jpg',
pngurl: 'https://tnuiimage.tnkjapp.com/swiper/c4d4.png'
}, {
id: 2,
type: 'image',
name: '更多彩蛋等你探索',
text: '酷炫多彩',
url: 'https://tnuiimage.tnkjapp.com/swiper/fullbg4.jpg',
pngurl: 'https://tnuiimage.tnkjapp.com/swiper/c4d5.png'
}],
}
},
methods: {
// cardSwiper
cardSwiper(e) {
this.cardCur = e.detail.current
},
}
}
</script>
<style lang="scss" scoped>
@import '@/static/css/templatePage/custom_nav_bar.scss';
.template-browser{
margin-bottom: calc(110rpx + env(safe-area-inset-bottom) / 2);;
}
/* 轮播视觉差 start */
.card-swiper {
height: 500rpx !important;
}
.card-swiper swiper-item {
width: 250rpx !important;
left: 250rpx;
box-sizing: border-box;
padding: 100rpx 0rpx 100rpx 0rpx;
overflow: initial;
}
.card-swiper swiper-item .swiper-item {
width: 100%;
display: block;
height: 200rpx;
border-radius: 0rpx;
transform: translate(0rpx, 0rpx) scale(1.5);
transition: all 0.2s ease-in 0s;
overflow: hidden;
border: 5rpx solid red;
}
.card-swiper swiper-item.cur .swiper-item {
transform: translate(0rpx, 0rpx) scale(2);
transition: all 0.2s ease-in 0s;
border: 5rpx solid pink;
}
.image-banner{
display: flex;
align-items: center;
justify-content: center;
}
.image-banner image{
width: 100%;
}
/* 轮播指示点 start*/
.indication{
z-index: 9999;
width: 100%;
height: 36rpx;
position: absolute;
display:flex;
flex-direction:row;
align-items:center;
justify-content:center;
}
.spot{
background-color: #FFF;
opacity: 0.4;
width: 10rpx;
height: 10rpx;
border-radius: 20rpx;
margin: 0 8rpx !important;
left: -270rpx;
top: -180rpx;
position: relative;
}
.spot.active{
opacity: 1;
width: 30rpx;
background-color: #FFF;
}
.swiper-item1 {
z-index: -1;
&--active {
z-index: 10;
}
}
/* 底部tabbar start*/
.footerfixed{
position: fixed;
width: 100%;
bottom: 0;
z-index: 999;
background-color: #FFFFFF;
box-shadow: 0rpx 0rpx 30rpx 0rpx rgba(0, 0, 0, 0.07);
}
.tabbar {
display: flex;
align-items: center;
min-height: 110rpx;
justify-content: space-between;
padding: 0;
height: calc(110rpx + env(safe-area-inset-bottom) / 2);
padding-bottom: calc(env(safe-area-inset-bottom) / 2);
}
.tabbar .action {
font-size: 22rpx;
position: relative;
flex: 1;
text-align: center;
padding: 0;
display: block;
height: auto;
line-height: 1;
margin: 0;
overflow: initial;
}
.tabbar .action .bar-icon {
width: 100rpx;
position: relative;
display: block;
height: auto;
margin: 0 auto 10rpx;
text-align: center;
font-size: 42rpx;
}
.tabbar .action .bar-icon image {
width: 50rpx;
height: 50rpx;
display: inline-block;
}
</style>
+159
View File
@@ -0,0 +1,159 @@
<template>
<view class="template-fullpage">
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed alpha customBack>
<view slot="back" class='tn-custom-nav-bar__back'
@click="goBack">
<text class='icon tn-icon-left'></text>
<text class='icon tn-icon-home-capsule-fill'></text>
</view>
</tn-nav-bar>
<swiper class="card-swiper" :circular="true" vertical="true"
:autoplay="true" duration="500" interval="5000" @change="cardSwiper" >
<swiper-item v-for="(item,index) in swiperList" :key="index" :class="cardCur==index?'cur':''">
<view class="swiper-item image-banner">
<image :src="item.url" mode="aspectFill" v-if="item.type=='image'" style="height: 100vh;width: 100vw;"></image>
</view>
<view class="swiper-item-png image-banner">
<image :src="item.pngurl" mode="heightFix" v-if="item.type=='image'" style="height: 100vh;width: 100vw;"></image>
</view>
</swiper-item>
</swiper>
<view class="indication">
<block v-for="(item,index) in swiperList" :key="index">
<view class="spot" :class="cardCur==index?'active':''"></view>
</block>
</view>
</view>
</template>
<script>
import template_page_mixin from '@/libs/mixin/template_page_mixin.js'
export default {
name: 'TemplateFullpage',
mixins: [template_page_mixin],
data(){
return {
cardCur: 0,
swiperList: [{
id: 0,
type: 'image',
url: 'https://tnuiimage.tnkjapp.com/swiper/fullbg1.jpg',
pngurl: 'https://tnuiimage.tnkjapp.com/swiper/full1.png'
}, {
id: 1,
type: 'image',
url: 'https://tnuiimage.tnkjapp.com/swiper/fullbg2.jpg',
pngurl: 'https://tnuiimage.tnkjapp.com/swiper/full2.png'
}, {
id: 2,
type: 'image',
url: 'https://tnuiimage.tnkjapp.com/swiper/fullbg1.jpg',
pngurl: 'https://tnuiimage.tnkjapp.com/swiper/full3.png'
}, {
id: 3,
type: 'image',
url: 'https://tnuiimage.tnkjapp.com/swiper/fullbg2.jpg',
pngurl: 'https://tnuiimage.tnkjapp.com/swiper/full4.png'
}],
}
},
methods: {
// cardSwiper
cardSwiper(e) {
this.cardCur = e.detail.current
},
}
}
</script>
<style lang="scss" scoped>
@import '@/static/css/templatePage/custom_nav_bar.scss';
/* 全屏轮播 start*/
.card-swiper {
height: 100vh !important;
}
.card-swiper swiper-item {
width: 750rpx !important;
left: 0rpx;
box-sizing: border-box;
overflow: initial;
}
.card-swiper swiper-item .swiper-item {
width: 100%;
display: block;
height: 100vh;
border-radius: 0rpx;
transform: scale(1);
transition: all 0.2s ease-in 0s;
overflow: hidden;
}
.card-swiper swiper-item.cur .swiper-item {
transform: none;
transition: all 0.2s ease-in 0s;
}
.card-swiper swiper-item .swiper-item-png {
margin-top: -50vh;
width: 100%;
display: block;
border-radius: 0rpx;
transform: translate(1040rpx, 20rpx) scale(0.5, 0.5);
transition: all 0.6s ease 0s;
// overflow: hidden;
}
.card-swiper swiper-item.cur .swiper-item-png {
margin-top: -100vh;
width: 900rpx;
transform: translate(-80rpx, 0rpx) scale(1, 1);
transition: all 0.6s ease 0s;
}
.image-banner{
display: flex;
align-items: center;
justify-content: center;
}
.image-banner image{
width: 100%;
}
/* 轮播指示点 start*/
.indication{
z-index: 9999;
width: 100%;
height: 36rpx;
position: fixed;
// display:flex;
display: block;
flex-direction:row;
align-items:center;
justify-content:center;
}
.spot{
background-color: #000;
opacity: 0.3;
width: 10rpx;
height: 10rpx;
border-radius: 20rpx;
margin: 20rpx 0 !important;
left: 95vw;
top: -60vh;
position: relative;
}
.spot.active{
opacity: 0.6;
height: 30rpx;
background-color: #000;
}
</style>
+150
View File
@@ -0,0 +1,150 @@
<template>
<view class="template-plus">
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed alpha customBack>
<view slot="back" class='tn-custom-nav-bar__back'
@click="goBack">
<text class='icon tn-icon-left'></text>
<text class='icon tn-icon-home-capsule-fill'></text>
</view>
</tn-nav-bar>
<view class="tn-text-center tn-margin-xl tn-text-lg plus-box" :style="{paddingTop: vuex_custom_bar_height + 'px'}">
<view class="plus-text">
<view class="tn-text-bold">图鸟UI小程序免费开源可商用</view>
<view class="tn-margin-bottom-xl">会员有更多福利鸭</view>
</view>
<view class="plus-text">
<view class="tn-text-bold">图鸟UI Plus会员初步定价</view>
<view class="tn-text-bold">
<text class="tn-text-xl-xxl">699 / </text>
<text class="tn-text-xxl tn-padding-left-sm">终身</text>
</view>
<view class="tn-margin-bottom-xl">大约等于两个前端页面价格</view>
</view>
<view class="plus-text">
<view class="tn-text-bold">或许会员人数达到100+</view>
<view class="tn-margin-bottom-xl">当然接项目恰饭最实在</view>
</view>
<view class="plus-text">
<view class="tn-text-bold">不断更新酷炫组件以及页面模板</view>
<view class="tn-margin-bottom-xl">偶尔恰饭时常更新啦</view>
</view>
<view class="plus-text">
<view class="tn-text-bold">请勿转售转售是会慢慢追究法律责任的</view>
<view class="tn-margin-bottom-xl">毕竟开发圈子就那么小</view>
</view>
<view class="plus-text">
<view class="tn-text-bold">使用手册 + 图片素材 + 意见反馈 + Bug提交</view>
<view class="tn-margin-bottom-xl">https://www.yuque.com/tuniao</view>
</view>
<view class="plus-text">
<view class="tn-text-bold">如需拓展人脉可进群与群友合作</view>
<view class="tn-margin-bottom-xl">群内禁止黄赌毒+吵架我秒怂</view>
</view>
<view class="plus-text">
<view class="tn-text-bold">项目初衷是拓展业务寻求商务合作</view>
<view class=""> 图鸟北北微信号tnkewo </view>
<view class="">如需入群可备注进微信群</view>
<view class="">如需合作可备注商业合作</view>
<view class="tn-margin-bottom-xl">如需聊天可备注咨询聊天</view>
</view>
<view class="plus-text">
<view class="tn-text-bold">期待你的5星好评</view>
<view class="tn-margin-bottom-xl">尽管图鸟UI不是我最完美的作品</view>
</view>
<view class="plus-text">
<view class="tn-text-bold">待补充....</view>
</view>
<view class="plus-text">
<view class="tn-text-bold">待补充....</view>
</view>
<view class="plus-text">
<view class="tn-text-bold">待补充....</view>
</view>
<view class="plus-text">
<view class="tn-text-bold">待补充....</view>
</view>
<view class="plus-text">
<view class="tn-text-bold">待补充....</view>
</view>
<view class="plus-text">
<view class="tn-text-bold">待补充....</view>
</view>
<view class="plus-text">
<view class="tn-text-bold">待补充....</view>
</view>
<view class="plus-text">
<view class="tn-text-bold">待补充....</view>
</view>
<view class="plus-text">
<view class="tn-text-bold">待补充....</view>
</view>
</view>
<view class="tn-padding-bottom"></view>
</view>
</template>
<script>
import template_page_mixin from '@/libs/mixin/template_page_mixin.js'
export default {
name: 'TemplatePlus',
mixins: [template_page_mixin],
data(){
return {}
},
methods: {
}
}
</script>
<style lang="scss" scoped>
@import '@/static/css/templatePage/custom_nav_bar.scss';
/* List */
.plus-box {
counter-reset: index;
padding: 0;
max-width: 100vw;
background-image: linear-gradient(to top, #FFA726 , #2DE8BD);
background-attachment: fixed;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
/* List element */
.plus-text {
counter-increment: index;
display: initial;
align-items: center;
padding: 12px 0;
box-sizing: border-box;
}
/* Element counter */
.plus-text::before {
content: counters(index, ".", decimal-leading-zero);
font-size: 1.5rem;
font-weight: bold;
font-feature-settings: "tnum";
font-variant-numeric: tabular-nums;
align-self: flex-start;
}
</style>
+414
View File
@@ -0,0 +1,414 @@
<template>
<view class="template-login">
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed alpha customBack>
<view slot="back" class='tn-custom-nav-bar__back'
@click="goBack">
<text class='icon tn-icon-left'></text>
<text class='icon tn-icon-home-capsule-fill'></text>
</view>
</tn-nav-bar>
<view class="login">
<!-- 顶部背景图片-->
<view class="login__bg login__bg--top">
<image class="bg" src="https://tnuiimage.tnkjapp.com/login/1/login_top2.jpg" mode="widthFix"></image>
</view>
<view class="login__bg login__bg--top">
<image class="rocket rocket-sussuspension" src="https://tnuiimage.tnkjapp.com/login/1/login_top3.png" mode="widthFix"></image>
</view>
<view class="login__wrapper">
<!-- 登录/注册切换 -->
<view class="login__mode tn-flex tn-flex-direction-row tn-flex-nowrap tn-flex-col-center tn-flex-row-center">
<view class="login__mode__item tn-flex-1" :class="[{'login__mode__item--active': currentModeIndex === 0}]" @tap.stop="modeSwitch(0)">
登录
</view>
<view class="login__mode__item tn-flex-1" :class="[{'login__mode__item--active': currentModeIndex === 1}]" @tap.stop="modeSwitch(1)">
注册
</view>
<!-- 滑块-->
<view class="login__mode__slider tn-cool-bg-color-15--reverse" :style="[modeSliderStyle]"></view>
</view>
<!-- 输入框内容-->
<view class="login__info tn-flex tn-flex-direction-column tn-flex-col-center tn-flex-row-center">
<!-- 登录 -->
<block v-if="currentModeIndex === 0">
<view class="login__info__item__input tn-flex tn-flex-direction-row tn-flex-nowrap tn-flex-col-center tn-flex-row-left">
<view class="login__info__item__input__left-icon">
<view class="tn-icon-phone"></view>
</view>
<view class="login__info__item__input__content">
<input maxlength="20" placeholder-class="input-placeholder" placeholder="请输入登录手机号码" />
</view>
</view>
<view class="login__info__item__input tn-flex tn-flex-direction-row tn-flex-nowrap tn-flex-col-center tn-flex-row-left">
<view class="login__info__item__input__left-icon">
<view class="tn-icon-lock"></view>
</view>
<view class="login__info__item__input__content">
<input :password="!showPassword" placeholder-class="input-placeholder" placeholder="请输入登录密码" />
</view>
<view class="login__info__item__input__right-icon" @click="showPassword = !showPassword">
<view :class="[showPassword ? 'tn-icon-eye' : 'tn-icon-eye-hide']"></view>
</view>
</view>
</block>
<!-- 注册 -->
<block v-if="currentModeIndex === 1">
<view class="login__info__item__input tn-flex tn-flex-direction-row tn-flex-nowrap tn-flex-col-center tn-flex-row-left">
<view class="login__info__item__input__left-icon">
<view class="tn-icon-phone"></view>
</view>
<view class="login__info__item__input__content">
<input maxlength="20" placeholder-class="input-placeholder" placeholder="请输入注册手机号码" />
</view>
</view>
<view class="login__info__item__input tn-flex tn-flex-direction-row tn-flex-nowrap tn-flex-col-center tn-flex-row-left">
<view class="login__info__item__input__left-icon">
<view class="tn-icon-code"></view>
</view>
<view class="login__info__item__input__content login__info__item__input__content--verify-code">
<input placeholder-class="input-placeholder" placeholder="请输入验证码" />
</view>
<view class="login__info__item__input__right-verify-code" @tap.stop="getCode">
<tn-button size="sm" padding="5rpx 10rpx" width="100%" shape="round">{{ tips }}</tn-button>
</view>
</view>
<view class="login__info__item__input tn-flex tn-flex-direction-row tn-flex-nowrap tn-flex-col-center tn-flex-row-left">
<view class="login__info__item__input__left-icon">
<view class="tn-icon-lock"></view>
</view>
<view class="login__info__item__input__content">
<input :password="!showPassword" placeholder-class="input-placeholder" placeholder="请输入登录密码" />
</view>
<view class="login__info__item__input__right-icon" @click="showPassword = !showPassword">
<view :class="[showPassword ? 'tn-icon-eye' : 'tn-icon-eye-hide']"></view>
</view>
</view>
</block>
<view class="login__info__item__button tn-cool-bg-color-7--reverse" hover-class="tn-hover" :hover-stay-time="150">{{ currentModeIndex === 0 ? '登录' : '注册'}}</view>
<view v-if="currentModeIndex === 0" class="login__info__item__tips">忘记密码?</view>
</view>
<!-- 其他登录方式 -->
<view class="login__way tn-flex tn-flex-col-center tn-flex-row-center">
<view class="tn-padding-sm tn-margin-xs">
<view class="login__way__item--icon tn-flex tn-flex-row-center tn-flex-col-center tn-shadow-blur tn-bg-green tn-color-white">
<view class="tn-icon-wechat-fill"></view>
</view>
</view>
<view class="tn-padding-sm tn-margin-xs">
<view class="login__way__item--icon tn-flex tn-flex-row-center tn-flex-col-center tn-shadow-blur tn-bg-red tn-color-white">
<view class="tn-icon-discover-fill"></view>
</view>
</view>
<view class="tn-padding-sm tn-margin-xs">
<view class="login__way__item--icon tn-flex tn-flex-row-center tn-flex-col-center tn-shadow-blur tn-bg-blue tn-color-white">
<view class="tn-icon-gloves-fill"></view>
</view>
</view>
</view>
</view>
<!-- 底部背景图片-->
<view class="login__bg login__bg--bottom">
<image src="https://tnuiimage.tnkjapp.com/login/1/login_bottom_bg.jpg" mode="widthFix"></image>
</view>
</view>
<!-- 验证码倒计时 -->
<tn-verification-code
ref="code"
uniqueKey="login-demo-1"
:seconds="60"
@change="codeChange">
</tn-verification-code>
</view>
</template>
<script>
import template_page_mixin from '@/libs/mixin/template_page_mixin.js'
export default {
name: 'login-demo-1',
mixins: [template_page_mixin],
data() {
return {
// 当前选中的模式
currentModeIndex: 0,
// 模式选中滑块
modeSliderStyle: {
left: 0
},
// 是否显示密码
showPassword: false,
// 倒计时提示文字
tips: '获取验证码'
}
},
watch: {
currentModeIndex(value) {
const sliderWidth = uni.upx2px(476 / 2)
this.modeSliderStyle.left = `${sliderWidth * value}px`
}
},
methods: {
// 切换模式
modeSwitch(index) {
this.currentModeIndex = index
this.showPassword = false
},
// 获取验证码
getCode() {
if (this.$refs.code.canGetCode) {
this.$t.messageUtils.loading('正在获取验证码')
setTimeout(() => {
this.$t.messageUtils.closeLoading()
this.$t.messageUtils.toast('验证码已经发送')
// 通知组件开始计时
this.$refs.code.start()
}, 2000)
} else {
this.$t.messageUtils.toast(this.$refs.code.secNum + '秒后再重试')
}
},
// 获取验证码倒计时被修改
codeChange(event) {
this.tips = event
}
}
}
</script>
<style lang="scss" scoped>
@import '@/static/css/templatePage/custom_nav_bar.scss';
/* 悬浮 */
.rocket-sussuspension{
animation: suspension 3s ease-in-out infinite;
}
@keyframes suspension {
0%, 100% {
transform: translate(0 , 0);
}
50% {
transform: translate(-0.8rem , 1rem);
}
}
.login {
position: relative;
height: 100%;
z-index: 1;
/* 背景图片 start */
&__bg {
z-index: -1;
position: fixed;
&--top {
top: 0;
left: 0;
right: 0;
width: 100%;
.bg {
width: 750rpx;
will-change: transform;
}
.rocket {
margin: 50rpx 28%;
width: 400rpx;
will-change: transform;
}
}
&--bottom {
bottom: -10rpx;
left: 0;
right: 0;
width: 100%;
// height: 144px;
margin-bottom: env(safe-area-inset-bottom);
image {
width: 750rpx;
will-change: transform;
}
}
}
/* 背景图片 end */
/* 内容 start */
&__wrapper {
margin-top: 403rpx;
width: 100%;
}
/* 切换 start */
&__mode {
position: relative;
margin: 0 auto;
width: 476rpx;
height: 77rpx;
background-color: #FFFFFF;
box-shadow: 0rpx 10rpx 50rpx 0rpx rgba(0, 3, 72, 0.1);
border-radius: 39rpx;
&__item {
height: 77rpx;
width: 100%;
line-height: 77rpx;
text-align: center;
font-size: 31rpx;
color: #908f8f;
letter-spacing: 1em;
text-indent: 1em;
z-index: 2;
transition: all 0.4s;
&--active {
font-weight: bold;
color: #FFFFFF;
}
}
&__slider {
position: absolute;
height: inherit;
width: calc(476rpx / 2);
border-radius: inherit;
box-shadow: 0rpx 18rpx 72rpx 18rpx rgba(0, 195, 255, 0.1);
z-index: 1;
transition: all 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55);
}
}
/* 切换 end */
/* 登录注册信息 start */
&__info {
margin: 0 30rpx;
margin-top: 105rpx;
padding: 30rpx 51rpx;
padding-bottom: 0;
border-radius: 20rpx;
background-color: #ffff;
box-shadow: 0rpx 10rpx 50rpx 0rpx rgba(0, 3, 72, 0.1);
&__item {
&__input {
margin-top: 59rpx;
width: 100%;
height: 77rpx;
border: 1rpx solid #E6E6E6;
border-radius: 39rpx;
&__left-icon {
width: 10%;
font-size: 44rpx;
margin-left: 20rpx;
color: #AAAAAA;
}
&__content {
width: 80%;
padding-left: 10rpx;
&--verify-code {
width: 56%;
}
input {
font-size: 24rpx;
// letter-spacing: 0.1em;
}
}
&__right-icon {
width: 10%;
font-size: 44rpx;
margin-right: 20rpx;
color: #AAAAAA;
}
&__right-verify-code {
width: 34%;
margin-right: 20rpx;
}
}
&__button {
margin-top: 75rpx;
margin-bottom: 39rpx;
width: 100%;
height: 77rpx;
text-align: center;
font-size: 31rpx;
font-weight: bold;
line-height: 77rpx;
letter-spacing: 1em;
text-indent: 1em;
border-radius: 39rpx;
box-shadow: 1rpx 10rpx 24rpx 0rpx rgba(60, 129, 254, 0.35);
}
&__tips {
margin: 30rpx 0;
color: #AAAAAA;
}
}
}
/* 登录注册信息 end */
/* 登录方式切换 start */
&__way {
margin: 0 auto;
margin-top: 110rpx;
&__item {
&--icon {
width: 77rpx;
height: 77rpx;
font-size: 50rpx;
border-radius: 100rpx;
margin-bottom: 18rpx;
position: relative;
z-index: 1;
&::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://tnuiimage.tnkjapp.com/cool_bg_image/icon_bg5.png);
}
}
}
}
/* 登录方式切换 end */
/* 内容 end */
}
/deep/.input-placeholder {
font-size: 24rpx;
color: #E6E6E6;
}
</style>
+495
View File
@@ -0,0 +1,495 @@
<template>
<view class="template-login2" >
<!-- 顶部自定义导航 -->
<tn-nav-bar fixed alpha customBack>
<view slot="back" class='tn-custom-nav-bar__back'
@click="goBack">
<text class='icon tn-icon-left'></text>
<text class='icon tn-icon-home-capsule-fill'></text>
</view>
</tn-nav-bar>
<canvas canvas-id="star_canvas" class="mycanvas" :style="'width:' + screenWidth + 'px;height:' + screenHeight + 'px;'"></canvas>
<view class="login">
<!-- 顶部背景图片-->
<!-- <view class="login__bg login__bg--top">
<image class="bg" src="https://tnuiimage.tnkjapp.com/login/1/login_top2.jpg" mode="widthFix"></image>
</view>
<view class="login__bg login__bg--top">
<image class="rocket rocket-sussuspension" src="https://tnuiimage.tnkjapp.com/login/1/login_top3.png" mode="widthFix"></image>
</view> -->
<view class="login__wrapper">
<!-- 登录/注册切换 -->
<view class="login__mode tn-flex tn-flex-direction-row tn-flex-nowrap tn-flex-col-center tn-flex-row-center">
<view class="login__mode__item tn-flex-1" :class="[{'login__mode__item--active': currentModeIndex === 0}]" @tap.stop="modeSwitch(0)">
登录
</view>
<view class="login__mode__item tn-flex-1" :class="[{'login__mode__item--active': currentModeIndex === 1}]" @tap.stop="modeSwitch(1)">
注册
</view>
<!-- 滑块-->
<view class="login__mode__slider tn-cool-bg-color-15--reverse" :style="[modeSliderStyle]"></view>
</view>
<!-- 输入框内容-->
<view class="login__info tn-flex tn-flex-direction-column tn-flex-col-center tn-flex-row-center">
<!-- 登录 -->
<block v-if="currentModeIndex === 0">
<view class="login__info__item__input tn-flex tn-flex-direction-row tn-flex-nowrap tn-flex-col-center tn-flex-row-left">
<view class="login__info__item__input__left-icon">
<view class="tn-icon-phone"></view>
</view>
<view class="login__info__item__input__content">
<input maxlength="20" placeholder-class="input-placeholder" placeholder="请输入登录手机号码" />
</view>
</view>
<view class="login__info__item__input tn-flex tn-flex-direction-row tn-flex-nowrap tn-flex-col-center tn-flex-row-left">
<view class="login__info__item__input__left-icon">
<view class="tn-icon-lock"></view>
</view>
<view class="login__info__item__input__content">
<input :password="!showPassword" placeholder-class="input-placeholder" placeholder="请输入登录密码" />
</view>
<view class="login__info__item__input__right-icon" @click="showPassword = !showPassword">
<view :class="[showPassword ? 'tn-icon-eye' : 'tn-icon-eye-hide']"></view>
</view>
</view>
</block>
<!-- 注册 -->
<block v-if="currentModeIndex === 1">
<view class="login__info__item__input tn-flex tn-flex-direction-row tn-flex-nowrap tn-flex-col-center tn-flex-row-left">
<view class="login__info__item__input__left-icon">
<view class="tn-icon-phone"></view>
</view>
<view class="login__info__item__input__content">
<input maxlength="20" placeholder-class="input-placeholder" placeholder="请输入注册手机号码" />
</view>
</view>
<view class="login__info__item__input tn-flex tn-flex-direction-row tn-flex-nowrap tn-flex-col-center tn-flex-row-left">
<view class="login__info__item__input__left-icon">
<view class="tn-icon-code"></view>
</view>
<view class="login__info__item__input__content login__info__item__input__content--verify-code">
<input placeholder-class="input-placeholder" placeholder="请输入验证码" />
</view>
<view class="login__info__item__input__right-verify-code" @tap.stop="getCode">
<tn-button size="sm" padding="5rpx 10rpx" width="100%" shape="round">{{ tips }}</tn-button>
</view>
</view>
<view class="login__info__item__input tn-flex tn-flex-direction-row tn-flex-nowrap tn-flex-col-center tn-flex-row-left">
<view class="login__info__item__input__left-icon">
<view class="tn-icon-lock"></view>
</view>
<view class="login__info__item__input__content">
<input :password="!showPassword" placeholder-class="input-placeholder" placeholder="请输入登录密码" />
</view>
<view class="login__info__item__input__right-icon" @click="showPassword = !showPassword">
<view :class="[showPassword ? 'tn-icon-eye' : 'tn-icon-eye-hide']"></view>
</view>
</view>
</block>
<view class="login__info__item__button tn-cool-bg-color-7--reverse" hover-class="tn-hover" :hover-stay-time="150">{{ currentModeIndex === 0 ? '登录' : '注册'}}</view>
<view v-if="currentModeIndex === 0" class="login__info__item__tips">忘记密码?</view>
</view>
<!-- 其他登录方式 -->
<view class="login__way tn-flex tn-flex-col-center tn-flex-row-center">
<view class="tn-padding-sm tn-margin-xs">
<view class="login__way__item--icon tn-flex tn-flex-row-center tn-flex-col-center tn-shadow-blur tn-bg-green tn-color-white">
<view class="tn-icon-wechat-fill"></view>
</view>
</view>
<view class="tn-padding-sm tn-margin-xs">
<view class="login__way__item--icon tn-flex tn-flex-row-center tn-flex-col-center tn-shadow-blur tn-bg-red tn-color-white">
<view class="tn-icon-discover-fill"></view>
</view>
</view>
<view class="tn-padding-sm tn-margin-xs">
<view class="login__way__item--icon tn-flex tn-flex-row-center tn-flex-col-center tn-shadow-blur tn-bg-cyan tn-color-white">
<view class="tn-icon-gloves-fill"></view>
</view>
</view>
</view>
</view>
<!-- 底部背景图片-->
<!-- <view class="login__bg login__bg--bottom">
<image src="https://tnuiimage.tnkjapp.com/login/1/login_bottom_bg.jpg" mode="widthFix"></image>
</view> -->
</view>
<!-- 验证码倒计时 -->
<tn-verification-code
ref="code"
uniqueKey="login-demo-1"
:seconds="60"
@change="codeChange">
</tn-verification-code>
</view>
</template>
<script>
import template_page_mixin from '@/libs/mixin/template_page_mixin.js'
const Point = class {
constructor(x, y) {
this.x = x
this.y = y
this.r = 1 + Math.random() * 2
this.sx = Math.random() * 2 - 1
this.sy = Math.random() * 2 - 1
}
draw(ctx) {
ctx.beginPath()
ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI)
ctx.closePath()
ctx.fillStyle = '#fff'
ctx.fill()
}
move(w, h) {
this.x += this.sx
this.y += this.sy
if (this.x > w || this.x < 0) this.sx = -this.sx
if (this.y > h || this.y < 0) this.sy = -this.sy
}
drawLine(ctx, p) {
const dx = this.x - p.x
const dy = this.y - p.y
const d = Math.sqrt(dx * dx + dy * dy)
if (d < 100) {
var alpha = (100 - d) / 300 * 1
ctx.beginPath()
ctx.moveTo(this.x, this.y)
ctx.lineTo(p.x, p.y)
ctx.closePath()
ctx.strokeStyle = 'rgba(255, 255, 255, ' + alpha + ')'
ctx.strokeWidth = 1
ctx.stroke()
}
}
}
const sysinfo = uni.getSystemInfoSync()
const w = 400
const h = 1000
export default {
name: 'login-demo-2',
mixins: [template_page_mixin],
data() {
return {
ctx: null,
screenWidth: sysinfo.screenWidth,
screenHeight: sysinfo.screenHeight,
timer: null,
points: [],
// 当前选中的模式
currentModeIndex: 0,
// 模式选中滑块
modeSliderStyle: {
left: 0
},
// 是否显示密码
showPassword: false,
// 倒计时提示文字
tips: '获取验证码'
}
},
onLoad(options) {
this.from = options.from || ''
for (let i = 0; i < 80; i++) {
this.points.push(new Point(Math.random() * w, Math.random() * h))
}
this.ctx = uni.createCanvasContext('star_canvas')
// console.log(points)
this.gameloop() //进行
// this.ctx.setFillStyle('red')
// this.ctx.fillRect(200, 300, 50, 50)
// this.ctx.draw()
},
onUnload() {
clearTimeout(this.timer)
},
watch: {
currentModeIndex(value) {
const sliderWidth = uni.upx2px(476 / 2)
this.modeSliderStyle.left = `${sliderWidth * value}px`
}
},
methods: {
/**粒子进行*/
gameloop() {
this.timer = setTimeout(this.gameloop, 100);
// console.log('gameloop')
this.paint();
},
/**清空画布*/
paint() {
this.ctx.clearRect(0, 0, w, h)
for (var i = 0; i < this.points.length; i++) {
this.points[i].move(w, h)
this.points[i].draw(this.ctx)
for (var j = i + 1; j < this.points.length; j++) {
this.points[i].drawLine(this.ctx, this.points[j])
}
}
this.ctx.draw();
},
// 切换模式
modeSwitch(index) {
this.currentModeIndex = index
this.showPassword = false
},
// 获取验证码
getCode() {
if (this.$refs.code.canGetCode) {
this.$t.messageUtils.loading('正在获取验证码')
setTimeout(() => {
this.$t.messageUtils.closeLoading()
this.$t.messageUtils.toast('验证码已经发送')
// 通知组件开始计时
this.$refs.code.start()
}, 2000)
} else {
this.$t.messageUtils.toast(this.$refs.code.secNum + '秒后再重试')
}
},
// 获取验证码倒计时被修改
codeChange(event) {
this.tips = event
}
}
}
</script>
<style lang="scss" scoped>
@import '@/static/css/templatePage/custom_nav_bar.scss';
/* 粒子背景 start*/
.template-login2 {
background: linear-gradient(90deg, #892FE8, #3D7EFF);
min-height: 100vh
}
// .template-login2:before {
// content: "";
// position: absolute;
// top: 0;
// left: 0;
// bottom: 0;
// right: 0;
// -webkit-mask-image: -webkit-gradient(linear, left top, left bottom, from(transparent), to(black));
// -webkit-mask-image: linear-gradient(to bottom, transparent, black);
// mask-image: -webkit-gradient(linear, left top, left bottom, from(transparent), to(black));
// mask-image: linear-gradient(to bottom, transparent, black);
// background: -webkit-gradient(linear, left top, right top, from(#E72F8C), to(#892FE8));
// background: linear-gradient(90deg, #E72F8C, #892FE8);
// }
.mycanvas {
position: absolute;
background-size: cover;
width: 100vw;
height: 100vh;
justify-content: center;
flex-direction: column;
color: #fff;
}
.login {
position: relative;
height: 100%;
z-index: 1;
/* 内容 start */
&__wrapper {
padding-top: 400rpx;
width: 100%;
}
/* 切换 start */
&__mode {
position: relative;
margin: 0 auto;
width: 476rpx;
height: 77rpx;
background-color: rgba(255,255,255,0.2);
backdrop-filter: blur(6rpx);
-webkit-backdrop-filter: blur(6rpx);
box-shadow: 0rpx 10rpx 50rpx 0rpx rgba(0, 3, 72, 0.1);
border-radius: 39rpx;
&__item {
height: 77rpx;
width: 100%;
line-height: 77rpx;
text-align: center;
font-size: 31rpx;
color: #FFFFFF;
letter-spacing: 1em;
text-indent: 1em;
z-index: 2;
transition: all 0.4s;
&--active {
font-weight: bold;
color: #FFFFFF;
}
}
&__slider {
position: absolute;
height: inherit;
width: calc(476rpx / 2);
border-radius: inherit;
box-shadow: 0rpx 18rpx 72rpx 18rpx rgba(0, 195, 255, 0.1);
z-index: 1;
transition: all 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55);
}
}
/* 切换 end */
/* 登录注册信息 start */
&__info {
margin: 0 50rpx;
margin-top: 105rpx;
padding: 30rpx 51rpx;
padding-bottom: 0;
border-radius: 20rpx;
background-color: rgba(255,255,255,0.2);
backdrop-filter: blur(6rpx);
-webkit-backdrop-filter: blur(6rpx);
border: 2rpx solid rgba(255, 255, 255, 0.1);
box-shadow: 0rpx 10rpx 50rpx 0rpx rgba(0, 3, 72, 0.1);
&__item {
&__input {
margin-top: 59rpx;
width: 100%;
height: 77rpx;
border: 1rpx solid #FFFFFF;
border-radius: 39rpx;
&__left-icon {
width: 10%;
font-size: 44rpx;
margin-left: 20rpx;
color: #FFFFFF;
}
&__content {
width: 80%;
padding-left: 10rpx;
&--verify-code {
width: 56%;
}
input {
font-size: 24rpx;
color: #FFFFFF;
// letter-spacing: 0.1em;
}
}
&__right-icon {
width: 10%;
font-size: 44rpx;
margin-right: 20rpx;
color: #FFFFFF;
}
&__right-verify-code {
width: 34%;
margin-right: 20rpx;
}
}
&__button {
margin-top: 75rpx;
margin-bottom: 39rpx;
width: 100%;
height: 77rpx;
text-align: center;
font-size: 31rpx;
font-weight: bold;
line-height: 77rpx;
letter-spacing: 1em;
text-indent: 1em;
border-radius: 100rpx;
color: #FFFFFF;
background-color: rgba(255,255,255,0.2);
// border: 2rpx solid #FFFFFF;
}
&__tips {
margin: 30rpx 0;
color: #FFFFFF;
}
}
}
/* 登录注册信息 end */
/* 登录方式切换 start */
&__way {
margin: 0 auto;
margin-top: 110rpx;
&__item {
&--icon {
width: 77rpx;
height: 77rpx;
font-size: 50rpx;
border-radius: 100rpx;
margin-bottom: 18rpx;
position: relative;
z-index: 1;
&::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://tnuiimage.tnkjapp.com/cool_bg_image/icon_bg5.png);
}
}
}
}
/* 登录方式切换 end */
/* 内容 end */
}
/deep/.input-placeholder {
font-size: 24rpx;
color: #E6E6E6;
}
</style>
+4
View File
@@ -0,0 +1,4 @@
TuniaoUi for uniApp v1.0.0 | by 图鸟 2021-09-01
仅供开发,如作它用所承受的法律责任一概与作者无关
*使用TuniaoUi开发扩展与插件时,请注明基于tuniao字眼
@@ -0,0 +1,202 @@
<template>
<view v-if="value" class="tn-action-sheet-class tn-action-sheet">
<tn-popup
v-model="value"
mode="bottom"
length="auto"
:popup="false"
:borderRadius="borderRadius"
:maskCloseable="maskCloseable"
:safeAreaInsetBottom="safeAreaInsetBottom"
:zIndex="elZIndex"
@close="close"
>
<!-- 提示信息 -->
<view
v-if="tips.text"
class="tn-action-sheet__tips tn-border-solid-bottom"
:style="[tipsStyle]"
>
{{tips.text}}
</view>
<!-- 按钮列表 -->
<block v-for="(item, index) in list" :key="index">
<view
class="tn-action-sheet__item tn-text-ellipsis"
:class="[ index < list.length - 1 ? 'tn-border-solid-bottom' : '']"
:style="[itemStyle(index)]"
hover-class="tn-hover-class"
:hover-stay-time="150"
@tap="itemClick(index)"
@touchmove.stop.prevent
>
<text>{{item.text}}</text>
<text v-if="item.subText" class="tn-action-sheet__item__subtext tn-text-ellipsis">{{item.subText}}</text>
</view>
</block>
<!-- 取消按钮 -->
<block v-if="cancelBtn">
<view class="tn-action-sheet__cancel--gab"></view>
<view
class="tn-action-sheet__cancel tn-action-sheet__item"
hover-class="tn-hover-class"
:hover-stay-time="150"
@tap="close"
>{{cancelText}}</view>
</block>
</tn-popup>
</view>
</template>
<script>
export default {
name: 'tn-action-sheet',
props: {
// 通过v-model控制弹出和收起
value: {
type: Boolean,
default: false
},
// 按钮文字数组,可以自定义颜色和字体大小
// return [{
// text: '确定',
// subText: '这是一个确定按钮',
// color: '',
// fontSize: '',
// disabled: true
// }]
list: {
type: Array,
default() {
return []
}
},
// 顶部提示文字
tips: {
type: Object,
default() {
return {
text: '',
color: '',
fontSize: 26
}
}
},
// 弹出的顶部圆角值
borderRadius: {
type: Number,
default: 0
},
// 点击遮罩可以关闭
maskCloseable: {
type: Boolean,
default: true
},
// 底部取消按钮
cancelBtn: {
type: Boolean,
default: true
},
// 底部取消按钮的文字
cancelText: {
type: String,
default: '取消'
},
// 开启底部安全区域
// 在iPhoneX机型底部添加一定的内边距
safeAreaInsetBottom: {
type: Boolean,
default: false
},
// z-index值
zIndex: {
type: Number,
default: 0
}
},
computed: {
// 顶部提示样式
tipsStyle() {
let style = {}
if (this.tips.color) style.color = this.tips.color
if (this.tips.fontSize) style.fontSize = this.tips.fontSize + 'rpx'
return style
},
// 操作项目的样式
itemStyle() {
return (index) => {
let style = {}
if (this.list[index].color) style.color = this.list[index].color
if (this.list[index].fontSize) style.fontSize = this.list[index].fontSize + 'rpx'
// 选项被禁用的样式
if (this.list[index].disabled) style.color = '#AAAAAA'
return style
}
},
elZIndex() {
return this.zIndex ? this.zIndex : this.$t.zIndex.popup
}
},
methods: {
// 点击取消按钮
close() {
// 发送input事件,并不会作用于父组件,而是要设置组件内部通过props传递的value参数
this.popupClose();
this.$emit('close');
},
// 关闭弹窗
popupClose() {
this.$emit('input', false)
},
// 点击对应的item
itemClick(index) {
// 如果是禁用项则不进行操作
if (this.list[index].disabled) return
this.$emit('click', index)
this.popupClose()
}
}
}
</script>
<style lang="scss" scoped>
.tn-action-sheet {
&__tips {
font-size: 26rpx;
text-align: center;
padding: 34rpx 0;
line-height: 1;
color: $tn-content-color;
}
&__item {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: 32rpx;
padding: 34rpx 0;
&__subtext {
font-size: 24rpx;
color: $tn-content-color;
margin-top: 20rpx;
}
}
&__cancel {
color: $tn-font-color;
&--gab {
height: 12rpx;
background-color: #eaeaec;
}
}
}
</style>
@@ -0,0 +1,101 @@
<template>
<view class="tn-avatar-group-class tn-avatar-group">
<view v-for="(item, index) in lists" :key="index" class="tn-avatar-group__item" :style="[itemStyle]">
<tn-avatar
:src="item.src || ''"
:text="item.text || ''"
:icon="item.icon || ''"
:size="size"
:shape="shape"
:imgMode="imgMode"
:border="true"
:borderSize="4"
></tn-avatar>
</view>
</view>
</template>
<script>
export default {
name: 'tn-avatar-group',
props: {
// 头像列表
lists: {
type: Array,
default() {
return []
}
},
// 头像类型
// square 带圆角正方形 circle 圆形
shape: {
type: String,
default: 'circle'
},
// 大小
// sm 小头像 lg 大头像 xl 加大头像
// 如果为其他则认为是直接设置大小
size: {
type: [Number, String],
default: ''
},
// 当设置为显示头像信息时,
// 图片的裁剪模式
imgMode: {
type: String,
default: 'aspectFill'
},
// 头像之间的遮挡比例
// 0.4 代表 40%
gap: {
type: Number,
default: 0.4
}
},
computed: {
itemStyle() {
let style = {}
if (this._checkSizeIsInline()) {
switch(this.size) {
case 'sm':
style.marginLeft = `${-48 * this.gap}rpx`
break
case 'lg':
style.marginLeft = `${-96 * this.gap}rpx`
break
case 'xl':
style.marginLeft = `${-128 * this.gap}rpx`
break
}
} else {
const size = Number(this.size.replace(/(px|rpx)/g, '')) || 64
style.marginLeft = `-${size * this.gap}rpx`
}
return style
}
},
data() {
return {
}
},
methods: {
// 检查是否使用内置的大小进行设置
_checkSizeIsInline() {
if (/(xs|sm|md|lg|xl|xxl)/.test(this.size)) return true
else return false
}
}
}
</script>
<style lang="scss" scoped>
.tn-avatar-group {
display: flex;
flex-direction: row;
&__item {
position: relative;
}
}
</style>
@@ -0,0 +1,298 @@
<template>
<view
class="tn-avatar-class tn-avatar"
:class="[backgroundColorClass,avatarClass]"
:style="[avatarStyle]"
@tap="click"
>
<image
v-if="showImg"
class="tn-avatar__img"
:class="[imgClass]"
:src="src"
:mode="imgMode || 'aspectFill'"
@error="loadImageError"
></image>
<view v-else class="tn-avatar__text" >
<view v-if="text">{{ text }}</view>
<view v-else :class="[`tn-icon-${icon}`]"></view>
</view>
<!-- 角标 -->
<tn-badge
v-if="badge && (badgeIcon || badgeText)"
:radius="badgeSize"
:backgroundColor="badgeBgColor"
:fontColor="badgeColor"
:fontSize="badgeSize - 8"
:absolute="true"
:top="badgePosition[0]"
:right="badgePosition[1]"
>
<view v-if="badgeIcon && badgeText === ''">
<view :class="[`tn-icon-${badgeIcon}`]"></view>
</view>
<view v-else>
{{ badgeText }}
</view>
</tn-badge>
</view>
</template>
<script>
import componentsColorMixin from '../../libs/mixin/components_color.js'
export default {
mixins: [componentsColorMixin],
name: 'tn-avatar',
props: {
// 序号
index: {
type: [Number, String],
default: 0
},
// 头像类型
// square 带圆角正方形 circle 圆形
shape: {
type: String,
default: 'circle'
},
// 大小
// sm 小头像 lg 大头像 xl 加大头像
// 如果为其他则认为是直接设置大小
size: {
type: [Number, String],
default: ''
},
// 是否显示阴影
shadow: {
type: Boolean,
default: false
},
// 是否显示边框
border: {
type: Boolean,
default: false
},
// 边框颜色
borderColor: {
type: String,
default: 'rgba(0, 0, 0, 0.1)'
},
// 边框大小, rpx
borderSize: {
type: Number,
default: 2
},
// 头像路径
src: {
type: String,
default: ''
},
// 文字
text: {
type: String,
default: ''
},
// 图标
icon: {
type: String,
default: ''
},
// 当设置为显示头像信息时,
// 图片的裁剪模式
imgMode: {
type: String,
default: 'aspectFill'
},
// 是否显示角标
badge: {
type: Boolean,
default: false
},
// 设置显示角标后,角标大小
badgeSize: {
type: Number,
default: 28
},
// 角标背景颜色
badgeBgColor: {
type: String,
default: '#AAAAAA'
},
// 角标字体颜色
badgeColor: {
type: String,
default: '#FFFFFF'
},
// 角标图标
badgeIcon: {
type: String,
default: ''
},
// 角标文字,优先级比icon高
badgeText: {
type: String,
default: ''
},
// 角标坐标
// [top, right]
badgePosition: {
type: Array,
default() {
return [0, 0]
}
}
},
data() {
return {
// 图片显示是否发生错误
imgLoadError: false
}
},
computed: {
showImg() {
// 如果设置了图片地址,则为显示图片,否则为显示文本
return this.text === '' && this.icon === ''
},
avatarClass() {
let clazz = ''
clazz += ` tn-avatar--${this.shape}`
if (this._checkSizeIsInline()) {
clazz += ` tn-avatar--${this.size}`
}
if (this.shadow) {
clazz += ' tn-avatar--shadow'
}
return clazz
},
avatarStyle() {
let style = {}
if (this.backgroundColorStyle) {
style.background = this.backgroundColorStyle
} else if (this.shadow && this.showImg) {
style.backgroundImage = `url(${this.src})`
}
if (this.border) {
style.border = `${this.borderSize}rpx solid ${this.borderColor}`
}
if (!this._checkSizeIsInline()) {
style.width = this.size
style.height = this.size
}
return style
},
imgClass() {
let clazz = ''
clazz += ` tn-avatar__img--${this.shape}`
return clazz
}
},
methods: {
// 加载图片失败
loadImageError() {
this.imgLoadError = true
},
// 点击事件
click() {
this.$emit("click", this.index)
},
// 检查是否使用内置的大小进行设置
_checkSizeIsInline() {
if (/^(xs|sm|md|lg|xl|xxl)$/.test(this.size)) return true
else return false
}
}
}
</script>
<style lang="scss" scoped>
.tn-avatar {
/* #ifndef APP-NVUE */
display: inline-flex;
/* #endif */
margin: 0;
padding: 0;
text-align: center;
align-items: center;
justify-content: center;
background-color: $tn-font-holder-color;
color: #FFFFFF;
white-space: nowrap;
position: relative;
width: 64rpx;
height: 64rpx;
z-index: 1;
&--sm {
width: 48rpx;
height: 48rpx;
}
&--lg {
width: 96rpx;
height: 96rpx;
}
&--xl {
width: 128rpx;
height: 128rpx;
}
&--square {
border-radius: 10rpx;
}
&--circle {
border-radius: 5000rpx;
}
&--shadow {
position: relative;
&::after {
content: " ";
display: block;
background: inherit;
filter: blur(10rpx);
position: absolute;
width: 100%;
height: 100%;
top: 10rpx;
left: 10rpx;
z-index: -1;
opacity: 0.4;
transform-origin: 0 0;
border-radius: inherit;
transform: scale(1, 1);
}
}
&__img {
width: 100%;
height: 100%;
&--square {
border-radius: 10rpx;
}
&--circle {
border-radius: 5000rpx;
}
}
&__text {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
}
}
</style>
+172
View File
@@ -0,0 +1,172 @@
<template>
<view
class="tn-badge-class tn-badge"
:class="[
backgroundColorClass,
fontColorClass,
badgeClass
]"
:style="[badgeStyle]"
@click="handleClick"
>
<slot v-if="!dot"></slot>
</view>
</template>
<script>
import componentsColorMixin from '../../libs/mixin/components_color.js'
export default {
mixins: [componentsColorMixin],
name: 'tn-badge',
props: {
// 序号
index: {
type: [Number, String],
default: '0'
},
// 徽章的大小 rpx
radius: {
type: Number,
default: 0
},
// 内边距
padding: {
type: String,
default: ''
},
// 外边距
margin: {
type: String,
default: '0'
},
// 是否为一个点
dot: {
type: Boolean,
default: false
},
// 是否使用绝对定位
absolute: {
type: Boolean,
default: false
},
// top
top: {
type: [String, Number],
default: '0'
},
// right
right: {
type: [String, Number],
default: '0'
},
// 居中 对齐右上角
translateCenter: {
type: Boolean,
default: true
}
},
computed: {
badgeClass() {
let clazz = ''
if (this.dot) {
clazz += ' tn-badge--dot'
}
if (this.absolute) {
clazz += ' tn-badge--absolute'
if (this.translateCenter) {
clazz += ' tn-badge--center-position'
}
}
return clazz
},
badgeStyle() {
let style = {}
if (this.radius !== 0) {
style.width = this.radius + 'rpx'
style.height = this.radius + 'rpx'
// style.borderRadius = (this.radius * 8) + 'rpx'
}
if (this.padding) {
style.padding = this.padding
}
if (this.margin) {
style.margin = this.margin
}
if (this.fontColorStyle) {
style.color = this.fontColorStyle
}
if (this.fontSize) {
style.fontSize = this.fontSize + this.fontUnit
}
if (this.backgroundColorStyle) {
style.backgroundColor = this.backgroundColorStyle
}
if (this.top) {
style.top = this.$t.string.getLengthUnitValue(this.top)
}
if (this.right) {
style.right = this.$t.string.getLengthUnitValue(this.right)
}
return style
},
},
data() {
return {
}
},
methods: {
// 处理点击事件
handleClick() {
this.$emit('click', {
index: Number(this.index)
})
this.$emit('tap', {
index: Number(this.index)
})
},
}
}
</script>
<style lang="scss" scoped>
.tn-badge {
width: auto;
height: auto;
line-height: 1;
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: center;
z-index: 10;
font-size: 18rpx;
background-color: $tn-main-color;
color: #FFFFFF;
border-radius: 100rpx;
padding: 4rpx 8rpx;
&--dot {
width: 8rpx;
height: 8rpx;
border-radius: 50%;
padding: 0;
}
&--absolute {
position: absolute;
top: 0;
right: 0;
}
&--center-position {
transform: translate(50%, -50%);
}
}
</style>
@@ -0,0 +1,298 @@
<template>
<button
class="tn-btn-class tn-btn"
:class="[
buttonClass,
backgroundColorClass,
fontColorClass
]"
:style="[buttonStyle]"
hover-class="tn-hover"
:loading="loading"
:disabled="disabled"
:form-type="formType"
:open-type="openType"
@getuserinfo="handleGetUserInfo"
@getphonenumber="handleGetPhoneNumber"
@contact="handleContact"
@error="handleError"
@tap="handleClick"
>
<slot></slot>
</button>
</template>
<script>
import componentsColorMixin from '../../libs/mixin/components_color.js'
export default {
mixins: [componentsColorMixin],
name: "tn-button",
// 解决再微信小程序种,自定义按钮无法触发bindsubmit
behaviors: ['wx://form-field-button'],
props: {
// 按钮索引,用于区分多个按钮
index: {
type: [Number, String],
default: 0
},
// 按钮形状 default 默认 round 圆角 icon 图标按钮
shape: {
type: String,
default: 'default'
},
// 是否加阴影
shadow: {
type: Boolean,
default: false
},
// 宽度 rpx或%
width: {
type: String,
default: 'auto'
},
// 高度 rpx或%
height: {
type: String,
default: ''
},
// 按钮的尺寸 sm lg
size: {
type: String,
default: ''
},
// 字体是否加粗
fontBold: {
type: Boolean,
default: false
},
padding: {
type: String,
default: '0 30rpx'
},
// 外边距 与css的margin参数用法相同
margin: {
type: String,
default: ''
},
// 是否镂空
plain: {
type: Boolean,
default: false
},
// 当plain=true时,是否显示边框
border: {
type: Boolean,
default: true
},
// 当plain=true时,是否加粗显示边框
borderBold: {
type: Boolean,
default: false
},
// 是否禁用
disabled: {
type: Boolean,
default: false
},
// 是否显示加载图标
loading: {
type: Boolean,
default: false
},
// 触发form表单的事件类型
formType: {
type: String,
default: ''
},
// 开放能力
openType: {
type: String,
default: ''
},
// 是否阻止重复点击(默认间隔是200ms)
blockRepeatClick: {
type: Boolean,
default: false
}
},
computed: {
// 根据不同的参数动态生成class
buttonClass() {
let clazz = ''
// 按钮形状
switch (this.shape) {
case 'icon':
case 'round':
clazz += ' tn-round'
break
}
// 阴影
if (this.shadow) {
if (this.backgroundColorClass !== '') {
const color = this.backgroundColor.slice(this.backgroundColor.lastIndexOf('-') + 1)
clazz += ` tn-shadow-${color}`
} else {
clazz += ' tn-shadow-blur'
}
}
// 字体加粗
if (this.fontBold) {
clazz += ' tn-text-bold'
}
// 设置为镂空并且设置镂空便可才进行设置
if (this.plain) {
clazz += ' tn-btn--plain'
if (this.border) {
clazz += ' tn-border-solid'
if (this.borderBold) {
clazz += ' tn-bold-border'
}
if (this.backgroundColor !== '' && this.backgroundColor.includes('tn-bg')) {
const color = this.backgroundColor.slice(this.backgroundColor.lastIndexOf('-') + 1)
clazz += ` tn-border-${color}`
}
}
}
return clazz
},
// 按钮的样式
buttonStyle() {
let style = {}
switch(this.size) {
case 'sm':
style.padding = '0 20rpx'
style.fontSize = '22rpx'
style.height = this.height || '48rpx'
break
case 'lg':
style.padding = '0 40rpx'
style.fontSize = '32rpx'
style.height = this.height || '80rpx'
break
default :
style.padding = '0 30rpx'
style.fontSize = '28rpx'
style.height = this.height || '64rpx'
}
// 是否手动设置了内边距
if (this.padding) {
style.padding = this.padding
}
// 是否手动设置外边距
if (this.margin) {
style.margin = this.margin
}
// 是否手动设置了字体大小
if (this.fontSize) {
style.fontSize = this.fontSize + this.fontUnit
}
style.width = this.shape === 'icon' ? style.height : this.width
style.padding = this.shape === 'icon' ? '0' : style.padding
if (this.fontColorStyle) {
style.color = this.fontColorStyle
}
if (!this.backgroundColorClass) {
if (this.plain) {
style.borderColor = this.backgroundColorStyle || '#01BEFF'
} else {
style.backgroundColor = this.backgroundColorStyle || '#01BEFF'
}
}
// 设置阴影
if (this.shadow && !this.backgroundColorClass) {
style.boxShadow = `6rpx 6rpx 8rpx ${(this.backgroundColorStyle || '#01BEFF')}10`
}
return style
},
},
data() {
return {
// 上次点击的时间
clickTime: 0,
// 两次点击防抖的间隔时间
clickIntervalTime: 200
}
},
methods: {
// 按钮点击事件
handleClick() {
if (this.disabled) {
return
}
if (this.blockRepeatClick) {
const nowTime = new Date().getTime()
if (nowTime - this.clickTime <= this.clickIntervalTime) {
return
}
this.clickTime = nowTime
setTimeout(() => {
this.clickTime = 0
}, this.clickIntervalTime)
}
this.$emit('click', {
index: Number(this.index)
})
// 兼容tap事件
this.$emit('tap', {
index: Number(this.index)
})
},
handleGetUserInfo({ detail = {} } = {}) {
this.$emit('getuserinfo', detail);
},
handleContact({ detail = {} } = {}) {
this.$emit('contact', detail);
},
handleGetPhoneNumber({ detail = {} } = {}) {
this.$emit('getphonenumber', detail);
},
handleError({ detail = {} } = {}) {
this.$emit('error', detail);
},
}
}
</script>
<style lang="scss" scoped>
.tn-btn {
position: relative;
display: inline-flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
line-height: 1;
text-align: center;
text-decoration: none;
overflow: visible;
margin-left: inherit;
transform: translate(0rpx, 0rpx);
margin-right: inherit;
// background-color: $tn-mai
border-radius: 12rpx;
color: #FFFFFF;
&--plain {
background-color: transparent !important;
background-image: none;
&.tn-round {
border-radius: 1000rpx !important;
}
}
}
</style>
@@ -0,0 +1,707 @@
<template>
<tn-popup
v-model="value"
mode="bottom"
:popup="false"
length="auto"
:borderRadius="borderRadius"
:safeAreaInsetBottom="safeAreaInsetBottom"
:maskCloseable="maskCloseable"
:closeBtn="closeBtn"
:zIndex="elIndex"
@close="close"
>
<view class="tn-calendar-class tn-calendar">
<!-- 头部 -->
<view class="tn-calendar__header">
<view v-if="!$slots.tooltip || !$slots.$tooltip" class="tn-calendar__header__text">
{{ toolTips }}
</view>
<view v-else>
<slot name="tooltip"></slot>
</view>
</view>
<!-- 操作提示信息 -->
<view class="tn-calendar__action">
<view v-if="changeYear" class="tn-calendar__action__icon" :style="{backgroundColor: yearArrowColor}" @tap.stop="changeYearHandler(false)">
<view><text class="tn-icon-left"></text></view>
</view>
<view v-if="changeMonth" class="tn-calendar__action__icon" :style="{backgroundColor: monthArrowColor}" @tap.stop="changeMonthHandler(false)">
<view><text class="tn-icon-left"></text></view>
</view>
<view class="tn-calendar__action__text">{{ dateTitle }}</view>
<view v-if="changeMonth" class="tn-calendar__action__icon" :style="{backgroundColor: monthArrowColor}" @tap.stop="changeMonthHandler(true)">
<view><text class="tn-icon-right"></text></view>
</view>
<view v-if="changeYear" class="tn-calendar__action__icon" :style="{backgroundColor: yearArrowColor}" @tap.stop="changeYearHandler(true)">
<view><text class="tn-icon-right"></text></view>
</view>
</view>
<!-- 星期中文标识 -->
<view class="tn-calendar__week-day-zh">
<view v-for="(item,index) in weekDayZh" :key="index" class="tn-calendar__week-day-zh__text">{{ item }}</view>
</view>
<!-- 日历主体 -->
<view class="tn-calendar__content">
<!-- 前置空白部分 -->
<block v-for="(item, index) in weekdayArr" :key="index">
<view class="tn-calendar__content__item"></view>
</block>
<view
v-for="(item, index) in daysArr"
:key="index"
class="tn-calendar__content__item"
:class="{
'tn-hover': disabledChoose(year, month, index + 1),
'tn-calendar__content--start-date': (mode === 'range' && startDate == `${year}-${month}-${index+1}`) || mode === 'date',
'tn-calendar__content--end-date': (mode === 'range' && endDate == `${year}-${month}-${index+1}`) || mode === 'date'
}"
:style="{
backgroundColor: colorValue(index, 'bg')
}"
@tap.stop="dateClick(index)"
>
<view class="tn-calendar__content__item__text" :style="{color: colorValue(index, 'text')}">
<view>{{ item.day }}</view>
</view>
<view class="tn-calendar__content__item__tips" :style="{color: item.color}">
{{ item.bottomInfo }}
</view>
</view>
<view class="tn-calendar__content__month--bg">{{ month }}</view>
</view>
<!-- 底部 -->
<view class="tn-calendar__bottom">
<view class="tn-calendar__bottom__choose">
<text>{{ mode === 'date' ? activeDate : startDate }}</text>
<text v-if="endDate">{{ endDate }}</text>
</view>
<view class="tn-calendar__bottom__btn" :style="{backgroundColor: btnColor}" @click="handleBtnClick(false)">
<view class="tn-calendar__bottom__btn--text">确定</view>
</view>
</view>
</view>
</tn-popup>
</template>
<script>
import Calendar from '../../libs/utils/calendar.js'
export default {
name: 'tn-calendar',
props: {
// 双向绑定控制组件弹出与收起
value: {
type: Boolean,
default: false
},
// 模式
// date -> 单日期 range -> 日期范围
mode: {
type: String,
default: 'date'
},
// 是否允许切换年份
changeYear: {
type: Boolean,
default: true
},
// 是否允许切换月份
changeMonth: {
type: Boolean,
default: true
},
// 可切换的最大年份
maxYear: {
type: [Number, String],
default: 2100
},
// 可切换的最小年份
minYear: {
type: [Number, String],
default: 1970
},
// 最小日期(不在范围被不允许选择)
minDate: {
type: String,
default: '1970-01-01'
},
// 最大日期,如果为空则默认为今天
maxDate: {
type: String,
default: ''
},
// 切换月份按钮的颜色
monthArrowColor: {
type: String,
default: '#AAAAAA'
},
// 切换年份按钮的颜色
yearArrowColor: {
type: String,
default: '#C8C8C8'
},
// 默认字体颜色
color: {
type: String,
default: '#080808'
},
// 选中|起始结束日期背景颜色
activeBgColor: {
type: String,
default: '#01BEFF'
},
// 选中|起始结束日期文字颜色
activeColor: {
type: String,
default: '#FFFFFF'
},
// 范围日期内的背景颜色
rangeBgColor: {
type: String,
default: '#E6E6E655'
},
// 范围日期内的文字颜色
rangeColor: {
type: String,
default: '#01BEFF'
},
// 起始日期显示的文字,mode=range时生效
startText: {
type: String,
default: '开始'
},
// 结束日期显示的文字,mode=range时生效
endText: {
type: String,
default: '结束'
},
// 按钮背景颜色
btnColor: {
type: String,
default: '#01BEFF'
},
// 农历文字的颜色
lunarColor: {
type: String,
default: '#AAAAAA'
},
// 选中日期是否有选中效果
isActiveCurrent: {
type: Boolean,
default: true
},
// 切换年月是否触发事件,mode=date时生效
isChange: {
type: Boolean,
default: false
},
// 是否显示农历
showLunar: {
type: Boolean,
default: true
},
// 顶部提示文字
toolTips: {
type: String,
default: '请选择日期'
},
// 显示圆角的大小
borderRadius: {
type: Number,
default: 8
},
// 是否开启底部安全区适配,开启的话,会在iPhoneX机型底部添加一定的内边距
safeAreaInsetBottom: {
type: Boolean,
default: false
},
// 是否可以通过点击遮罩进行关闭
maskCloseable: {
type: Boolean,
default: true
},
// zIndex
zIndex: {
type: Number,
default: 0
},
// 是否显示关闭按钮
closeBtn: {
type: Boolean,
default: false
},
},
computed: {
dateChange() {
return `${this.mode}-${this.minDate}-${this.maxDate}`
},
elIndex() {
return this.zIndex ? this.zIndex : this.$t.zIndex.popup
},
colorValue() {
return (index, type) => {
let color = type === 'bg' ? '' : this.color
let day = index + 1
let date = `${this.year}-${this.month}-${day}`
let timestamp = new Date(date.replace(/\-/g,'/')).getTime()
let start = this.startDate.replace(/\-/g,'/')
let end = this.endDate.replace(/\-/g,'/')
if ((this.mode === 'date' && this.isActiveCurrent && this.activeDate == date) || this.startDate == date || this.endDate == date) {
color = type === 'bg' ? this.activeBgColor : this.activeColor
} else if (this.endDate && timestamp > new Date(start).getTime() && timestamp < new Date(end).getTime()) {
color = type === 'bg' ? this.rangeBgColor : this.rangeColor
}
return color
}
}
},
data() {
return {
// 星期几,1-7
weekday: 1,
weekdayArr: [],
// 星期对应的中文
weekDayZh: ['日','一','二','三','四','五','六'],
// 当前月有多少天
days: 0,
daysArr: [],
year: 2021,
month: 0,
day: 0,
startYear: 0,
startMonth: 0,
startDay: 0,
endYear: 0,
endMonth: 0,
endDay: 0,
today: '',
activeDate: '',
startDate: '',
endDate: '',
min: null,
max: null,
// 日期标题
dateTitle: '',
// 标记是否已经选择了开始日期
chooseStart: false
}
},
watch: {
dateChange() {
this.init()
}
},
created() {
this.init()
},
methods: {
// 初始化
init() {
let now = new Date()
this.year = now.getFullYear()
this.month = now.getMonth() + 1
this.day = now.getDate()
this.today = `${this.year}-${this.month}-${this.day}`
this.activeDate = this.today
this.min = this.initDate(this.minDate)
this.max = this.initDate(this.maxDate || this.today)
this.startDate = ''
this.startYear = 0
this.startMonth = 0
this.startDay = 0
this.endDate = ''
this.endYear = 0
this.endMonth = 0
this.endDay = 0
this.chooseStart = false
this.changeData()
},
// 切换月份
changeMonthHandler(add) {
if (add) {
let month = this.month + 1
let year = month > 12 ? this.year + 1 : this.year
if (!this.checkRange(year)) {
this.month = month > 12 ? 1 : month
this.year = year
this.changeData()
}
} else {
let month = this.month - 1
let year = month < 1 ? this.year - 1 : this.year
if (!this.checkRange(year)) {
this.month = month < 1 ? 12 : month
this.year = year
this.changeData()
}
}
},
// 切换年份
changeYearHandler(add) {
let year = add ? this.year + 1 : this.year - 1
if (!this.checkRange(year)) {
this.year = year
this.changeData()
}
},
// 日期点击事件
dateClick(day) {
day += 1
if (!this.disabledChoose(this.year, this.month, day)) {
this.day = day
let date = `${this.year}-${this.month}-${day}`
if (this.mode === 'date') {
this.activeDate = date
} else {
let startTimeCompare = new Date(date.replace(/\-/g,'/')).getTime() < new Date(this.startDate.replace(/\-/g,'/')).getTime()
if (!this.chooseStart || startTimeCompare) {
this.startDate = date
this.startYear = this.year
this.startMonth = this.month
this.startDay = this.day
this.endYear = 0
this.endMonth = 0
this.endDay = 0
this.endDate = ''
this.activeDate = ''
this.chooseStart = true
} else {
this.endDate = date
this.endYear = this.year
this.endMonth = this.month
this.endDay = this.day
this.chooseStart = false
}
}
this.daysArr = this.handleDaysArr()
}
},
// 修改日期数据
changeData() {
this.days = this.getMonthDay(this.year, this.month)
this.daysArr = this.handleDaysArr()
this.weekday = this.getMonthFirstWeekDay(this.year, this.month)
this.weekdayArr = this.generateArray(1, this.weekday)
this.dateTitle = `${this.year}${this.month}`
if (this.isChange && this.mode === 'date') {
this.handleBtnClick(true)
}
},
// 处理按钮点击
handleBtnClick(show) {
if (!show) {
this.close()
}
if (this.mode === 'date') {
let arr = this.activeDate.split('-')
let year = this.isChange ? this.year : Number(arr[0])
let month = this.isChange ? this.month : Number(arr[1])
let day = this.isChange ? this.day : Number(arr[2])
let days = this.getMonthDay(year, month)
let result = `${year}-${this.formatNumber(month)}-${this.formatNumber(day)}`
let weekText = this.getWeekText(result)
let isToday = false
if (`${year}-${month}-${day}` === this.today) {
isToday = true
}
this.$emit('change', {
year,
month,
day,
days,
week: weekText,
isToday,
date: result,
// 是否为切换年月操作
switch: show
})
} else {
if (!this.startDate || !this.endDate) return
let startMonth = this.formatNumber(this.startMonth)
let startDay = this.formatNumber(this.startDay)
let startDate = `${this.startYear}-${startMonth}-${startDay}`
let startWeek = this.getWeekText(startDate)
let endMonth = this.formatNumber(this.endMonth)
let endDay = this.formatNumber(this.endDay)
let endDate = `${this.endYear}-${endMonth}-${endDay}`
let endWeek = this.getWeekText(endDate)
this.$emit('change', {
startYear: this.startYear,
startMonth: this.startMonth,
startDay: this.startDay,
startDate,
startWeek,
endYear: this.endYear,
endMonth: this.endMonth,
endDay: this.endDay,
endDate,
endWeek
})
}
},
// 判断是否允许选择
disabledChoose(year, month, day) {
let flag = true
let date = `${year}/${month}/${day}`
let min = `${this.min.year}/${this.min.month}/${this.min.day}`
let max = `${this.max.year}/${this.max.month}/${this.max.day}`
let timestamp = new Date(date).getTime()
if (timestamp >= new Date(min).getTime() && timestamp <= new Date(max).getTime()) {
flag = false
}
return flag
},
// 检查是否在日期范围内
checkRange(year) {
let overstep = false
if (year < this.minYear || year > this.maxYear) {
uni.showToast({
title: '所选日期超出范围',
icon: 'none'
})
overstep = true
}
return overstep
},
// 处理日期
initDate(date) {
let fdate = date.split('-')
return {
year: Number(fdate[0] || 1970),
month: Number(fdate[1] || 1),
day: Number(fdate[2] || 1)
}
},
// 处理日期数组
handleDaysArr() {
let days = this.generateArray(1, this.days)
let daysArr = days.map((item) => {
let bottomInfo = this.showLunar ? Calendar.solar2lunar(this.year, this.month, item).IDayCn : ''
let color = this.showLunar ? this.lunarColor : this.activeColor
if (
(this.mode === 'date' && this.day == item) ||
(this.mode === 'range' && (this.startDay == item || this.endDay == item))
) {
color = this.activeColor
}
if (this.mode === 'range') {
if (this.startDay == item && this.startDay != this.endDay) {
bottomInfo = this.startText
}
if (this.endDay == item) {
bottomInfo = this.endText
}
}
return {
day: item,
color: color,
bottomInfo: bottomInfo
}
})
return daysArr
},
// 获取对应月有多少天
getMonthDay(year, month) {
return new Date(year, month, 0).getDate()
},
// 获取对应月的第一天时星期几
getMonthFirstWeekDay(year, month) {
return new Date(`${year}/${month}/01 00:00:00`).getDay()
},
// 获取对应星期的文本
getWeekText(date) {
date = new Date(`${date.replace(/\-/g, '/')} 00:00:00`)
let week = date.getDay()
return '星期' + this.weekDayZh[week]
},
// 生成日期天数数组
generateArray(start, end) {
return Array.from(new Array(end + 1).keys()).slice(start)
},
// 格式化数字
formatNumber(num) {
return num < 10 ? '0' + num : num + ''
},
// 关闭窗口
close() {
this.$emit('input', false)
}
}
}
</script>
<style lang="scss" scoped>
.tn-calendar {
color: $tn-font-color;
&__header {
width: 100%;
box-sizing: border-box;
font-size: 30rpx;
background-color: #FFFFFF;
color: $tn-main-color;
&__text {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
margin-top: 30rpx;
padding: 0 60rpx;
}
}
&__action {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
padding: 40rpx 0 40rpx 0;
&__icon {
display: flex;
align-items: center;
justify-content: center;
margin: 0 16rpx;
width: 32rpx;
height: 32rpx;
font-size: 20rpx;
// line-height: 32rpx;
border-radius: 50%;
color: #FFFFFF;
}
&__text {
padding: 0 16rpx;
color: $tn-font-color;
font-size: 32rpx;
font-weight: bold;
}
}
&__week-day-zh {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
padding: 12rpx 0;
overflow: hidden;
box-shadow: 16rpx 6rpx 8rpx 0 #E6E6E6;
margin-bottom: 2rpx;
&__text {
flex: 1;
text-align: center;
}
}
&__content {
display: flex;
flex-direction: row;
flex-wrap: wrap;
width: 100%;
padding: 12rpx 0;
box-sizing: border-box;
background-color: #F7F7F7;
position: relative;
&__item {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 14.2857%;
padding: 12rpx 0;
margin: 6rpx 0;
overflow: hidden;
position: relative;
z-index: 2;
// box-shadow: inset 0rpx 0rpx 22rpx 4rpx rgba(255,255,255, 0.52);
&__text {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 80rpx;
font-size: 32rpx;
position: relative;
}
&__tips {
position: absolute;
width: 100%;
line-height: 24rpx;
left: 0;
bottom: 8rpx;
text-align: center;
z-index: 2;
transform-origin: center center;
transform: scale(0.8);
}
}
&--start-date {
border-top-left-radius: 8rpx;
border-bottom-left-radius: 8rpx;
}
&--end-date {
border-top-right-radius: 8rpx;
border-bottom-right-radius: 8rpx;
}
&__month {
&--bg {
position: absolute;
font-size: 200rpx;
line-height: 200rpx;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
color: $tn-font-holder-color;
z-index: 1;
}
}
}
&__bottom {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 100%;
background-color: #F7F7F7;
padding: 0 40rpx 30rpx;
box-sizing: border-box;
font-size: 24rpx;
color: $tn-font-sub-color;
&__choose {
height: 50rpx;
}
&__btn {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 60rpx;
border-radius: 40rpx;
color: #FFFFFF;
font-size: 28rpx;
}
}
}
</style>
@@ -0,0 +1,320 @@
<template>
<view class="tn-car-keyboard-class tn-car-keyboard" @touchmove.stop.prevent="() => {}">
<view class="tn-car-keyboard__grids">
<view
v-for="(data, index) in inputCarNumber ? endKeyBoardList : areaList"
:key="index"
class="tn-car-keyboard__grids__item"
>
<view
v-for="(sub_data, sub_index) in data"
:key="sub_index"
class="tn-car-keyboard__grids__btn"
:class="{'tn-car-keyboard__grids__btn--disabled': sub_data === 'I'}"
:hover-class="sub_data !== 'I' ? 'tn-car-keyboard--hover' : ''"
:hover-stay-time="100"
@tap="click(index, sub_index)"
>
{{ sub_data }}
</view>
</view>
<view
class="tn-car-keyboard__back"
hover-class="tn-hover-class"
:hover-stay-time="150"
@touchstart.stop="backspaceClick"
@touchend="clearTimer"
>
<view class="tn-icon-left-arrow tn-car-keyboard__back__icon"></view>
</view>
<view
class="tn-car-keyboard__change"
hover-class="tn-car-keyboard--hover"
:hover-stay-time="150"
@tap="changeMode"
>
<text class="tn-car-keyboard__mode--zh" :class="[`tn-car-keyboard__mode--${!inputCarNumber ? 'active' : 'inactive'}`]"></text>
/
<text class="tn-car-keyboard__mode--en" :class="[`tn-car-keyboard__mode--${inputCarNumber ? 'active' : 'inactive'}`]"></text>
</view>
</view>
</view>
</template>
<script>
export default {
name: 'tn-car-keyboard',
props: {
// 是否打乱键盘顺序
randomEnabled: {
type: Boolean,
default: false
},
// 切换中英文输入
switchEnMode: {
type: Boolean,
default: false
}
},
computed: {
areaList() {
let data = [
'京',
'沪',
'粤',
'津',
'冀',
'豫',
'云',
'辽',
'黑',
'湘',
'皖',
'鲁',
'苏',
'浙',
'赣',
'鄂',
'桂',
'甘',
'晋',
'陕',
'蒙',
'吉',
'闽',
'贵',
'渝',
'川',
'青',
'琼',
'宁',
'藏',
'港',
'澳',
'新',
'使',
'学',
'临',
'警'
]
// 打乱顺序
if (this.randomEnabled) data = this.$t.array.random(data)
// 切割二维数组
let showData = []
showData[0] = data.slice(0, 10)
showData[1] = data.slice(10, 20)
showData[2] = data.slice(20, 30)
showData[3] = data.slice(30, 37)
return showData
},
endKeyBoardList() {
let data = [
1,
2,
3,
4,
5,
6,
7,
8,
9,
0,
'Q',
'W',
'E',
'R',
'T',
'Y',
'U',
'I',
'O',
'P',
'A',
'S',
'D',
'F',
'G',
'H',
'J',
'K',
'L',
'Z',
'X',
'C',
'V',
'B',
'N',
'M'
]
// 打乱顺序
if (this.randomEnabled) data = this.$t.array.random(data)
// 切割二维数组
let showData = []
showData[0] = data.slice(0, 10)
showData[1] = data.slice(10, 20)
showData[2] = data.slice(20, 29)
showData[3] = data.slice(29, 36)
return showData
}
},
data() {
return {
// 标记是否输入车牌号码
inputCarNumber: false,
// 长按多次删除事件监听
longPressDeleteTimer: null
}
},
watch:{
switchEnMode: {
handler(value) {
if (value) {
this.inputCarNumber = true
} else {
this.inputCarNumber = false
}
},
immediate: true
}
},
methods: {
// 点击键盘按钮
click(i, j) {
let value = ''
// 根据不同模式获取不同数组的值
if (this.inputCarNumber) value = this.endKeyBoardList[i][j]
else value = this.areaList[i][j]
// 车牌里不包含I
if (value === 'I') return
this.$emit('change', value)
},
// 修改输入模式
// 中文/英文
changeMode() {
this.inputCarNumber = !this.inputCarNumber
},
// 点击退格
backspaceClick() {
this.$emit('backspace')
this.clearTimer()
this.longPressDeleteTimer = setInterval(() => {
this.$emit('backspace')
}, 250)
},
// 清空定时器
clearTimer() {
if (this.longPressDeleteTimer) {
clearInterval(this.longPressDeleteTimer)
this.longPressDeleteTimer = null
}
}
}
}
</script>
<style lang="scss" scoped>
.tn-car-keyboard {
position: relative;
padding: 24rpx 0;
background-color: #E6E6E6;
&__grids {
&__item {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
}
&__btn {
display: inline-flex;
justify-content: center;
flex: 0 0 64rpx;
width: 62rpx;
height: 80rpx;
font-size: 38rpx;
line-height: 80rpx;
font-weight: 500;
text-decoration: none;
text-align: center;
background-color: #FFFFFF;
margin: 8rpx 5rpx;
border-radius: 8rpx;
box-shadow: 0 2rpx 0rpx $tn-box-shadow-color;
&--disabled {
opacity: 0.6;
}
}
}
&__back {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
position: absolute;
width: 96rpx;
height: 80rpx;
right: 22rpx;
bottom: 32rpx;
background-color: #E6E6E6;
border-radius: 8rpx;
box-shadow: 0 2rpx 0rpx $tn-box-shadow-color;
}
&__change {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
position: absolute;
width: 96rpx;
height: 80rpx;
left: 22rpx;
bottom: 32rpx;
line-height: 1;
background-color: #FFFFFF;
border-radius: 8rpx;
box-shadow: 0 2rpx 0rpx $tn-box-shadow-color;
}
&__mode {
&--zh {
transform: translateY(-10rpx);
}
&--en {
transform: translateY(10rpx);
}
&--active {
color: $tn-main-color;
font-size: 30rpx;
}
&--inactive {
&.tn-car-keyboard__mode--zh {
transform: scale(0.85) translateY(-10rpx);
}
}
&--inactive {
&.tn-car-keyboard__mode--en {
transform: scale(0.85) translateY(10rpx);
}
}
}
&--hover {
background-color: #E6E6E6 !important;
}
}
</style>
@@ -0,0 +1,134 @@
<template>
<view class="tn-checkbox-group-class tn-checkbox-group">
<slot></slot>
</view>
</template>
<script>
import Emitter from '../../libs/utils/emitter.js'
export default {
mixins: [ Emitter ],
name: 'tn-checkbox-group',
props: {
value: {
type: Array,
default() {
return []
}
},
// 可以选中多少个checkbox
max: {
type: Number,
default: 999
},
// 表单提交时的标识符
name: {
type: String,
default: ''
},
// 禁用选择
disabled: {
type: Boolean,
default: false
},
// 禁用点击标签进行选择
disabledLabel: {
type: Boolean,
default: false
},
// 选择框的形状 square 方形 circle 圆形
shape: {
type: String,
default: 'square'
},
// 选中时的颜色
activeColor: {
type: String,
default: '#01BEFF'
},
// 组件大小
size: {
type: Number,
default: 34
},
// 每个checkbox占的宽度
width: {
type: String,
default: 'auto'
},
// 是否换行
wrap: {
type: Boolean,
default: false
},
// 图标大小
iconSize: {
type: Number,
default: 20
}
},
computed: {
// 这里computed的变量,都是子组件tn-checkbox需要用到的,由于头条小程序的兼容性差异,子组件无法实时监听父组件参数的变化
// 所以需要手动通知子组件,这里返回一个parentData变量,供watch监听,在其中去通知每一个子组件重新从父组件(tn-checkbox-group)
// 拉取父组件新的变化后的参数
parentData() {
return [this.value, this.disabled, this.disabledLabel, this.shape, this.activeColor, this.size, this.width, this.wrap, this.iconSize]
}
},
data() {
return {
}
},
watch: {
// 当父组件中的子组件需要共享的参数发生了变化,手动通知子组件
parentData() {
if (this.children.length) {
this.children.map(child => {
// 判断子组件(tn-checkbox)如果有updateParentData方法的话,子组件重新从父组件拉取了最新的值
typeof(child.updateParentData) === 'function' && child.updateParentData()
})
}
}
},
created() {
this.children = []
},
methods: {
initValue(values) {
this.$emit('input', values)
},
// 触发事件
emitEvent() {
let values = []
this.children.map(child => {
if (child.checkValue) values.push(child.name)
})
this.$emit('change', values)
this.$emit('input', values)
// 发出事件,用于在表单组件中嵌入checkbox的情况,进行验证
// 由于头条小程序执行迟钝,故需要用几十毫秒的延时
setTimeout(() => {
// 将当前的值发送到 tn-form-item 进行校验
this.dispatch('tn-form-item', 'on-form-change', values)
}, 60)
}
}
}
</script>
<style lang="scss" scoped>
.tn-checkbox-group {
/* #ifndef MP || APP-NVUE */
display: inline-flex;
flex-wrap: wrap;
/* #endif */
&::after {
content: " ";
display: table;
clear: both;
}
}
</style>

Some files were not shown because too many files have changed in this diff Show More