榆钱落尽槿花稀 01448b7113 feat: 添加多个静态图片资源及配置文件
新增了多个静态图片资源文件,包括01.png、02.png等,并添加了相关的配置文件和组件,如vue.config.js、package.json等。同时引入了Tuniao UI库,并配置了相关的依赖和设置,以支持项目的开发和构建。
2025-05-09 17:07:24 +08:00

255 lines
7.2 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view
v-if="show"
class="tn-skeleton-class tn-skeleton"
:class="[backgroundColorClass]"
:style="[skeletonStyle]"
@touchmove.stop.prevent
>
<view
v-for="(item, index) in rectNodes"
:key="$tn.uuid()"
class="tn-skeleton__item tn-skeleton__item--rect"
:class="[elBackgroundColorClass, {'tn-skeleton__item--fade': animation}]"
:style="[itemStyle('rect', item)]"
></view>
<view
v-for="(item, index) in circleNodes"
:key="$tn.uuid()"
class="tn-skeleton__item tn-skeleton__item--circle"
:class="[elBackgroundColorClass, {'tn-skeleton__item--fade': animation}]"
:style="[itemStyle('circle', item)]"
></view>
<view
v-for="(item, index) in filletNodes"
:key="$tn.uuid()"
class="tn-skeleton__item tn-skeleton__item--fillet"
:class="[elBackgroundColorClass, {'tn-skeleton__item--fade': animation}]"
:style="[itemStyle('fillet', item)]"
></view>
</view>
</template>
<script>
import componentsColorMixin from '../../libs/mixin/components_color.js'
export default {
name: 'tn-skeleton',
mixins: [ componentsColorMixin ],
props: {
// 显示骨架屏
show: {
type: Boolean,
default: false
},
// 需要渲染的元素背景颜色
elBackgroundColor: {
type: String,
default: ''
},
// 开启加载动画
animation: {
type: Boolean,
default: true
},
// 矩形元素自定义样式
rectCustomStyle: {
type: Object,
default() {
return {}
}
},
// 圆形元素自定义样式
circleCustomStyle: {
type: Object,
default() {
return {}
}
},
// 圆角元素自定义样式
filletCustomStyle: {
type: Object,
default() {
return {}
}
}
},
computed: {
elBackgroundColorStyle() {
return this.$tn.color.getBackgroundColorStyle(this.elBackgroundColor)
},
elBackgroundColorClass() {
return this.$tn.color.getBackgroundColorInternalClass(this.elBackgroundColor)
},
// 骨架屏样式
skeletonStyle() {
let style = {}
style.width = this.skeletonWidth + 'px'
style.height = this.skeletonHeight + 'px'
if (this.backgroundColorStyle) {
style.backgroundColor = this.backgroundColorStyle
}
style.left = this.left + 'px'
style.top = this.top + 'px'
return style
},
// 元素样式
itemStyle() {
return (type, item) => {
let style = {}
style.width = item.width + 'px'
style.height = item.height + 'px'
if (this.elBackgroundColorStyle) {
style.backgroundColor = this.elBackgroundColorStyle
}
style.left = (item.left - this.left) + 'px'
style.top = (item.top - this.top) + 'px'
if (type === 'rect') {
Object.assign(style, this.rectCustomStyle)
} else if (type === 'circle') {
style.borderRadius = (item.width / 2) + 'px'
Object.assign(style, this.circleCustomStyle)
} else if (type === 'fillet') {
Object.assign(style, this.filletCustomStyle)
}
return style
}
}
},
data() {
return {
// 骨架屏宽度
skeletonWidth: 750,
// 骨架屏高度
skeletonHeight: 1500,
// 圆角元素
filletNodes: [],
// 圆形元素
circleNodes: [],
// 矩形元素
rectNodes: [],
// 元素偏移位置
top: 0,
left: 0
}
},
mounted() {
this.$nextTick(() => {
// 获取系统信息
const systemInfo = uni.getSystemInfoSync()
this.skeletonWidth = systemInfo.safeArea.width
this.skeletonHeight = systemInfo.safeArea.height
this.selectQueryInfo()
})
},
methods: {
// 查询节点信息
selectQueryInfo() {
// 获取整个父容器的宽高作为骨架屏的宽高
// 在微信小程序中如果把骨架屏放入组件使用需要in(this)上下文为父组件才有效
let query = null
// 在微信小程序中如果把骨架屏放入组件使用需要in(this)上下文为父组件才有效
// #ifdef MP-WEIXIN
query = uni.createSelectorQuery().in(this.$parent)
// #endif
// #ifndef MP-WEIXIN
query = uni.createSelectorQuery()
// #endif
query.selectAll('.tn-skeleton').boundingClientRect().exec((res) => {
console.log(res);
this.skeletonWidth = res[0][0].width
this.skeletonHeight = res[0][0].height
this.top = res[0][0].bottom - res[0][0].height
this.left = res[0][0].left
})
// 获取元素列表
this.getRectElements()
this.getCircleElements()
this.getFillteElements()
},
// 矩形元素列表
getRectElements() {
let query = null
// 在微信小程序中如果把骨架屏放入组件使用需要in(this)上下文为父组件才有效
// #ifdef MP-WEIXIN
query = uni.createSelectorQuery().in(this.$parent)
// #endif
// #ifndef MP-WEIXIN
query = uni.createSelectorQuery()
// #endif
query.selectAll('.tn-skeleton-rect').boundingClientRect().exec((res) => {
this.rectNodes = res[0]
})
},
// 圆形元素列表
getCircleElements() {
let query = null
// 在微信小程序中如果把骨架屏放入组件使用需要in(this)上下文为父组件才有效
// #ifdef MP-WEIXIN
query = uni.createSelectorQuery().in(this.$parent)
// #endif
// #ifndef MP-WEIXIN
query = uni.createSelectorQuery()
// #endif
query.selectAll('.tn-skeleton-circle').boundingClientRect().exec((res) => {
this.circleNodes = res[0]
})
},
// 圆角元素列表
getFillteElements() {
let query = null
// 在微信小程序中如果把骨架屏放入组件使用需要in(this)上下文为父组件才有效
// #ifdef MP-WEIXIN
query = uni.createSelectorQuery().in(this.$parent)
// #endif
// #ifndef MP-WEIXIN
query = uni.createSelectorQuery()
// #endif
query.selectAll('.tn-skeleton-fillet').boundingClientRect().exec((res) => {
this.filletNodes = res[0]
})
}
}
}
</script>
<style lang="scss" scoped>
.tn-skeleton {
position: absolute;
z-index: 9998;
overflow: hidden;
background-color: #FFFFFF;
&__item {
position: absolute;
background-color: #F0F0F0;
&--fillet {
border-radius: 10rpx;
}
&--fade {
width: 100%;
height: 100%;
background-color: #E6E6E6;
animation-duration: 1.5s;
animation-name: blink;
animation-timing-function: ease-in-out;
animation-iteration-count: infinite;
}
}
}
@keyframes blink {
0% {
opacity: 1;
}
50% {
opacity: 0.4;
}
100% {
opacity: 1;
}
}
</style>