From da25434b85fc5b4321c429bf95e719d00ec395bb Mon Sep 17 00:00:00 2001 From: quanyawei <401863037@qq.com> Date: Thu, 11 Jan 2024 16:21:16 +0800 Subject: [PATCH] 定位优化 --- uni_modules/uview-ui/components/u-skeleton/u-skeleton.vue | 244 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 244 insertions(+), 0 deletions(-) diff --git a/uni_modules/uview-ui/components/u-skeleton/u-skeleton.vue b/uni_modules/uview-ui/components/u-skeleton/u-skeleton.vue new file mode 100644 index 0000000..efa649e --- /dev/null +++ b/uni_modules/uview-ui/components/u-skeleton/u-skeleton.vue @@ -0,0 +1,244 @@ +<template> + <view class="u-skeleton"> + <view + class="u-skeleton__wrapper" + ref="u-skeleton__wrapper" + v-if="loading" + style="display: flex; flex-direction: row;" + > + <view + class="u-skeleton__wrapper__avatar" + v-if="avatar" + :class="[`u-skeleton__wrapper__avatar--${avatarShape}`, animate && 'animate']" + :style="{ + height: $u.addUnit(avatarSize), + width: $u.addUnit(avatarSize) + }" + ></view> + <view + class="u-skeleton__wrapper__content" + ref="u-skeleton__wrapper__content" + style="flex: 1;" + > + <view + class="u-skeleton__wrapper__content__title" + v-if="title" + :style="{ + width: uTitleWidth, + height: $u.addUnit(titleHeight), + }" + :class="[animate && 'animate']" + ></view> + <view + class="u-skeleton__wrapper__content__rows" + :class="[animate && 'animate']" + v-for="(item, index) in rowsArray" + :key="index" + :style="{ + width: item.width, + height: item.height, + marginTop: item.marginTop + }" + > + + </view> + </view> + </view> + <slot v-else /> + </view> +</template> + +<script> + import props from './props.js'; + // #ifdef APP-NVUE + // ������weex������������KPI���������������������������������������������������������������������������dom��������������������� + const dom = uni.requireNativePlugin('dom') + const animation = uni.requireNativePlugin('animation') + // #endif + /** + * Skeleton ��������� + * @description ������������������������������������������������������������������������������������������������������������������������������������������������ + * @tutorial https://www.uviewui.com/components/skeleton.html + * @property {Boolean} loading ���������������������������������������false��������������������������� (������ true ) + * @property {Boolean} animate ������������������������ (������ true ) + * @property {String | Number} rows ��������������������� (������ 0 ) + * @property {String | Number | Array} rowsWidth ������������������������������������������������������������������������������������������������������������������������������������ (������ '100%' ) + * @property {String | Number | Array} rowsHeight ��������������� (������ 18 ) + * @property {Boolean} title ��������������������������� (������ true ) + * @property {String | Number} titleWidth ��������������� (������ '50%' ) + * @property {String | Number} titleHeight ��������������� (������ 18 ) + * @property {Boolean} avatar ��������������������������� (������ false ) + * @property {String | Number} avatarSize ��������������������� (������ 32 ) + * @property {String} avatarShape ���������������������������circle-���������square-������ (������ 'circle' ) + * @example <u-search placeholder="���������������������" v-model="keyword"></u-search> + */ + export default { + name: 'u-skeleton', + mixins: [uni.$u.mpMixin, uni.$u.mixin, props], + data() { + return { + width: 0, + } + }, + watch: { + loading() { + this.getComponentWidth() + } + }, + computed: { + rowsArray() { + if (/%$/.test(this.rowsHeight)) { + uni.$u.error('rowsHeight������������������������������') + } + const rows = [] + for (let i = 0; i < this.rows; i++) { + let item = {}, + // ��������������������������������������� + rowWidth = uni.$u.test.array(this.rowsWidth) ? (this.rowsWidth[i] || (i === this.row - 1 ? '70%' : '100%')) : i === + this.rows - 1 ? '70%' : this.rowsWidth, + rowHeight = uni.$u.test.array(this.rowsHeight) ? (this.rowsHeight[i] || '18px') : this.rowsHeight + // ���������title������������������������������������������������������������������������������title������������������������������������������������������ + // ������������������������������������weex���������������������������������������������css��������������� + item.marginTop = !this.title && i === 0 ? 0 : this.title && i === 0 ? '20px' : '12px' + // ������������������������������������������������px������������nvue������������������������ + if (/%$/.test(rowWidth)) { + // ������parseInt���������������������������������������������������100��������������������������� + item.width = uni.$u.addUnit(this.width * parseInt(rowWidth) / 100) + } else { + item.width = uni.$u.addUnit(rowWidth) + } + item.height = uni.$u.addUnit(rowHeight) + rows.push(item) + } + // console.log(rows); + return rows + }, + uTitleWidth() { + let tWidth = 0 + if (/%$/.test(this.titleWidth)) { + // ������parseInt���������������������������������������������������100��������������������������� + tWidth = uni.$u.addUnit(this.width * parseInt(this.titleWidth) / 100) + } else { + tWidth = uni.$u.addUnit(this.titleWidth) + } + return uni.$u.addUnit(tWidth) + }, + + }, + mounted() { + this.init() + }, + methods: { + init() { + this.getComponentWidth() + // #ifdef APP-NVUE + this.loading && this.animate && this.setNvueAnimation() + // #endif + }, + async setNvueAnimation() { + // #ifdef APP-NVUE + // ���������opacity:1��������������������������������������������������� + await uni.$u.sleep(500) + const skeleton = this.$refs['u-skeleton__wrapper']; + skeleton && this.loading && this.animate && animation.transition(skeleton, { + styles: { + opacity: 0.5 + }, + duration: 600, + }, () => { + // ������������������������loading���������������������������������������������������������opacity: 1��������������� + // ������������opacity: 0.5������������ + animation.transition(skeleton, { + styles: { + opacity: 1 + }, + duration: 600, + }, () => { + // ���������loading������������������������ + this.loading && this.animate && this.setNvueAnimation() + }) + }) + // #endif + }, + // ��������������������� + async getComponentWidth() { + // ������������������������������dom������ + await uni.$u.sleep(20) + // #ifndef APP-NVUE + this.$uGetRect('.u-skeleton__wrapper__content').then(size => { + this.width = size.width + }) + // #endif + + // #ifdef APP-NVUE + const ref = this.$refs['u-skeleton__wrapper__content'] + ref && dom.getComponentRect(ref, (res) => { + this.width = res.size.width + }) + // #endif + } + } + } +</script> + +<style lang="scss" scoped> + @import "../../libs/css/components.scss"; + + @mixin background { + /* #ifdef APP-NVUE */ + background-color: #F1F2F4; + /* #endif */ + /* #ifndef APP-NVUE */ + background: linear-gradient(90deg, #F1F2F4 25%, #e6e6e6 37%, #F1F2F4 50%); + background-size: 400% 100%; + /* #endif */ + } + + .u-skeleton { + flex: 1; + + &__wrapper { + @include flex(row); + + &__avatar { + @include background; + margin-right: 15px; + + &--circle { + border-radius: 100px; + } + + &--square { + border-radius: 4px; + } + } + + &__content { + flex: 1; + + &__rows, + &__title { + @include background; + border-radius: 3px; + } + } + } + } + + /* #ifndef APP-NVUE */ + .animate { + animation: skeleton 1.8s ease infinite + } + + @keyframes skeleton { + 0% { + background-position: 100% 50% + } + + 100% { + background-position: 0 50% + } + } + + /* #endif */ +</style> -- Gitblit v1.8.0