fix: 修复部分问题
This commit is contained in:
parent
d596b818e2
commit
fc777ef92d
|
|
@ -149,13 +149,13 @@
|
||||||
.xnz{
|
.xnz{
|
||||||
width: 8rpx;
|
width: 8rpx;
|
||||||
height: 20rpx;
|
height: 20rpx;
|
||||||
background-color: #fff;
|
// background-color: #fff;
|
||||||
border-left: 1rpx solid black;
|
// border-left: 1rpx solid black;
|
||||||
border-right: 1rpx solid black;
|
// border-right: 1rpx solid black;
|
||||||
position: absolute;
|
// position: absolute;
|
||||||
right: 50rpx;
|
// right: 50rpx;
|
||||||
top: 19rpx;
|
// top: 19rpx;
|
||||||
transform: rotate(15deg);
|
// transform: rotate(15deg);
|
||||||
}
|
}
|
||||||
.zzt-body{
|
.zzt-body{
|
||||||
height: 10rpx;
|
height: 10rpx;
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,9 @@
|
||||||
<view style="height: 40rpx;background-color: #fff;"></view>
|
<view style="height: 40rpx;background-color: #fff;"></view>
|
||||||
|
|
||||||
<!-- 图表 -->
|
<!-- 图表 -->
|
||||||
<l-echart ref="chartRef" @finished="init"></l-echart>
|
<view class="charts">
|
||||||
|
<l-echart ref="chartRef" @finished="init"></l-echart>
|
||||||
|
</view>
|
||||||
|
|
||||||
<overview v-if="dataConfig[pageData.type].overviewData" :overviewData="dataConfig[pageData.type].overviewData"></overview>
|
<overview v-if="dataConfig[pageData.type].overviewData" :overviewData="dataConfig[pageData.type].overviewData"></overview>
|
||||||
<cankao v-if="dataConfig[pageData.type].cankaoData" :cankaoData="dataConfig[pageData.type].cankaoData" ></cankao>
|
<cankao v-if="dataConfig[pageData.type].cankaoData" :cankaoData="dataConfig[pageData.type].cankaoData" ></cankao>
|
||||||
|
|
@ -179,7 +181,7 @@ import { mapGetters } from "vuex";
|
||||||
name:'血脂概况',
|
name:'血脂概况',
|
||||||
tb_head:[
|
tb_head:[
|
||||||
'',
|
'',
|
||||||
'范围',
|
'单日测量范围',
|
||||||
'平均值'
|
'平均值'
|
||||||
],
|
],
|
||||||
data:[
|
data:[
|
||||||
|
|
@ -248,7 +250,7 @@ import { mapGetters } from "vuex";
|
||||||
0.00,
|
0.00,
|
||||||
-0.04
|
-0.04
|
||||||
],
|
],
|
||||||
max:1.5
|
max:3
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name:'低密度脂蛋白',
|
name:'低密度脂蛋白',
|
||||||
|
|
@ -1142,4 +1144,11 @@ import { mapGetters } from "vuex";
|
||||||
width: 80%;
|
width: 80%;
|
||||||
padding: 0rpx 20rpx;
|
padding: 0rpx 20rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.charts {
|
||||||
|
margin: 0rpx 100rpx;
|
||||||
|
border: 1rpx solid gray;
|
||||||
|
border-radius: 20px;
|
||||||
|
padding: 20px 0px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
@ -39,7 +39,7 @@
|
||||||
</audio>
|
</audio>
|
||||||
|
|
||||||
<div class="status">
|
<div class="status">
|
||||||
<div class="btn">正在听…</div>
|
<input class="voice-input" type="search" name="voice" id="status-txt" style="pointer-events: none"/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="AiButton">
|
<div id="AiButton">
|
||||||
|
|
@ -56,7 +56,7 @@
|
||||||
<!-- 讯飞测试 -->
|
<!-- 讯飞测试 -->
|
||||||
<div class="voice">
|
<div class="voice">
|
||||||
<div class="voice-box scroll-text">
|
<div class="voice-box scroll-text">
|
||||||
<input class="voice-input" type="search" name="voice" id="voice-txt" style="pointer-events: none"/>
|
<input class="voice-input" type="search" name="voice" id="voice-txt" style="pointer-events: none" value="我是您的健康助手, 请问您有什么帮助吗?"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -246,6 +246,7 @@
|
||||||
|
|
||||||
|
|
||||||
// 文本输入框
|
// 文本输入框
|
||||||
|
const statusTxt = document.querySelector('#status-txt');
|
||||||
const voiceTxt = document.querySelector('#voice-txt');
|
const voiceTxt = document.querySelector('#voice-txt');
|
||||||
|
|
||||||
// 防止多次请求
|
// 防止多次请求
|
||||||
|
|
@ -280,8 +281,8 @@
|
||||||
|
|
||||||
onTextChange: function (text) {
|
onTextChange: function (text) {
|
||||||
// 监听识别结果的变化
|
// 监听识别结果的变化
|
||||||
console.log(text, '监听')
|
|
||||||
voiceTxt.value = text;
|
voiceTxt.value = text;
|
||||||
|
statusTxt.value = '正在听…';
|
||||||
|
|
||||||
// 3秒钟内没有说话,就自动关闭
|
// 3秒钟内没有说话,就自动关闭
|
||||||
if (text) {
|
if (text) {
|
||||||
|
|
@ -471,6 +472,8 @@
|
||||||
isCallbackExecuted = true;
|
isCallbackExecuted = true;
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
statusTxt.value = '';
|
||||||
}, 3000);
|
}, 3000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,18 @@
|
||||||
<template>
|
<template>
|
||||||
<view>
|
<view>
|
||||||
|
<view class="skeleton flx" v-if="loading">
|
||||||
|
<view style="width: 60%">
|
||||||
|
<x-skeleton type="banner" :loading="loading"></x-skeleton>
|
||||||
|
<x-skeleton type="banner" :loading="loading"></x-skeleton>
|
||||||
|
<x-skeleton type="banner" :loading="loading"></x-skeleton>
|
||||||
|
<x-skeleton type="banner" :loading="loading"></x-skeleton>
|
||||||
|
<x-skeleton type="banner" :loading="loading"></x-skeleton>
|
||||||
|
</view>
|
||||||
|
<view style="width: 40%">
|
||||||
|
<x-skeleton :loading="loading" :configs="customConfigs" fadeOut></x-skeleton>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
<view class="content">
|
<view class="content">
|
||||||
<!-- 首页数据 -->
|
<!-- 首页数据 -->
|
||||||
<view class="content-wrap" v-if="Sindex == 1">
|
<view class="content-wrap" v-if="Sindex == 1">
|
||||||
|
|
@ -83,6 +96,17 @@
|
||||||
|
|
||||||
pageData: {
|
pageData: {
|
||||||
type: ''
|
type: ''
|
||||||
|
},
|
||||||
|
|
||||||
|
loading: true,
|
||||||
|
customConfigs: {
|
||||||
|
padding: '30rpx', //内边距
|
||||||
|
gridRows: 2, //行数
|
||||||
|
gridColumns: 1, //列数
|
||||||
|
headShow: true, //head是否展示
|
||||||
|
headWidth: '100%', //head宽度,支持百分比
|
||||||
|
headHeight: '100vh', //head高度
|
||||||
|
headBorderRadius: '12rpx', //head圆角,支持百分比
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -161,6 +185,7 @@
|
||||||
this.dataListsNew.bloodLiquidAll.type = 'bloodLiquidAll';
|
this.dataListsNew.bloodLiquidAll.type = 'bloodLiquidAll';
|
||||||
|
|
||||||
this.urlLink = `/hybrid/html/ai.html?data=${JSON.stringify(this.dataListsNew)}&user=${JSON.stringify(this.getUserInfo)}&token=${store.getters['api/getApiToken']}&deviceId=${this.getActiceDevice.device_id}`;
|
this.urlLink = `/hybrid/html/ai.html?data=${JSON.stringify(this.dataListsNew)}&user=${JSON.stringify(this.getUserInfo)}&token=${store.getters['api/getApiToken']}&deviceId=${this.getActiceDevice.device_id}`;
|
||||||
|
this.loading = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
@ -240,6 +265,16 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
.skeleton {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100vh;
|
||||||
|
overflow: hidden;
|
||||||
|
background-color: #fff;
|
||||||
|
z-index: 99;
|
||||||
|
}
|
||||||
.flex_data{
|
.flex_data{
|
||||||
display: flex;
|
display: flex;
|
||||||
.f_left{
|
.f_left{
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
## 1.0.4(2023-09-02)
|
||||||
|
1、优化一些显示的细节问题
|
||||||
|
## 1.0.3(2023-09-01)
|
||||||
|
1、新增动画、时间、颜色等相关属性
|
||||||
|
## 1.0.2(2023-08-31)
|
||||||
|
1、回滚到v1.0.0版本,暂时取消动画时间的修改属性
|
||||||
|
## 1.0.1(2023-08-31)
|
||||||
|
1、新增动画持续时间属性
|
||||||
|
2、新增淡出持续时间属性
|
||||||
|
## 1.0.0(2023-08-31)
|
||||||
|
第一个版本
|
||||||
|
|
@ -0,0 +1,147 @@
|
||||||
|
export default {
|
||||||
|
methods: {
|
||||||
|
bannerConfigs() {
|
||||||
|
return {
|
||||||
|
padding: '30rpx',
|
||||||
|
gridRows: 1,
|
||||||
|
gridColumns: 1,
|
||||||
|
gridRowsGap: '40rpx',
|
||||||
|
gridColumnsGap: '24rpx',
|
||||||
|
itemDirection: 'row',
|
||||||
|
itemGap: '30rpx',
|
||||||
|
itemAlign: 'center',
|
||||||
|
headShow: true,
|
||||||
|
headWidth: '100%',
|
||||||
|
headHeight: '300rpx',
|
||||||
|
headBorderRadius: '20rpx',
|
||||||
|
textShow: false,
|
||||||
|
textRows: 3,
|
||||||
|
textRowsGap: '20rpx',
|
||||||
|
textWidth: '100%',
|
||||||
|
textHeight: '30rpx',
|
||||||
|
textBorderRadius: '6rpx',
|
||||||
|
...this.configs
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
infoConfigs() {
|
||||||
|
return {
|
||||||
|
padding: '30rpx',
|
||||||
|
gridRows: 1,
|
||||||
|
gridColumns: 1,
|
||||||
|
gridRowsGap: '50rpx',
|
||||||
|
gridColumnsGap: '24rpx',
|
||||||
|
itemDirection: 'row',
|
||||||
|
itemGap: '30rpx',
|
||||||
|
itemAlign: 'flex-start',
|
||||||
|
headShow: true,
|
||||||
|
headWidth: '100rpx',
|
||||||
|
headHeight: '100rpx',
|
||||||
|
headBorderRadius: '50%',
|
||||||
|
textShow: true,
|
||||||
|
textRows: 4,
|
||||||
|
textRowsGap: '30rpx',
|
||||||
|
textWidth: ['50%', '100%', '100%', '80%'],
|
||||||
|
textHeight: ['40rpx', '24rpx', '24rpx', '24rpx'],
|
||||||
|
textBorderRadius: '6rpx',
|
||||||
|
...this.configs
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
textConfigs() {
|
||||||
|
return {
|
||||||
|
padding: '30rpx',
|
||||||
|
gridRows: 1,
|
||||||
|
gridColumns: 1,
|
||||||
|
gridRowsGap: '50rpx',
|
||||||
|
gridColumnsGap: '24rpx',
|
||||||
|
itemDirection: 'row',
|
||||||
|
itemGap: '30rpx',
|
||||||
|
itemAlign: 'flex-start',
|
||||||
|
headShow: false,
|
||||||
|
headWidth: '100rpx',
|
||||||
|
headHeight: '100rpx',
|
||||||
|
headBorderRadius: '50%',
|
||||||
|
textShow: true,
|
||||||
|
textRows: 4,
|
||||||
|
textRowsGap: '30rpx',
|
||||||
|
textWidth: ['50%', '100%', '100%', '80%'],
|
||||||
|
textHeight: '30rpx',
|
||||||
|
textBorderRadius: '6rpx',
|
||||||
|
...this.configs
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
menuConfigs() {
|
||||||
|
return {
|
||||||
|
padding: '30rpx',
|
||||||
|
gridRows: 2,
|
||||||
|
gridColumns: 5,
|
||||||
|
gridRowsGap: '40rpx',
|
||||||
|
gridColumnsGap: '40rpx',
|
||||||
|
itemDirection: 'column',
|
||||||
|
itemGap: '16rpx',
|
||||||
|
itemAlign: 'center',
|
||||||
|
headShow: true,
|
||||||
|
headWidth: '100rpx',
|
||||||
|
headHeight: '100rpx',
|
||||||
|
headBorderRadius: '50%',
|
||||||
|
textShow: true,
|
||||||
|
textRows: 1,
|
||||||
|
textRowsGap: '0rpx',
|
||||||
|
textWidth: '100%',
|
||||||
|
textHeight: '24rpx',
|
||||||
|
textBorderRadius: '6rpx',
|
||||||
|
...this.configs
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
listConfigs() {
|
||||||
|
return {
|
||||||
|
padding: '30rpx',
|
||||||
|
gridRows: 2,
|
||||||
|
gridColumns: 1,
|
||||||
|
gridRowsGap: '50rpx',
|
||||||
|
gridColumnsGap: '24rpx',
|
||||||
|
itemDirection: 'row',
|
||||||
|
itemGap: '30rpx',
|
||||||
|
itemAlign: 'flex-start',
|
||||||
|
headShow: true,
|
||||||
|
headWidth: '200rpx',
|
||||||
|
headHeight: '200rpx',
|
||||||
|
headBorderRadius: '16rpx',
|
||||||
|
textShow: true,
|
||||||
|
textRows: 4,
|
||||||
|
textRowsGap: '30rpx',
|
||||||
|
textWidth: ['50%', '100%', '100%', '80%'],
|
||||||
|
textHeight: ['38rpx', '24rpx', '24rpx', '24rpx'],
|
||||||
|
textBorderRadius: '6rpx',
|
||||||
|
...this.configs
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
waterfallConfigs() {
|
||||||
|
return {
|
||||||
|
padding: '30rpx',
|
||||||
|
gridRows: 2,
|
||||||
|
gridColumns: 2,
|
||||||
|
gridRowsGap: '40rpx',
|
||||||
|
gridColumnsGap: '24rpx',
|
||||||
|
itemDirection: 'column',
|
||||||
|
itemGap: '16rpx',
|
||||||
|
itemAlign: 'center',
|
||||||
|
headShow: true,
|
||||||
|
headWidth: '100%',
|
||||||
|
headHeight: '400rpx',
|
||||||
|
headBorderRadius: '12rpx',
|
||||||
|
textShow: true,
|
||||||
|
textRows: 3,
|
||||||
|
textRowsGap: '12rpx',
|
||||||
|
textWidth: ['40%', '85%', '60%'],
|
||||||
|
textHeight: ['30rpx', '20rpx', '20rpx'],
|
||||||
|
textBorderRadius: '6rpx',
|
||||||
|
...this.configs
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,324 @@
|
||||||
|
<template>
|
||||||
|
<view class="x-skeleton" :style="variableStr">
|
||||||
|
<!-- 骨架屏 -->
|
||||||
|
<view
|
||||||
|
v-if="skeletonLoading"
|
||||||
|
class="x-skeleton__wrapper"
|
||||||
|
:class="[ startFadeOut && 'fade-out' ]"
|
||||||
|
:style="{ padding: skeletonConfigs.padding }"
|
||||||
|
>
|
||||||
|
<view
|
||||||
|
v-for="(row, rowIndex) in gridRowsArr" :key="rowIndex"
|
||||||
|
class="x-skeleton__wrapper__rows"
|
||||||
|
:style="{ marginBottom: rowIndex < gridRowsArr.length - 1 ? skeletonConfigs.gridRowsGap : 0 }"
|
||||||
|
>
|
||||||
|
<view
|
||||||
|
v-for="(column, columnIndex) in gridColumnsArr" :key="columnIndex"
|
||||||
|
class="x-skeleton__wrapper__columns"
|
||||||
|
:style="{
|
||||||
|
flexDirection: skeletonConfigs.itemDirection,
|
||||||
|
alignItems: skeletonConfigs.itemAlign,
|
||||||
|
marginRight: columnIndex < gridColumnsArr.length - 1 ? skeletonConfigs.gridColumnsGap : 0,
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<view
|
||||||
|
v-if="skeletonConfigs.headShow"
|
||||||
|
class="x-skeleton__wrapper__head"
|
||||||
|
:class="[ animate && 'animate' ]"
|
||||||
|
:style="{
|
||||||
|
width: skeletonConfigs.headWidth,
|
||||||
|
height: skeletonConfigs.headHeight,
|
||||||
|
borderRadius: skeletonConfigs.headBorderRadius,
|
||||||
|
marginRight: (skeletonConfigs.itemDirection == 'row' && skeletonConfigs.textShow) ? skeletonConfigs.itemGap : 0,
|
||||||
|
marginBottom: (skeletonConfigs.itemDirection == 'column' && skeletonConfigs.textShow) ? skeletonConfigs.itemGap : 0
|
||||||
|
}"
|
||||||
|
></view>
|
||||||
|
<view v-if="skeletonConfigs.textShow" class="x-skeleton__wrapper__text">
|
||||||
|
<view
|
||||||
|
v-for="(text, textIndex) in textRowsArr" :key="textIndex"
|
||||||
|
class="x-skeleton__wrapper__text__row"
|
||||||
|
:class="[animate && 'animate']"
|
||||||
|
:style="{
|
||||||
|
width: text.width,
|
||||||
|
height: text.height,
|
||||||
|
borderRadius: skeletonConfigs.textBorderRadius,
|
||||||
|
marginBottom: textIndex < textRowsArr.length - 1 ? skeletonConfigs.textRowsGap : 0
|
||||||
|
}"
|
||||||
|
></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!-- 插槽 -->
|
||||||
|
<view v-else>
|
||||||
|
<slot></slot>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import XSkeletonConfigs from './x-skeleton-configs.js'
|
||||||
|
export default {
|
||||||
|
name: "x-skeleton",
|
||||||
|
mixins: [ XSkeletonConfigs ],
|
||||||
|
props: {
|
||||||
|
// 骨架屏类型
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: '' //banner轮播图、info个人信息、text段落、menu菜单、list列表、waterfall瀑布流
|
||||||
|
},
|
||||||
|
// 是否展示骨架组件
|
||||||
|
loading: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
// 是否开启动画效果
|
||||||
|
animate: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
// 动画效果持续时间,单位秒
|
||||||
|
animateTime: {
|
||||||
|
type: Number | String,
|
||||||
|
default: 1.8
|
||||||
|
},
|
||||||
|
// 是否开启淡出动画
|
||||||
|
fadeOut: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
// 淡出效果持续时间,单位秒
|
||||||
|
fadeOutTime: {
|
||||||
|
type: Number | String,
|
||||||
|
default: 0.5
|
||||||
|
},
|
||||||
|
// 骨架的背景色
|
||||||
|
bgColor: {
|
||||||
|
type: String,
|
||||||
|
default: '#EAEDF5'
|
||||||
|
},
|
||||||
|
// 骨架的动画高亮背景色
|
||||||
|
highlightBgColor: {
|
||||||
|
type: String,
|
||||||
|
default: '#F9FAFF'
|
||||||
|
},
|
||||||
|
// 自定义配置
|
||||||
|
configs: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {
|
||||||
|
return {
|
||||||
|
// padding: '30rpx', //内边距
|
||||||
|
// gridRows: 3, //行数
|
||||||
|
// gridColumns: 2, //列数
|
||||||
|
// gridRowsGap: '40rpx', //行间隔
|
||||||
|
// gridColumnsGap: '24rpx', //竖间距
|
||||||
|
// itemDirection: 'column', //head与text之间的排列方向(row、column)
|
||||||
|
// itemGap: '16rpx', //head与text之间的间隔
|
||||||
|
// itemAlign: 'center', //head与text之间的纵轴对齐方式(center、flex-start、flex-end、baseline)
|
||||||
|
// headShow: true, //head是否展示
|
||||||
|
// headWidth: '100%', //head宽度,支持百分比
|
||||||
|
// headHeight: '400rpx', //head高度
|
||||||
|
// headBorderRadius: '12rpx', //head圆角,支持百分比
|
||||||
|
// textShow: true, //文本是否展示
|
||||||
|
// textRows: 3, //文本的行数
|
||||||
|
// textRowsGap: '12rpx', //文本间距
|
||||||
|
// textWidth: ['40%', '85%', '60%'], //文本的宽度,可以为百分比,数值,带单位字符串等,可通过数组传入指定每个段落行的宽度
|
||||||
|
// textHeight: ['30rpx', '20rpx', '20rpx'], //文本的高度,可以为数值,带单位字符串等,可通过数组传入指定每个段落行的高度
|
||||||
|
// textBorderRadius: '6rpx', //文本的圆角,支持百分比
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
gridRowsArr() {
|
||||||
|
return new Array(Number(this.skeletonConfigs?.gridRows || []));
|
||||||
|
},
|
||||||
|
gridColumnsArr() {
|
||||||
|
return new Array(Number(this.skeletonConfigs?.gridColumns || []));
|
||||||
|
},
|
||||||
|
textRowsArr() {
|
||||||
|
if (!this.skeletonConfigs?.textShow) return [];
|
||||||
|
if (/%$/.test(this.skeletonConfigs.textHeight)) {
|
||||||
|
console.error('x-skeleton: textHeight参数不支持百分比单位');
|
||||||
|
}
|
||||||
|
const rows = []
|
||||||
|
for (let i = 0; i < this.skeletonConfigs.textRows; i++) {
|
||||||
|
const { gridRows, textWidth, textHeight } = this.skeletonConfigs;
|
||||||
|
let item = {},
|
||||||
|
// 需要预防超出数组边界的情况
|
||||||
|
rowWidth = this.isArray(textWidth) ? (textWidth[i] || (i === gridRows - 1 ? '70%' : '100%')) : i === gridRows - 1 ? '70%' : textWidth,
|
||||||
|
rowHeight = this.isArray(textHeight) ? (textHeight[i] || '30rpx') : textHeight
|
||||||
|
// 非百分比的宽度时,调整像素单位
|
||||||
|
if (/%$/.test(rowWidth)) {
|
||||||
|
item.width = rowWidth;
|
||||||
|
} else {
|
||||||
|
item.width = this.addUnit(rowWidth)
|
||||||
|
}
|
||||||
|
item.height = this.addUnit(rowHeight)
|
||||||
|
rows.push(item)
|
||||||
|
}
|
||||||
|
return rows
|
||||||
|
},
|
||||||
|
variableStr() {
|
||||||
|
let keys = ['animateTime', 'fadeOutTime', 'bgColor', 'highlightBgColor'];
|
||||||
|
let str = keys.map(item => {
|
||||||
|
if (item.indexOf('Time') > -1) {
|
||||||
|
return `--${item}:${this[item]}s`
|
||||||
|
} else {
|
||||||
|
return `--${item}:${this[item]}`
|
||||||
|
}
|
||||||
|
}).join(";");
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
loading: {
|
||||||
|
immediate: true,
|
||||||
|
handler(value) {
|
||||||
|
if (value) {
|
||||||
|
this.skeletonLoading = true;
|
||||||
|
} else {
|
||||||
|
if (this.fadeOut) {
|
||||||
|
this.startFadeOut = true;
|
||||||
|
setTimeout(() => {
|
||||||
|
this.skeletonLoading = false;
|
||||||
|
this.startFadeOut = false;
|
||||||
|
}, this.fadeOutTime * 1000);
|
||||||
|
} else {
|
||||||
|
this.skeletonLoading = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
immediate: true,
|
||||||
|
handler(value) {
|
||||||
|
if (value === 'banner') {
|
||||||
|
this.skeletonConfigs = this.bannerConfigs();
|
||||||
|
} else if (value === 'info') {
|
||||||
|
this.skeletonConfigs = this.infoConfigs();
|
||||||
|
} else if (value === 'text') {
|
||||||
|
this.skeletonConfigs = this.textConfigs();
|
||||||
|
} else if (value === 'menu') {
|
||||||
|
this.skeletonConfigs = this.menuConfigs();
|
||||||
|
} else if (value === 'list') {
|
||||||
|
this.skeletonConfigs = this.listConfigs();
|
||||||
|
} else if (value === 'waterfall') {
|
||||||
|
this.skeletonConfigs = this.waterfallConfigs();
|
||||||
|
} else {
|
||||||
|
this.skeletonConfigs = this.configs || {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
skeletonConfigs: this.configs || {},
|
||||||
|
skeletonLoading: this.loading,
|
||||||
|
startFadeOut: false,
|
||||||
|
width: 0
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
/**
|
||||||
|
* @description 是否为数组
|
||||||
|
* @param {object} value 需要判断的对象
|
||||||
|
*/
|
||||||
|
isArray(value) {
|
||||||
|
if (typeof Array.isArray === 'function') {
|
||||||
|
return Array.isArray(value)
|
||||||
|
}
|
||||||
|
return Object.prototype.toString.call(value) === '[object Array]'
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 添加单位,如果有rpx,upx,%,px等单位结尾或者值为auto,直接返回,否则加上px单位结尾
|
||||||
|
* @param {string|number} value 需要添加单位的值
|
||||||
|
* @param {string} unit 添加的单位名 比如px
|
||||||
|
*/
|
||||||
|
addUnit(value = 'auto', unit = 'px') {
|
||||||
|
value = String(value);
|
||||||
|
// 用uView内置验证规则中的number判断是否为数值
|
||||||
|
return /^[\+-]?(\d+\.?\d*|\.\d+|\d\.\d+e\+\d+)$/.test(value) ? `${value}${unit}` : value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@mixin background {
|
||||||
|
background: linear-gradient(90deg, var(--bgColor) 25%, var(--highlightBgColor) 37%, var(--bgColor) 50%);
|
||||||
|
background-size: 400% 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.x-skeleton {
|
||||||
|
width: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
.x-skeleton__wrapper {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
&__rows {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__columns {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__head {
|
||||||
|
width: 100%;
|
||||||
|
@include background;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__text {
|
||||||
|
flex: 1;
|
||||||
|
width: 100%;
|
||||||
|
&__row {
|
||||||
|
@include background;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-out {
|
||||||
|
opacity: 0;
|
||||||
|
animation: fadeOutAnim var(--fadeOutTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fadeOutAnim {
|
||||||
|
from {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate {
|
||||||
|
animation: skeletonAnim var(--animateTime) ease infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes skeletonAnim {
|
||||||
|
0% {
|
||||||
|
background-position: 100% 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
background-position: 0 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,84 @@
|
||||||
|
{
|
||||||
|
"id": "x-skeleton",
|
||||||
|
"displayName": "skeleton骨架屏(可任意配置-易用-灵活-动画)",
|
||||||
|
"version": "1.0.4",
|
||||||
|
"description": "x-skeleton骨架屏可随意配置内容,扩展性强,简单易用,内含常用的骨架类型",
|
||||||
|
"keywords": [
|
||||||
|
"skeleton",
|
||||||
|
"骨架屏",
|
||||||
|
"加载效果",
|
||||||
|
"vue",
|
||||||
|
"微信小程序"
|
||||||
|
],
|
||||||
|
"repository": "",
|
||||||
|
"engines": {
|
||||||
|
},
|
||||||
|
"dcloudext": {
|
||||||
|
"type": "component-vue",
|
||||||
|
"sale": {
|
||||||
|
"regular": {
|
||||||
|
"price": "0.00"
|
||||||
|
},
|
||||||
|
"sourcecode": {
|
||||||
|
"price": "0.00"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"contact": {
|
||||||
|
"qq": ""
|
||||||
|
},
|
||||||
|
"declaration": {
|
||||||
|
"ads": "无",
|
||||||
|
"data": "插件不采集任何数据",
|
||||||
|
"permissions": "无"
|
||||||
|
},
|
||||||
|
"npmurl": ""
|
||||||
|
},
|
||||||
|
"uni_modules": {
|
||||||
|
"dependencies": [],
|
||||||
|
"encrypt": [],
|
||||||
|
"platforms": {
|
||||||
|
"cloud": {
|
||||||
|
"tcb": "y",
|
||||||
|
"aliyun": "y"
|
||||||
|
},
|
||||||
|
"client": {
|
||||||
|
"Vue": {
|
||||||
|
"vue2": "y",
|
||||||
|
"vue3": "u"
|
||||||
|
},
|
||||||
|
"App": {
|
||||||
|
"app-vue": "u",
|
||||||
|
"app-nvue": "u"
|
||||||
|
},
|
||||||
|
"H5-mobile": {
|
||||||
|
"Safari": "u",
|
||||||
|
"Android Browser": "u",
|
||||||
|
"微信浏览器(Android)": "u",
|
||||||
|
"QQ浏览器(Android)": "u"
|
||||||
|
},
|
||||||
|
"H5-pc": {
|
||||||
|
"Chrome": "y",
|
||||||
|
"IE": "y",
|
||||||
|
"Edge": "y",
|
||||||
|
"Firefox": "y",
|
||||||
|
"Safari": "u"
|
||||||
|
},
|
||||||
|
"小程序": {
|
||||||
|
"微信": "y",
|
||||||
|
"阿里": "u",
|
||||||
|
"百度": "u",
|
||||||
|
"字节跳动": "u",
|
||||||
|
"QQ": "u",
|
||||||
|
"钉钉": "u",
|
||||||
|
"快手": "u",
|
||||||
|
"飞书": "u",
|
||||||
|
"京东": "u"
|
||||||
|
},
|
||||||
|
"快应用": {
|
||||||
|
"华为": "u",
|
||||||
|
"联盟": "u"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,93 @@
|
||||||
|
# x-skeleton
|
||||||
|
|
||||||
|
# 功能介绍
|
||||||
|
- 支持 H5、微信小程序,其他端未测试过
|
||||||
|
- 使用简单、灵活,高度自定义
|
||||||
|
- 加载时支持动画
|
||||||
|
- 消失时加了动画,不再生硬切换页面
|
||||||
|
- 支持绝大部分常用场景:
|
||||||
|
1、轮播图
|
||||||
|
2、个人信息
|
||||||
|
3、段落
|
||||||
|
4、菜单
|
||||||
|
5、列表
|
||||||
|
6、瀑布流
|
||||||
|
7、自定义...
|
||||||
|
|
||||||
|
# 属性说明
|
||||||
|
|
||||||
|
| 参数 | 说明 | 类型 | 默认值 | 可选值 |
|
||||||
|
| ------- | --------------------------------------------------- | ------- | ------ | --- |
|
||||||
|
| type | 骨架类型,为空时是完全自定义 | String | - |banner轮播图、info个人信息、text段落、menu菜单、list列表、waterfall瀑布流|
|
||||||
|
| loading | 是否显示骨架占位图,设置为false将会展示子组件内容 | Boolean | true |true、false|
|
||||||
|
| animate | 是否开启动画效果 | Boolean | true |true、false|
|
||||||
|
| animateTime | 动画效果持续时间,单位秒 | Number \| String | 1.8 |-|
|
||||||
|
| fadeOut | 是否开启淡出动画 | Boolean | true |true、false|
|
||||||
|
| fadeOutTime | 淡出效果持续时间,单位秒 | Number \| String | 0.5 |-|
|
||||||
|
| bgColor | 骨架的背景色 | String | #EAEDF5 |-|
|
||||||
|
| highlightBgColor | 骨架的动画高亮背景色 | String | #F9FAFF |-|
|
||||||
|
| configs | 自定义配置,具体看下方 | Object | {} |-|
|
||||||
|
|
||||||
|
## configs参数说明
|
||||||
|
|
||||||
|
| 参数 | 说明 | 类型 |
|
||||||
|
| ------- | --------------------------------------------------- | ------- |
|
||||||
|
| padding | 骨架内边距,同 css 的 padding | String |
|
||||||
|
| gridRows | 行数 | Number |
|
||||||
|
| gridColumns | 列数 | Number |
|
||||||
|
| gridRowsGap | 行间隔 | String |
|
||||||
|
| gridColumnsGap | 竖间距 | String |
|
||||||
|
| itemDirection | head与text之间的排列方向(row、column) | String |
|
||||||
|
| itemGap | head与text之间的间隔 | String |
|
||||||
|
| itemAlign | head与text之间的纵轴对齐方式,同 flex 的align-items(center、flex-start、flex-end等) | String |
|
||||||
|
| headShow | head是否展示 | Boolean |
|
||||||
|
| headWidth | head宽度,支持百分比 | String |
|
||||||
|
| headHeight | head高度 | String |
|
||||||
|
| headBorderRadius | head圆角,支持百分比 | String |
|
||||||
|
| textShow | text是否展示 | Boolean |
|
||||||
|
| textRows | text的行数 | Number |
|
||||||
|
| textRowsGap | text间距 | String |
|
||||||
|
| textWidth | text的宽度,可以为百分比,数值,带单位字符串等,可通过数组传入指定每个段落行的宽度 | String \| Array \| Number |
|
||||||
|
| textHeight | text的高度,可以为数值,带单位字符串等,可通过数组传入指定每个段落行的高度 | String \| Array \| Number |
|
||||||
|
| textBorderRadius | text的圆角,支持百分比 | String |
|
||||||
|
|
||||||
|
大部分情况下,直接指定相应的 type 已经够用了,如果大家想进行样式的微调、完全自定义可通过设置 configs 来实现。
|
||||||
|
|
||||||
|
简单解释一下这些参数(右边有结构布局图示):
|
||||||
|
|
||||||
|
布局总共分成 4 块,分别是 grid、item、head、text。
|
||||||
|
|
||||||
|
1、grid:包含 item,指定每一行有多少个 item,每一列有多少个 item
|
||||||
|
|
||||||
|
2、item:包含 head、text,可设置他们之间的排列方式、间距
|
||||||
|
|
||||||
|
3、head:一个 item 只有一个 head,可设置宽高、圆角
|
||||||
|
|
||||||
|
4、text:一个 item 可以有多行 text,可分别设置宽高、圆角、间距
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# 使用示例
|
||||||
|
|
||||||
|
```html
|
||||||
|
<x-skeleton type="banner" :loading="loading">
|
||||||
|
<view>我是轮播图</view>
|
||||||
|
</x-skeleton>
|
||||||
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
loading: true,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onLoad() {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.loading = false;
|
||||||
|
}, 2000);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
更多用法请下载查看示例代码,有问题可以留言
|
||||||
Loading…
Reference in New Issue