This commit is contained in:
dev
2025-10-28 09:25:46 +08:00
commit 9431e325df
1089 changed files with 143917 additions and 0 deletions
+4
View File
@@ -0,0 +1,4 @@
## 1.0.12023-11-15
1. 修复支付宝小程序报错的BUG
## 1.0.02023-10-30
1. 新版骨架屏上线
@@ -0,0 +1,247 @@
<template>
<view class="uv-skeleton">
<view v-if="loading">
<view v-for="(item, index) in elements" :key="index">
<!-- 横向并列布局 -->
<view class="uv-skeleton__group" :style="[style(item)]" v-if="item.type=='flex'">
<view v-for="(item2,index2) in item.children" :class="[item2.clas]" :style="[style(item2)]" :key="index2">
<view v-for="(item3,index3) in item2.elements" :key="index3">
<!-- 垂直高度站位 -->
<view :style="{height: $uv.addUnit(item3.height,'rpx')}" v-if="item3.type=='gap'"></view>
<view :class="[item3.clas, roundClass, animateClass]" :style="[style(item3)]" v-else ref="skeleton"></view>
</view>
</view>
</view>
<!-- 自定义骨架屏内容 -->
<!-- ps 自定义扩展说明 -->
<!-- 如果你需要自定义模板可以参照这个custom的写法增加一个skeleton配置类型编写布局和样式就可以了 -->
<!-- 注意事项为了保证骨架效果和动态效果的一致扩展时在你希望实际展示在页面中的元素上加上 :class="[style, animateClass]" :style="[style(item)]" ref="skeleton" -->
<view :class="[item.clas, animateClass]" :style="[style(item)]" ref="skeleton" v-else-if="item.type == 'custom'"></view>
<!-- 垂直高度站位 -->
<view :style="{height: $uv.addUnit(item.height,'rpx')}" v-else-if="item.type=='gap'"></view>
<!-- 其他基本单位 line avatar -->
<view :class="[item.clas, roundClass, animateClass]" :style="[style(item)]" v-else ref="skeleton"></view>
</view>
</view>
<view v-else>
<slot />
</view>
</view>
</template>
<script>
import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js'
import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js'
// #ifdef APP-NVUE
const animation = weex.requireModule('animation');
// #endif
export default {
name: 'uv-skeletons',
mixins: [mpMixin, mixin],
props: {
// 是否显示骨架
loading: {
type: Boolean,
default: true
},
// 骨架内容 具体说明参考文档:
skeleton: {
type: Array,
default: () => []
},
// 是否开启动画效果
animate: {
type: Boolean,
default: true
},
// 是否圆角骨架风格
round: {
type: Boolean,
default: false
},
...uni.$uv?.props?.skeleton
},
data() {
return {
elements: [],
opacity: 0.5,
duration: 600
}
},
computed: {
animateClass() {
return this.animate ? 'uv-skeleton--animation' : 'uv-skeleton--static';
},
roundClass() {
return this.round ? 'uv-skeleton--round' : 'uv-skeleton--radius';
},
style(item) {
return item => {
const style = {};
return this.$uv.deepMerge(style, this.$uv.addStyle(item.style));
}
}
},
created() {
this.init();
// #ifdef APP-NVUE
if (this.loading && this.animate) {
this.$uv.sleep(50).then(res => {
this.createAnimation(this.opacity);
})
}
// #endif
},
methods: {
/**
* 初始化数据
*/
init() {
let elements = [];
if (!this.$uv.test.array(this.skeleton)) return this.$uv.error('skeleton参数必须为数组形式,参考文档示例:');
this.skeleton.forEach(el => {
const elClass = this.getElCounts(el);
elements = elements.concat(elClass);
})
this.elements = [...elements];
},
/**
* 处理骨架屏参数内容
* @param {Object} el 每项数据
*/
getElCounts(el) {
let elements = [];
let children = [];
if (this.$uv.test.number(el)) {
elements.push({
type: 'gap',
height: el
});
return elements;
} else {
const type = el.type ? el.type : 'line';
const num = el.num ? el.num : 1;
const style = el.style ? el.style : {};
const styleIsArray = this.$uv.test.array(style);
const gap = el.gap ? el.gap : '20rpx';
const child = el.children ? el.children : [];
for (let i = 0; i < child.length; i++) {
children[i] = {
clas: child[i].type.indexOf('avatar') > -1 || child[i].type.indexOf('custom') > -1 ? '' : 'uv-skeleton__group__sub',
elements: this.getElCounts(child[i])
};
}
for (let i = 0; i < num; i++) {
if (gap && i < num && i > 0) {
elements.push({
type: 'gap',
height: gap
});
}
elements.push({
clas: `uv-skeleton__${type}`,
type,
style: styleIsArray ? style[i] : style,
gap,
children
});
}
return elements;
}
},
/**
* 创建动画
*/
createAnimation(opacity = 1) {
// loading结束之后或未开启动画不执行
if (!this.loading || !this.animate) return;
let count = 0;
const skeletons = this.$refs.skeleton;
skeletons.forEach(item => {
animation.transition(item, {
styles: {
opacity: opacity,
},
duration: this.duration
}, () => {
count++;
if (count >= skeletons.length) {
setTimeout(() => {
this.createAnimation(opacity < 1 ? 1 : this.opacity);
}, 200)
}
});
})
}
}
}
</script>
<style scoped lang="scss">
@import '@/uni_modules/uv-ui-tools/libs/css/components.scss';
@mixin background {
/* #ifdef APP-NVUE */
background-color: #e6e6e6;
/* #endif */
/* #ifndef APP-NVUE */
background: linear-gradient(90deg, #F1F2F4 25%, #e6e6e6 37%, #F1F2F4 50%);
background-size: 400% 100%;
/* #endif */
}
.uv-skeleton__line {
height: 32rpx;
// margin-bottom: 30rpx;
}
.uv-skeleton__line--sm {
height: 24rpx;
margin-bottom: 30rpx;
}
.uv-skeleton__line--lg {
height: 48rpx;
margin-bottom: 30rpx;
}
.uv-skeleton--static {
@include background;
}
.uv-skeleton--radius {
border-radius: 8rpx;
}
.uv-skeleton--round {
border-radius: 30rpx;
}
.uv-skeleton__avatar {
width: 100rpx;
height: 100rpx;
border-radius: 50rpx;
}
.uv-skeleton__avatar--sm {
width: 50rpx;
height: 50rpx;
border-radius: 25rpx;
}
.uv-skeleton__avatar--lg {
width: 200rpx;
height: 200rpx;
border-radius: 100rpx;
}
.uv-skeleton__group {
@include flex;
&__sub {
flex: 1;
}
}
.uv-skeleton--animation {
@include background;
/* #ifndef APP-NVUE */
animation: skeleton 1.8s ease infinite
/* #endif */
}
/* #ifndef APP-NVUE */
@keyframes skeleton {
0% {
background-position: 100% 50%
}
100% {
background-position: 0 50%
}
}
/* #endif */
</style>
+88
View File
@@ -0,0 +1,88 @@
{
"id": "uv-skeletons",
"displayName": "uv-skeletons 骨架屏 全面兼容小程序、nvue、vue2、vue3等多端",
"version": "1.0.1",
"description": "全新升级骨架屏,更加灵活,体验更加,强烈推荐使用新版骨架屏。一般用于页面在请求远程数据尚未完成时,在内容加载出来前展示与内容布局结构一致的灰白块,提升用户视觉体验。",
"keywords": [
"uv-skeletons",
"uvui",
"uv-ui",
"skeleton",
"骨架屏"
],
"repository": "",
"engines": {
"HBuilderX": "^3.1.0"
},
"dcloudext": {
"type": "component-vue",
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "插件不采集任何数据",
"permissions": "无"
},
"npmurl": ""
},
"uni_modules": {
"dependencies": [
"uv-ui-tools",
"uv-text"
],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"Vue": {
"vue2": "y",
"vue3": "y"
},
"App": {
"app-vue": "y",
"app-nvue": "y"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y",
"钉钉": "u",
"快手": "u",
"飞书": "u",
"京东": "u"
},
"快应用": {
"华为": "u",
"联盟": "u"
}
}
}
}
}
+23
View File
@@ -0,0 +1,23 @@
# Skeletons 新版骨架屏
> **组件名:uv-skeletons**
骨架屏一般用于页面在请求远程数据尚未完成时,在内容加载出来前展示与内容布局结构一致的灰白块,提升用户视觉体验。
新版骨架屏与老版本使用参数有很大的区别,所以才有了新版本,无法替换老版本。
新版骨架屏比老版本骨架屏更加灵活,理论上简单的左右上下布局结构均可以轻松实现,样式自由度较高,只要你会写css,推荐使用新版。
# <a href="https://www.uvui.cn/components/skeletons.html" target="_blank">查看文档</a>
## [下载完整示例项目](https://ext.dcloud.net.cn/plugin?name=uv-ui) <small>(请不要 下载插件ZIP</small>
### [更多插件,请关注uv-ui组件库](https://ext.dcloud.net.cn/plugin?name=uv-ui)
<a href="https://ext.dcloud.net.cn/plugin?name=uv-ui" target="_blank">
![image](https://mp-a667b617-c5f1-4a2d-9a54-683a67cff588.cdn.bspapp.com/uv-ui/banner.png)
</a>
#### 如使用过程中有任何问题反馈,或者您对uv-ui有一些好的建议,欢迎加入uv-ui官方交流群:<a href="https://www.uvui.cn/components/addQQGroup.html" target="_blank">官方QQ群</a>