HBuilderX

HBuilderX

极客开发工具
uni-app

uni-app

开发一次,多端覆盖
uniCloud

uniCloud

云开发平台
HTML5+

HTML5+

增强HTML5的功能体验
MUI

MUI

上万Star的前端框架

Stack组件实现Swiper堆叠动画效果

问题现象
Swiper如何实现卡片堆叠样式:

上下堆叠:Swiper内容像卡片堆叠,在底部留部分空间显示下一页的内容,上下滑实现卡片切换。
左右堆叠:Swiper内容像卡片堆叠,在右侧留部分空间显示下一页的内容,左右滑实现卡片切换。
背景知识
Swiper组件提供滑动轮播显示的能力。Swiper本身是一个容器组件,当设置了多个子组件后,可以对这些子组件进行轮播显示。
Stack是堆叠容器,子组件按照顺序依次入栈,后一个子组件覆盖前一个子组件。
gesture可以为组件绑定手势方法进行相应处理,如滑动手势事件PanGesture。
animateTo指定由于闭包代码导致的状态变化插入过渡动效。
解决方案
上下堆叠实现。
自定义实现卡片堆叠的组件:使用Stack组件堆叠需要展示的图片,设置最上面的图片向上偏移部分距离,露出下一张图片的底部。为Stack绑定上下滑动的手势处理,实现切换图片逻辑,同时使用animateTo接口设置图片切换动画。

export class SwiperData {
imageSrc: Resource;

constructor(imageSrc: Resource) {
this.imageSrc = imageSrc;
}
}

@Component
export struct SwiperStackComponent {
@Link currentIndex: number;
@Prop swiperData: SwiperData[];
private halfCount: number = Math.floor(3 / 2);
private automaticSlidingDuration: number = 300;

aboutToAppear(): void {
this.currentIndex = 0;
}

// 修改堆叠方向系数计算
getImgCoefficients(index: number): number {
const coefficient = this.currentIndex - index;
const tempCoefficient = Math.abs(coefficient);
if (tempCoefficient <= this.halfCount) {
return coefficient;
}
const dataLength = this.swiperData.length;
let tempOffset = dataLength - tempCoefficient;
if (tempOffset <= this.halfCount) {
return coefficient > 0 ? -tempOffset : tempOffset;
}
return 0;
}

// 修改堆叠方向偏移量计算
getOffSet(index: number): number {
let offsetIndex = this.getImgCoefficients(index);
const tempOffset = Math.abs(offsetIndex);
let offset = 0;
if (tempOffset === 1) {
if (offsetIndex === 1) {
offsetIndex = -1;
}
offset = 50 * offsetIndex;
}
return -offset;
}

startAnimation(isLeft: boolean, duration: number): void {
this.getUIContext().animateTo({ duration: duration, }, () => {
const dataLength: number = this.swiperData.length;
const tempIndex: number = isLeft ? this.currentIndex + 1 : this.currentIndex - 1 + dataLength;
this.currentIndex = tempIndex % dataLength;
});
}

build() {
Stack() {
ForEach(this.swiperData, (item: SwiperData, index: number) => {
Stack({ alignContent: Alignment.Bottom }) {
Image(item.imageSrc)
.objectFit(ImageFit.Cover)
.width('100%')
.height('100%')
.borderRadius(8);
}
.offset({ x: 0, y: this.getOffSet(index) })
.shadow(ShadowStyle.OUTER_DEFAULT_SM)
.backgroundColor(Color.White)
.borderRadius(8)
.blur(index !== this.currentIndex ? 12 : 0)
// 通过animateTo实现动画并且同时改变currentIndex数据中间值来判断组件zIndex实现切换动画
.zIndex(index !== this.currentIndex && this.getImgCoefficients(index) === 0 ?
0 : 2 - Math.abs(this.getImgCoefficients(index)))
.width(310)
.height(index !== this.currentIndex ? 130 : 180);
});
}
.height(200)
.width('100%')
.gesture(
PanGesture({ direction: PanDirection.Vertical })
.onActionStart((event: GestureEvent) => {
this.startAnimation(event.offsetY < 0, this.automaticSlidingDuration);
})
)
.alignContent(Alignment.Center)
.padding({ left: 12, right: 12, top: 12 });
}
}
在页面中直接使用上面封装好的SwiperStackComponent即可,示例如下:传给SwiperStackComponent要堆叠的图片。
https://pastebin.com/m1LSXzRK
https://pastebin.com/cFaDz2JM
https://pastebin.com/94NrGTMh
https://pastebin.com/Yjx17LeK
https://pastebin.com/LqsPJ96h
https://pastebin.com/DPDgXMvK
https://pastebin.com/hSjsmXQA
https://pastebin.com/uKP1SMUS
https://pastebin.com/NzZpsC1T
https://pastebin.com/YYRMvbNK
https://pastebin.com/yMGLZhE6
https://pastebin.com/S95qV0Uz
https://pastebin.com/KkbjxT3u
https://pastebin.com/KtDaV8W6
https://pastebin.com/StWuCs6Y
https://pastebin.com/P1C46HUd
https://pastebin.com/jQVY68MF
https://pastebin.com/pZWdw2nr
https://pastebin.com/hWvq20CX
https://pastebin.com/6gYgutXU
https://pastebin.com/U4bchZ6m
https://pastebin.com/gfaWG0r6
https://pastebin.com/e9Y0r65R
https://pastebin.com/TVxKvWAq
https://pastebin.com/XQf3dgCp
https://pastebin.com/DpcrwpV5
https://pastebin.com/ebTwvrA8
https://pastebin.com/9AVaZHpP
https://pastebin.com/0XNziuPN
https://pastebin.com/5pX3w9Qz
https://pastebin.com/LxBeC4wT
https://pastebin.com/Ts4YH8YT
https://pastebin.com/gtTcZ7WL
https://pastebin.com/9hCAm4pk
https://pastebin.com/ivQAv3W6
https://pastebin.com/kQkScYnm
https://pastebin.com/Pggf2AJf
https://pastebin.com/93YQXuS2
https://pastebin.com/8bT7ebcm
https://pastebin.com/qhwZL1PA
https://pastebin.com/1j9Dfhf3
https://pastebin.com/yr8G62Eb
https://pastebin.com/i6keBveX
https://pastebin.com/8cShExkL
https://pastebin.com/uRpXa4D8
https://pastebin.com/GCWXMvkV
https://pastebin.com/5r8kkafj
https://pastebin.com/gZqmkKFY
https://pastebin.com/uzX4RXb8
https://pastebin.com/NX85Yeya
https://pastebin.com/0bnHmnn1
https://pastebin.com/4TEuJiyp
https://pastebin.com/19ECBLgF
https://pastebin.com/Q6sXfyLu
https://pastebin.com/J3wkaGhA
https://pastebin.com/MV4f7R1P
https://pastebin.com/4dtFguZU
https://pastebin.com/adNJrURC
https://pastebin.com/aTtEKzis
https://pastebin.com/PQrg1GWd
https://pastebin.com/gKTKwvqf
https://pastebin.com/uuYPPvaA
https://pastebin.com/j4Ls35Kc
https://pastebin.com/E0Ukv7Aj
https://pastebin.com/f6k4t5u2
https://pastebin.com/Q1DXAxWt
https://pastebin.com/tjfUhr1N
https://pastebin.com/uU5iHdYy
https://pastebin.com/cRR3KhUL
https://pastebin.com/nCiKrKtB
https://pastebin.com/dSHVsFy0
https://pastebin.com/2XAKUkn6
https://pastebin.com/Jppiihgb
https://pastebin.com/h3yaiqzz
https://pastebin.com/2JWDAsub
https://pastebin.com/tmPvc6uP
https://pastebin.com/FUnWQQwV
https://pastebin.com/Gp2UtxKN
https://pastebin.com/h95wHCfg
https://pastebin.com/fsCpD2Z8
https://pastebin.com/zJr9HCpS
https://pastebin.com/0PvFpNur
https://pastebin.com/VJyawuD5
https://pastebin.com/ba848eTS
https://pastebin.com/RACk8XWR
https://pastebin.com/0hwQHBAn
https://pastebin.com/sm0bEg5B
https://pastebin.com/KQVK1Ux4
https://pastebin.com/RzSuT9wU
https://pastebin.com/9zX0dafY
https://pastebin.com/vkitG9Jw
https://pastebin.com/BcsGM1ug
https://pastebin.com/mj2Ugnd4
https://pastebin.com/qUZmarS4
https://pastebin.com/db2sFPQt
https://pastebin.com/0Quw6jc1
https://pastebin.com/bPBJjv7K
https://pastebin.com/85VrwdEB
https://pastebin.com/ShwKYbhk
https://pastebin.com/n90Pae7n
https://pastebin.com/SKapsvXq
https://pastebin.com/jchhgXp5
https://pastebin.com/PKj7m3Lc
https://pastebin.com/uGYXHZAJ
https://pastebin.com/1Q4Smy2t
https://pastebin.com/sm9Guq40
https://pastebin.com/mwR9cXpE
https://pastebin.com/yJwCfxSP
https://pastebin.com/CBCVt6RG
https://pastebin.com/g5h9tUZ3
https://pastebin.com/LCgxSJzf
https://pastebin.com/VTQUWA8N
https://pastebin.com/qjDyTgv1
https://pastebin.com/6dFvv5Fp
https://pastebin.com/JaPKffGq
https://pastebin.com/92nW5dg4
https://pastebin.com/gH5hqPqi
https://pastebin.com/s6MKA67r
https://pastebin.com/8wtXs6PD
https://pastebin.com/jMc5xGpz
https://pastebin.com/EzDZD9aa
https://pastebin.com/p0AmhcjH
https://pastebin.com/QS1iAeCm
https://pastebin.com/X7QsHtdw
https://pastebin.com/0b4Y7fQY
https://pastebin.com/Y0sEGX9d
https://pastebin.com/6Vhw047x
https://pastebin.com/m7VxYsWv
https://pastebin.com/rDK9zsnw
https://pastebin.com/Z37U43eV
https://pastebin.com/80dR4QFi
https://pastebin.com/uB10GAXp
https://pastebin.com/8ts4FMmm
https://pastebin.com/y6TXLitK
https://pastebin.com/xPQ81CN6
https://pastebin.com/3hqhfZua
https://pastebin.com/aamUFtH2
https://pastebin.com/Lgh7nvP5
https://pastebin.com/x7Wg8naG
https://pastebin.com/aW7iLfRT
https://pastebin.com/Y7sTZ6Vb
https://pastebin.com/ZGPVkCwr
https://pastebin.com/jbcbQ9SV
https://pastebin.com/dxRWmQfk
https://pastebin.com/s02yGqxb
https://pastebin.com/1hB6AGkw
https://pastebin.com/hbcaCTpF
https://pastebin.com/pa2dcEuK
https://pastebin.com/2DV3gLRS
https://pastebin.com/wXieGb5z
https://pastebin.com/QDuKzm2f
https://pastebin.com/KzNj7grC
https://pastebin.com/89UWyNL0
https://pastebin.com/DGiiVVM6
https://pastebin.com/p1c3MvZT
https://pastebin.com/ecWTPGqn
https://pastebin.com/x6xBU9WV
https://pastebin.com/6yDL7fCa
https://pastebin.com/zjV0dLrr
https://pastebin.com/5d6FK30q
https://pastebin.com/EAxBa9Rm
https://pastebin.com/fwUrdJ4g
https://pastebin.com/VfBQU7Wb
https://pastebin.com/qwmVxX40
https://pastebin.com/71mdDTym
https://pastebin.com/qKrKiQbA
https://pastebin.com/z4WQJNkG
https://pastebin.com/1cdSJ8z5
https://pastebin.com/RtJXd9SW
https://pastebin.com/awkWi3s0
https://pastebin.com/xYkp2v8B
https://pastebin.com/rVehqExV
https://pastebin.com/Ws1Rd9bX
https://pastebin.com/8rXf1587
https://pastebin.com/9rfqNX50
https://pastebin.com/xVW5XQ2C
https://pastebin.com/dtHPSD6d
https://pastebin.com/mZD42AGm
https://pastebin.com/mXgU9d1f
https://pastebin.com/wTcD42mF
https://pastebin.com/KWqcG3if
https://pastebin.com/36p4EnHw
https://pastebin.com/TgjikqB4
https://pastebin.com/JHfBjWDg
https://pastebin.com/YhNpnZ3J
https://pastebin.com/TfC4Wa6F
https://pastebin.com/AFbL5S7E
https://pastebin.com/tVynY480
https://pastebin.com/bCevMY23
https://pastebin.com/7D3RhcvW
https://pastebin.com/sx5zBNRT
https://pastebin.com/6BEu5JtE
https://pastebin.com/LLdT59KZ
https://pastebin.com/qVaqen3E
https://pastebin.com/teqJ5Faw
https://pastebin.com/iYGt5cfB
https://pastebin.com/PvxNyjNd
https://pastebin.com/7LrBhZtK
https://pastebin.com/Uw6gnw98
https://pastebin.com/EiurXwH0
https://pastebin.com/jqRuvh0m
https://pastebin.com/geBdNDtb
https://pastebin.com/zQKdEZza
https://pastebin.com/QYFjE08P
https://pastebin.com/TBLAMRQF
https://pastebin.com/CzT8XHXy
https://pastebin.com/MBYQTUi5
https://pastebin.com/PCfCFgCR

继续阅读 »

问题现象
Swiper如何实现卡片堆叠样式:

上下堆叠:Swiper内容像卡片堆叠,在底部留部分空间显示下一页的内容,上下滑实现卡片切换。
左右堆叠:Swiper内容像卡片堆叠,在右侧留部分空间显示下一页的内容,左右滑实现卡片切换。
背景知识
Swiper组件提供滑动轮播显示的能力。Swiper本身是一个容器组件,当设置了多个子组件后,可以对这些子组件进行轮播显示。
Stack是堆叠容器,子组件按照顺序依次入栈,后一个子组件覆盖前一个子组件。
gesture可以为组件绑定手势方法进行相应处理,如滑动手势事件PanGesture。
animateTo指定由于闭包代码导致的状态变化插入过渡动效。
解决方案
上下堆叠实现。
自定义实现卡片堆叠的组件:使用Stack组件堆叠需要展示的图片,设置最上面的图片向上偏移部分距离,露出下一张图片的底部。为Stack绑定上下滑动的手势处理,实现切换图片逻辑,同时使用animateTo接口设置图片切换动画。

export class SwiperData {
imageSrc: Resource;

constructor(imageSrc: Resource) {
this.imageSrc = imageSrc;
}
}

@Component
export struct SwiperStackComponent {
@Link currentIndex: number;
@Prop swiperData: SwiperData[];
private halfCount: number = Math.floor(3 / 2);
private automaticSlidingDuration: number = 300;

aboutToAppear(): void {
this.currentIndex = 0;
}

// 修改堆叠方向系数计算
getImgCoefficients(index: number): number {
const coefficient = this.currentIndex - index;
const tempCoefficient = Math.abs(coefficient);
if (tempCoefficient <= this.halfCount) {
return coefficient;
}
const dataLength = this.swiperData.length;
let tempOffset = dataLength - tempCoefficient;
if (tempOffset <= this.halfCount) {
return coefficient > 0 ? -tempOffset : tempOffset;
}
return 0;
}

// 修改堆叠方向偏移量计算
getOffSet(index: number): number {
let offsetIndex = this.getImgCoefficients(index);
const tempOffset = Math.abs(offsetIndex);
let offset = 0;
if (tempOffset === 1) {
if (offsetIndex === 1) {
offsetIndex = -1;
}
offset = 50 * offsetIndex;
}
return -offset;
}

startAnimation(isLeft: boolean, duration: number): void {
this.getUIContext().animateTo({ duration: duration, }, () => {
const dataLength: number = this.swiperData.length;
const tempIndex: number = isLeft ? this.currentIndex + 1 : this.currentIndex - 1 + dataLength;
this.currentIndex = tempIndex % dataLength;
});
}

build() {
Stack() {
ForEach(this.swiperData, (item: SwiperData, index: number) => {
Stack({ alignContent: Alignment.Bottom }) {
Image(item.imageSrc)
.objectFit(ImageFit.Cover)
.width('100%')
.height('100%')
.borderRadius(8);
}
.offset({ x: 0, y: this.getOffSet(index) })
.shadow(ShadowStyle.OUTER_DEFAULT_SM)
.backgroundColor(Color.White)
.borderRadius(8)
.blur(index !== this.currentIndex ? 12 : 0)
// 通过animateTo实现动画并且同时改变currentIndex数据中间值来判断组件zIndex实现切换动画
.zIndex(index !== this.currentIndex && this.getImgCoefficients(index) === 0 ?
0 : 2 - Math.abs(this.getImgCoefficients(index)))
.width(310)
.height(index !== this.currentIndex ? 130 : 180);
});
}
.height(200)
.width('100%')
.gesture(
PanGesture({ direction: PanDirection.Vertical })
.onActionStart((event: GestureEvent) => {
this.startAnimation(event.offsetY < 0, this.automaticSlidingDuration);
})
)
.alignContent(Alignment.Center)
.padding({ left: 12, right: 12, top: 12 });
}
}
在页面中直接使用上面封装好的SwiperStackComponent即可,示例如下:传给SwiperStackComponent要堆叠的图片。
https://pastebin.com/m1LSXzRK
https://pastebin.com/cFaDz2JM
https://pastebin.com/94NrGTMh
https://pastebin.com/Yjx17LeK
https://pastebin.com/LqsPJ96h
https://pastebin.com/DPDgXMvK
https://pastebin.com/hSjsmXQA
https://pastebin.com/uKP1SMUS
https://pastebin.com/NzZpsC1T
https://pastebin.com/YYRMvbNK
https://pastebin.com/yMGLZhE6
https://pastebin.com/S95qV0Uz
https://pastebin.com/KkbjxT3u
https://pastebin.com/KtDaV8W6
https://pastebin.com/StWuCs6Y
https://pastebin.com/P1C46HUd
https://pastebin.com/jQVY68MF
https://pastebin.com/pZWdw2nr
https://pastebin.com/hWvq20CX
https://pastebin.com/6gYgutXU
https://pastebin.com/U4bchZ6m
https://pastebin.com/gfaWG0r6
https://pastebin.com/e9Y0r65R
https://pastebin.com/TVxKvWAq
https://pastebin.com/XQf3dgCp
https://pastebin.com/DpcrwpV5
https://pastebin.com/ebTwvrA8
https://pastebin.com/9AVaZHpP
https://pastebin.com/0XNziuPN
https://pastebin.com/5pX3w9Qz
https://pastebin.com/LxBeC4wT
https://pastebin.com/Ts4YH8YT
https://pastebin.com/gtTcZ7WL
https://pastebin.com/9hCAm4pk
https://pastebin.com/ivQAv3W6
https://pastebin.com/kQkScYnm
https://pastebin.com/Pggf2AJf
https://pastebin.com/93YQXuS2
https://pastebin.com/8bT7ebcm
https://pastebin.com/qhwZL1PA
https://pastebin.com/1j9Dfhf3
https://pastebin.com/yr8G62Eb
https://pastebin.com/i6keBveX
https://pastebin.com/8cShExkL
https://pastebin.com/uRpXa4D8
https://pastebin.com/GCWXMvkV
https://pastebin.com/5r8kkafj
https://pastebin.com/gZqmkKFY
https://pastebin.com/uzX4RXb8
https://pastebin.com/NX85Yeya
https://pastebin.com/0bnHmnn1
https://pastebin.com/4TEuJiyp
https://pastebin.com/19ECBLgF
https://pastebin.com/Q6sXfyLu
https://pastebin.com/J3wkaGhA
https://pastebin.com/MV4f7R1P
https://pastebin.com/4dtFguZU
https://pastebin.com/adNJrURC
https://pastebin.com/aTtEKzis
https://pastebin.com/PQrg1GWd
https://pastebin.com/gKTKwvqf
https://pastebin.com/uuYPPvaA
https://pastebin.com/j4Ls35Kc
https://pastebin.com/E0Ukv7Aj
https://pastebin.com/f6k4t5u2
https://pastebin.com/Q1DXAxWt
https://pastebin.com/tjfUhr1N
https://pastebin.com/uU5iHdYy
https://pastebin.com/cRR3KhUL
https://pastebin.com/nCiKrKtB
https://pastebin.com/dSHVsFy0
https://pastebin.com/2XAKUkn6
https://pastebin.com/Jppiihgb
https://pastebin.com/h3yaiqzz
https://pastebin.com/2JWDAsub
https://pastebin.com/tmPvc6uP
https://pastebin.com/FUnWQQwV
https://pastebin.com/Gp2UtxKN
https://pastebin.com/h95wHCfg
https://pastebin.com/fsCpD2Z8
https://pastebin.com/zJr9HCpS
https://pastebin.com/0PvFpNur
https://pastebin.com/VJyawuD5
https://pastebin.com/ba848eTS
https://pastebin.com/RACk8XWR
https://pastebin.com/0hwQHBAn
https://pastebin.com/sm0bEg5B
https://pastebin.com/KQVK1Ux4
https://pastebin.com/RzSuT9wU
https://pastebin.com/9zX0dafY
https://pastebin.com/vkitG9Jw
https://pastebin.com/BcsGM1ug
https://pastebin.com/mj2Ugnd4
https://pastebin.com/qUZmarS4
https://pastebin.com/db2sFPQt
https://pastebin.com/0Quw6jc1
https://pastebin.com/bPBJjv7K
https://pastebin.com/85VrwdEB
https://pastebin.com/ShwKYbhk
https://pastebin.com/n90Pae7n
https://pastebin.com/SKapsvXq
https://pastebin.com/jchhgXp5
https://pastebin.com/PKj7m3Lc
https://pastebin.com/uGYXHZAJ
https://pastebin.com/1Q4Smy2t
https://pastebin.com/sm9Guq40
https://pastebin.com/mwR9cXpE
https://pastebin.com/yJwCfxSP
https://pastebin.com/CBCVt6RG
https://pastebin.com/g5h9tUZ3
https://pastebin.com/LCgxSJzf
https://pastebin.com/VTQUWA8N
https://pastebin.com/qjDyTgv1
https://pastebin.com/6dFvv5Fp
https://pastebin.com/JaPKffGq
https://pastebin.com/92nW5dg4
https://pastebin.com/gH5hqPqi
https://pastebin.com/s6MKA67r
https://pastebin.com/8wtXs6PD
https://pastebin.com/jMc5xGpz
https://pastebin.com/EzDZD9aa
https://pastebin.com/p0AmhcjH
https://pastebin.com/QS1iAeCm
https://pastebin.com/X7QsHtdw
https://pastebin.com/0b4Y7fQY
https://pastebin.com/Y0sEGX9d
https://pastebin.com/6Vhw047x
https://pastebin.com/m7VxYsWv
https://pastebin.com/rDK9zsnw
https://pastebin.com/Z37U43eV
https://pastebin.com/80dR4QFi
https://pastebin.com/uB10GAXp
https://pastebin.com/8ts4FMmm
https://pastebin.com/y6TXLitK
https://pastebin.com/xPQ81CN6
https://pastebin.com/3hqhfZua
https://pastebin.com/aamUFtH2
https://pastebin.com/Lgh7nvP5
https://pastebin.com/x7Wg8naG
https://pastebin.com/aW7iLfRT
https://pastebin.com/Y7sTZ6Vb
https://pastebin.com/ZGPVkCwr
https://pastebin.com/jbcbQ9SV
https://pastebin.com/dxRWmQfk
https://pastebin.com/s02yGqxb
https://pastebin.com/1hB6AGkw
https://pastebin.com/hbcaCTpF
https://pastebin.com/pa2dcEuK
https://pastebin.com/2DV3gLRS
https://pastebin.com/wXieGb5z
https://pastebin.com/QDuKzm2f
https://pastebin.com/KzNj7grC
https://pastebin.com/89UWyNL0
https://pastebin.com/DGiiVVM6
https://pastebin.com/p1c3MvZT
https://pastebin.com/ecWTPGqn
https://pastebin.com/x6xBU9WV
https://pastebin.com/6yDL7fCa
https://pastebin.com/zjV0dLrr
https://pastebin.com/5d6FK30q
https://pastebin.com/EAxBa9Rm
https://pastebin.com/fwUrdJ4g
https://pastebin.com/VfBQU7Wb
https://pastebin.com/qwmVxX40
https://pastebin.com/71mdDTym
https://pastebin.com/qKrKiQbA
https://pastebin.com/z4WQJNkG
https://pastebin.com/1cdSJ8z5
https://pastebin.com/RtJXd9SW
https://pastebin.com/awkWi3s0
https://pastebin.com/xYkp2v8B
https://pastebin.com/rVehqExV
https://pastebin.com/Ws1Rd9bX
https://pastebin.com/8rXf1587
https://pastebin.com/9rfqNX50
https://pastebin.com/xVW5XQ2C
https://pastebin.com/dtHPSD6d
https://pastebin.com/mZD42AGm
https://pastebin.com/mXgU9d1f
https://pastebin.com/wTcD42mF
https://pastebin.com/KWqcG3if
https://pastebin.com/36p4EnHw
https://pastebin.com/TgjikqB4
https://pastebin.com/JHfBjWDg
https://pastebin.com/YhNpnZ3J
https://pastebin.com/TfC4Wa6F
https://pastebin.com/AFbL5S7E
https://pastebin.com/tVynY480
https://pastebin.com/bCevMY23
https://pastebin.com/7D3RhcvW
https://pastebin.com/sx5zBNRT
https://pastebin.com/6BEu5JtE
https://pastebin.com/LLdT59KZ
https://pastebin.com/qVaqen3E
https://pastebin.com/teqJ5Faw
https://pastebin.com/iYGt5cfB
https://pastebin.com/PvxNyjNd
https://pastebin.com/7LrBhZtK
https://pastebin.com/Uw6gnw98
https://pastebin.com/EiurXwH0
https://pastebin.com/jqRuvh0m
https://pastebin.com/geBdNDtb
https://pastebin.com/zQKdEZza
https://pastebin.com/QYFjE08P
https://pastebin.com/TBLAMRQF
https://pastebin.com/CzT8XHXy
https://pastebin.com/MBYQTUi5
https://pastebin.com/PCfCFgCR

收起阅读 »

如何解决NavDestination切换页面后浏览位置无法保存问题

问题现象
在HarmonyOS中,使用NavDestination实现页面跳转至其他页面后,下次进入如何保持跳转前页面的浏览位置?

背景知识
Navigation:Navigation组件是路由导航的根视图容器,一般作为Page页面的根容器使用,其内部默认包含了标题栏、内容区和工具栏,其中内容区默认首页显示导航内容(NavDestination的子组件)或非首页显示(NavDestination的子组件),首页和非首页通过路由进行切换。
@ohos.arkui.observer(无感监听)提供UI组件行为变化的无感监听能力。可以监听Navigation的页面切换事件进行相应操作。
Scroll是一种可滚动的容器组件,当子组件的布局尺寸超过父组件的尺寸时,内容可以滚动。
onDidScroll方法在Scroll滚动时触发,可用于在滑动过程中获取Scroll组件的偏移量yOffset。
scrollTo方法可用于让Scroll组件滑动到指定位置。
AppStorage是应用全局的UI状态存储,和应用的进程绑定,只能在UI主线程中使用,无法在子线程中使用、修改。
解决方案
方案一:使用路由模式保留页面实例。
在页面跳转时不要使用pop和clear等方法,否则NavDestination页面会被回收。可以采用单例模式MOVE_TO_TOP_SINGLETON跳转至指定的页面,该方式会使用栈内已存在的页面实例(即浏览位置不变)。

由于单例模式是从栈底到栈顶依次查找,当栈内存在多个同名页面实例时,会默认跳转最底层的同名页面实例,所以需确保栈内只存在一个同名实例,否则跳转的页面保留的滚动位置与上一次显示的页面会不一致(显示的是栈底同名实例保留的滚动位置)。

import { PageOneS1Builder } from './PageOneS1';
import { PageTwoS1Builder } from './PageTwoS1';

@Entry
@Component
struct Solution1 {
private pathStack: NavPathStack = new NavPathStack();

aboutToAppear(): void {
this.pathStack.pushPath({ name: 'PageOneS1' }); // 推送第一个子页作为首页
}

@Builder
pageMap(name: string) {
if (name === 'PageOneS1') {
PageOneS1Builder();
} else if (name === 'PageTwoS1') {
PageTwoS1Builder();
}
}

build() {
Navigation(this.pathStack) {
}
.navDestination(this.pageMap)
.width('100%')
.height('100%')
.hideNavBar(true);
}
}
@Builder
export function PageOneS1Builder() {
PageOneS1();
}

@Component
struct PageOneS1 {
private pathStack: NavPathStack = new NavPathStack();
private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];

build() {
NavDestination() {
Column({ space: 20 }) {
Row() {
Button('跳转页面')
.margin({ top: 20 })
.onClick(() => {
this.pathStack.pushPathByName('PageTwoS1', null, false);
});
};

    List({ space: 16 }) {  
      ForEach(this.arr, (item: number) => {  
        ListItem() {  
          Text(item.toString())  
            .width('100%')  
            .height(100)  
            .fontSize(16)  
            .textAlign(TextAlign.Center)  
            .borderRadius(16)  
            .backgroundColor('#F1F3F5');  
        }.width('100%');  
      }, (item: string) => item);  
    }.padding({ left: 12, right: 12 })  
    .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM])  
    .alignListItem(ListItemAlign.Center)  
    .height('90%');  
  };  
}.width('100%').height('100%')  
.onReady((context: NavDestinationContext) => {  
  this.pathStack = context.pathStack;  
});  

}
}
@Builder
export function PageTwoS1Builder() {
PageTwoS1();
}

@Component
struct PageTwoS1 {
pathStack: NavPathStack = new NavPathStack();

build() {
NavDestination() {
Column({ space: 20 }) {
Button('单例跳转')
.width('30%')
.margin('20vp')
.onClick(() => {
// 或者使用单例模式跳转回其它页面
this.pathStack.pushPath({ name: 'PageOneS1' }, { launchMode: LaunchMode.MOVE_TO_TOP_SINGLETON });
});
}.width('100%').height('100%');
}
.onReady((context: NavDestinationContext) => {
this.pathStack = context.pathStack;
});
}
}
https://pastebin.com/B0hqJAZx
https://pastebin.com/v4JTaWDt
https://pastebin.com/d5ge4288
https://pastebin.com/3shcMPv5
https://pastebin.com/70uKbDuw
https://pastebin.com/3LhjKXni
https://pastebin.com/5gVBhCGx
https://pastebin.com/dpMxkMXN
https://pastebin.com/fv8cG0b7
https://pastebin.com/JtuLjtFR
https://pastebin.com/yCfWpnxz
https://pastebin.com/Q2rrq3WB
https://pastebin.com/3bKAPcGk
https://pastebin.com/j7MfT7Dc
https://pastebin.com/U0p3Fvrc
https://pastebin.com/6sYfe5Lr
https://pastebin.com/jLNESEFx
https://pastebin.com/2KdkqCkw
https://pastebin.com/WAgQsmsV
https://pastebin.com/xmiRqKfd
https://pastebin.com/LXPu7Btx
https://pastebin.com/Qcg8dPbD
https://pastebin.com/EhtDxXMD
https://pastebin.com/yEwh5m4v
https://pastebin.com/tU0CueV4
https://pastebin.com/8JzMaNz7
https://pastebin.com/3jg8aspW
https://pastebin.com/YyHrmrJK
https://pastebin.com/ZgagcLAc
https://pastebin.com/ABpgUr5G
https://pastebin.com/cvPYk5AN
https://pastebin.com/XGZQUT1m
https://pastebin.com/qAd27GCF
https://pastebin.com/PiFNHkLd
https://pastebin.com/aiYX5L1G
https://pastebin.com/aqpnXQvz
https://pastebin.com/kB8XJ9n2
https://pastebin.com/sLfk0TR7
https://pastebin.com/nQ9nV4g8
https://pastebin.com/NAUQ9SA0
https://pastebin.com/GxvWFg6T
https://pastebin.com/TSNy8Cys
https://pastebin.com/fpN03727
https://pastebin.com/QAFi8vrv
https://pastebin.com/fGkfHRgA
https://pastebin.com/3uF2PZgW
https://pastebin.com/yrwWGir9
https://pastebin.com/DuJE5XWa
https://pastebin.com/AVFvUePM
https://pastebin.com/M238qSej
https://pastebin.com/0B4NeJVz
https://pastebin.com/QC10Yytt
https://pastebin.com/z9uFQLbx
https://pastebin.com/jnR6Ksj2
https://pastebin.com/PJRHZYLg
https://pastebin.com/fskAwwPB
https://pastebin.com/GZ06rdYf
https://pastebin.com/spckePTy
https://pastebin.com/k5bpeqiD
https://pastebin.com/FUU83kVA
https://pastebin.com/dM5D2uq9
https://pastebin.com/HDyrbkcH
https://pastebin.com/6wLvBQBZ
https://pastebin.com/mkzrQGUE
https://pastebin.com/w40S6h1g
https://pastebin.com/EC5Qsc1J
https://pastebin.com/YyecbF2B
https://pastebin.com/rzFVRVD1
https://pastebin.com/nfukdwW3
https://pastebin.com/U0TfAD8F
https://pastebin.com/cegRdmaa
https://pastebin.com/HP55mCGz
https://pastebin.com/tDXrav7c
https://pastebin.com/VVzmD76k
https://pastebin.com/BHNwWAgu
https://pastebin.com/eR9LLY9Q
https://pastebin.com/0VYxXiXy
https://pastebin.com/XnBpR3QN
https://pastebin.com/tBtYnBVG
https://pastebin.com/8u9mvEPB
https://pastebin.com/2U7ttpz2
https://pastebin.com/Gagnm4jU
https://pastebin.com/43arJtBe
https://pastebin.com/XZ5ysaad
https://pastebin.com/JH3cJ0tN
https://pastebin.com/WfYeNrRa
https://pastebin.com/qDUK54Zy
https://pastebin.com/5LK03T2X
https://pastebin.com/d9GP4N9f
https://pastebin.com/AegGQDh5
https://pastebin.com/Msh1eGGs
https://pastebin.com/pW3QVH8H
https://pastebin.com/YQvV6CCA
https://pastebin.com/BekJgqXm
https://pastebin.com/24wFN8fj
https://pastebin.com/PcJRC4W5
https://pastebin.com/cjM2pYBz
https://pastebin.com/vEqh5L7f
https://pastebin.com/KZBzS7Re
https://pastebin.com/M7KwpPmg

继续阅读 »

问题现象
在HarmonyOS中,使用NavDestination实现页面跳转至其他页面后,下次进入如何保持跳转前页面的浏览位置?

背景知识
Navigation:Navigation组件是路由导航的根视图容器,一般作为Page页面的根容器使用,其内部默认包含了标题栏、内容区和工具栏,其中内容区默认首页显示导航内容(NavDestination的子组件)或非首页显示(NavDestination的子组件),首页和非首页通过路由进行切换。
@ohos.arkui.observer(无感监听)提供UI组件行为变化的无感监听能力。可以监听Navigation的页面切换事件进行相应操作。
Scroll是一种可滚动的容器组件,当子组件的布局尺寸超过父组件的尺寸时,内容可以滚动。
onDidScroll方法在Scroll滚动时触发,可用于在滑动过程中获取Scroll组件的偏移量yOffset。
scrollTo方法可用于让Scroll组件滑动到指定位置。
AppStorage是应用全局的UI状态存储,和应用的进程绑定,只能在UI主线程中使用,无法在子线程中使用、修改。
解决方案
方案一:使用路由模式保留页面实例。
在页面跳转时不要使用pop和clear等方法,否则NavDestination页面会被回收。可以采用单例模式MOVE_TO_TOP_SINGLETON跳转至指定的页面,该方式会使用栈内已存在的页面实例(即浏览位置不变)。

由于单例模式是从栈底到栈顶依次查找,当栈内存在多个同名页面实例时,会默认跳转最底层的同名页面实例,所以需确保栈内只存在一个同名实例,否则跳转的页面保留的滚动位置与上一次显示的页面会不一致(显示的是栈底同名实例保留的滚动位置)。

import { PageOneS1Builder } from './PageOneS1';
import { PageTwoS1Builder } from './PageTwoS1';

@Entry
@Component
struct Solution1 {
private pathStack: NavPathStack = new NavPathStack();

aboutToAppear(): void {
this.pathStack.pushPath({ name: 'PageOneS1' }); // 推送第一个子页作为首页
}

@Builder
pageMap(name: string) {
if (name === 'PageOneS1') {
PageOneS1Builder();
} else if (name === 'PageTwoS1') {
PageTwoS1Builder();
}
}

build() {
Navigation(this.pathStack) {
}
.navDestination(this.pageMap)
.width('100%')
.height('100%')
.hideNavBar(true);
}
}
@Builder
export function PageOneS1Builder() {
PageOneS1();
}

@Component
struct PageOneS1 {
private pathStack: NavPathStack = new NavPathStack();
private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];

build() {
NavDestination() {
Column({ space: 20 }) {
Row() {
Button('跳转页面')
.margin({ top: 20 })
.onClick(() => {
this.pathStack.pushPathByName('PageTwoS1', null, false);
});
};

    List({ space: 16 }) {  
      ForEach(this.arr, (item: number) => {  
        ListItem() {  
          Text(item.toString())  
            .width('100%')  
            .height(100)  
            .fontSize(16)  
            .textAlign(TextAlign.Center)  
            .borderRadius(16)  
            .backgroundColor('#F1F3F5');  
        }.width('100%');  
      }, (item: string) => item);  
    }.padding({ left: 12, right: 12 })  
    .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM])  
    .alignListItem(ListItemAlign.Center)  
    .height('90%');  
  };  
}.width('100%').height('100%')  
.onReady((context: NavDestinationContext) => {  
  this.pathStack = context.pathStack;  
});  

}
}
@Builder
export function PageTwoS1Builder() {
PageTwoS1();
}

@Component
struct PageTwoS1 {
pathStack: NavPathStack = new NavPathStack();

build() {
NavDestination() {
Column({ space: 20 }) {
Button('单例跳转')
.width('30%')
.margin('20vp')
.onClick(() => {
// 或者使用单例模式跳转回其它页面
this.pathStack.pushPath({ name: 'PageOneS1' }, { launchMode: LaunchMode.MOVE_TO_TOP_SINGLETON });
});
}.width('100%').height('100%');
}
.onReady((context: NavDestinationContext) => {
this.pathStack = context.pathStack;
});
}
}
https://pastebin.com/B0hqJAZx
https://pastebin.com/v4JTaWDt
https://pastebin.com/d5ge4288
https://pastebin.com/3shcMPv5
https://pastebin.com/70uKbDuw
https://pastebin.com/3LhjKXni
https://pastebin.com/5gVBhCGx
https://pastebin.com/dpMxkMXN
https://pastebin.com/fv8cG0b7
https://pastebin.com/JtuLjtFR
https://pastebin.com/yCfWpnxz
https://pastebin.com/Q2rrq3WB
https://pastebin.com/3bKAPcGk
https://pastebin.com/j7MfT7Dc
https://pastebin.com/U0p3Fvrc
https://pastebin.com/6sYfe5Lr
https://pastebin.com/jLNESEFx
https://pastebin.com/2KdkqCkw
https://pastebin.com/WAgQsmsV
https://pastebin.com/xmiRqKfd
https://pastebin.com/LXPu7Btx
https://pastebin.com/Qcg8dPbD
https://pastebin.com/EhtDxXMD
https://pastebin.com/yEwh5m4v
https://pastebin.com/tU0CueV4
https://pastebin.com/8JzMaNz7
https://pastebin.com/3jg8aspW
https://pastebin.com/YyHrmrJK
https://pastebin.com/ZgagcLAc
https://pastebin.com/ABpgUr5G
https://pastebin.com/cvPYk5AN
https://pastebin.com/XGZQUT1m
https://pastebin.com/qAd27GCF
https://pastebin.com/PiFNHkLd
https://pastebin.com/aiYX5L1G
https://pastebin.com/aqpnXQvz
https://pastebin.com/kB8XJ9n2
https://pastebin.com/sLfk0TR7
https://pastebin.com/nQ9nV4g8
https://pastebin.com/NAUQ9SA0
https://pastebin.com/GxvWFg6T
https://pastebin.com/TSNy8Cys
https://pastebin.com/fpN03727
https://pastebin.com/QAFi8vrv
https://pastebin.com/fGkfHRgA
https://pastebin.com/3uF2PZgW
https://pastebin.com/yrwWGir9
https://pastebin.com/DuJE5XWa
https://pastebin.com/AVFvUePM
https://pastebin.com/M238qSej
https://pastebin.com/0B4NeJVz
https://pastebin.com/QC10Yytt
https://pastebin.com/z9uFQLbx
https://pastebin.com/jnR6Ksj2
https://pastebin.com/PJRHZYLg
https://pastebin.com/fskAwwPB
https://pastebin.com/GZ06rdYf
https://pastebin.com/spckePTy
https://pastebin.com/k5bpeqiD
https://pastebin.com/FUU83kVA
https://pastebin.com/dM5D2uq9
https://pastebin.com/HDyrbkcH
https://pastebin.com/6wLvBQBZ
https://pastebin.com/mkzrQGUE
https://pastebin.com/w40S6h1g
https://pastebin.com/EC5Qsc1J
https://pastebin.com/YyecbF2B
https://pastebin.com/rzFVRVD1
https://pastebin.com/nfukdwW3
https://pastebin.com/U0TfAD8F
https://pastebin.com/cegRdmaa
https://pastebin.com/HP55mCGz
https://pastebin.com/tDXrav7c
https://pastebin.com/VVzmD76k
https://pastebin.com/BHNwWAgu
https://pastebin.com/eR9LLY9Q
https://pastebin.com/0VYxXiXy
https://pastebin.com/XnBpR3QN
https://pastebin.com/tBtYnBVG
https://pastebin.com/8u9mvEPB
https://pastebin.com/2U7ttpz2
https://pastebin.com/Gagnm4jU
https://pastebin.com/43arJtBe
https://pastebin.com/XZ5ysaad
https://pastebin.com/JH3cJ0tN
https://pastebin.com/WfYeNrRa
https://pastebin.com/qDUK54Zy
https://pastebin.com/5LK03T2X
https://pastebin.com/d9GP4N9f
https://pastebin.com/AegGQDh5
https://pastebin.com/Msh1eGGs
https://pastebin.com/pW3QVH8H
https://pastebin.com/YQvV6CCA
https://pastebin.com/BekJgqXm
https://pastebin.com/24wFN8fj
https://pastebin.com/PcJRC4W5
https://pastebin.com/cjM2pYBz
https://pastebin.com/vEqh5L7f
https://pastebin.com/KZBzS7Re
https://pastebin.com/M7KwpPmg

收起阅读 »

Uni-Grid二次进入样式问题深度解析与解决方案

Uni-Grid二次进入样式问题深度解析与解决方案
一、uni-grid组件概述
uni-grid是uni-app框架中用于实现网格布局的UI组件,特别适用于展示多个项目或产品的场景。它可以将子元素按照行和列的网格方式进行自动排列,保持布局的整齐和一致性。uni-grid组件提供灵活的布局选项,包括网格大小的设定、行列的对齐方式、间距调整等,使开发者能够在设计UI时保持美观性
1
2

‌主要应用场景‌:

电商分类商品列表展示
功能入口按钮布局
新闻资讯卡片展示
多项目对比展示
二、二次进入样式问题表现
uni-grid在二次进入页面时常见的样式问题主要包括:

‌少一列现象‌:第二次进入页面时,网格布局的最后一列可能消失或显示不全
7
‌样式闪烁‌:页面切换时出现短暂的布局错乱或闪烁现象
‌字节小程序嵌套问题‌:在字节跳动小程序中,由于自定义组件多一层嵌套,可能导致布局失效
8
‌边框显示异常‌:二次进入时边框可能错位或消失
‌间距变化‌:网格项之间的间距在二次进入时可能不一致
三、问题原因分析

  1. 布局计算机制
    uni-grid在首次渲染时会根据当前容器尺寸计算布局,但二次进入时可能由于以下原因导致计算不准确:

容器尺寸变化未被正确检测
缓存了错误的布局参数
响应式更新机制延迟

  1. 平台差异
    不同平台对CSS Grid布局的支持程度不同,特别是小程序环境存在额外的渲染层,可能导致样式表现不一致
    8

  2. 组件内部实现
    uni-grid组件在某些版本中存在以下问题:

列数计算逻辑缺陷
状态管理不完善
样式重置不彻底
四、解决方案与最佳实践

  1. 基础解决方案
    ‌方案一:去除边框‌

html
Copy Code
<column="4" :highlight="true" :show-border="false">
<!-- 网格项内容 -->
</uni-grid>`` 通过设置show-border="false"`可以避免边框相关的问题:ml-citation{ref="7" data="citationList"}。

方案二:固定外层容器宽度


<view style="width: 100%;">  
  <uni-grid :column="4">  
    <!-- 网格项内容 -->  
  </uni-grid>  
</view>  
2. 字节小程序特殊处理  
对于字节小程序中的嵌套问题,可以使用以下方案:  

‌方案一:使用customStyle属性  
BbS.rasyi45.cn/PoSt/1118_19299.HtM  
BbS.by00ez4.cn/PoSt/1118_37172.HtM  
BbS.azlqul5.cn/PoSt/1118_18151.HtM  
BbS.z5tiiyy.cn/PoSt/1118_83137.HtM  
BbS.n9trnzh.cn/PoSt/1118_20556.HtM  
BbS.38zp1cm.cn/PoSt/1118_67206.HtM  
BbS.na2xy0k.cn/PoSt/1118_48017.HtM  
BbS.vb5kftl.cn/PoSt/1118_70297.HtM  
BbS.cjn8dgi.cn/PoSt/1118_41500.HtM  
BbS.bhkgwzx.cn/PoSt/1118_03535.HtM  
BbS.rasyi45.cn/PoSt/1118_69627.HtM  
BbS.by00ez4.cn/PoSt/1118_51140.HtM  
BbS.azlqul5.cn/PoSt/1118_24675.HtM  
BbS.z5tiiyy.cn/PoSt/1118_48794.HtM  
BbS.n9trnzh.cn/PoSt/1118_05781.HtM  
BbS.38zp1cm.cn/PoSt/1118_78901.HtM  
BbS.na2xy0k.cn/PoSt/1118_14040.HtM  
BbS.vb5kftl.cn/PoSt/1118_77932.HtM  
BbS.cjn8dgi.cn/PoSt/1118_08901.HtM  
BbS.bhkgwzx.cn/PoSt/1118_11627.HtM  
BbS.rasyi45.cn/PoSt/1118_25034.HtM  
BbS.by00ez4.cn/PoSt/1118_40190.HtM  
BbS.azlqul5.cn/PoSt/1118_52596.HtM  
BbS.z5tiiyy.cn/PoSt/1118_95405.HtM  
BbS.n9trnzh.cn/PoSt/1118_58926.HtM  
BbS.38zp1cm.cn/PoSt/1118_55895.HtM  
BbS.na2xy0k.cn/PoSt/1118_60516.HtM  
BbS.vb5kftl.cn/PoSt/1118_83011.HtM  
BbS.cjn8dgi.cn/PoSt/1118_65087.HtM  
BbS.bhkgwzx.cn/PoSt/1118_11916.HtM  
BbS.rasyi45.cn/PoSt/1118_50730.HtM  
BbS.by00ez4.cn/PoSt/1118_87660.HtM  
BbS.azlqul5.cn/PoSt/1118_98032.HtM  
BbS.z5tiiyy.cn/PoSt/1118_57044.HtM  
BbS.n9trnzh.cn/PoSt/1118_11285.HtM  
BbS.38zp1cm.cn/PoSt/1118_65869.HtM  
BbS.na2xy0k.cn/PoSt/1118_77049.HtM  
BbS.vb5kftl.cn/PoSt/1118_28621.HtM  
BbS.cjn8dgi.cn/PoSt/1118_07305.HtM  
BbS.bhkgwzx.cn/PoSt/1118_50869.HtM  
BbS.rasyi45.cn/PoSt/1118_63530.HtM  
BbS.by00ez4.cn/PoSt/1118_55851.HtM  
BbS.azlqul5.cn/PoSt/1118_33005.HtM  
BbS.z5tiiyy.cn/PoSt/1118_64993.HtM  
BbS.n9trnzh.cn/PoSt/1118_35153.HtM  
BbS.38zp1cm.cn/PoSt/1118_18891.HtM  
BbS.na2xy0k.cn/PoSt/1118_17872.HtM  
BbS.vb5kftl.cn/PoSt/1118_94456.HtM  
BbS.cjn8dgi.cn/PoSt/1118_91569.HtM  
BbS.bhkgwzx.cn/PoSt/1118_83731.HtM  
BbS.rasyi45.cn/PoSt/1118_08124.HtM  
BbS.by00ez4.cn/PoSt/1118_96290.HtM  
BbS.azlqul5.cn/PoSt/1118_95198.HtM  
BbS.z5tiiyy.cn/PoSt/1118_45924.HtM  
BbS.n9trnzh.cn/PoSt/1118_42449.HtM  
BbS.38zp1cm.cn/PoSt/1118_35483.HtM  
BbS.na2xy0k.cn/PoSt/1118_88432.HtM  
BbS.vb5kftl.cn/PoSt/1118_73893.HtM  
BbS.cjn8dgi.cn/PoSt/1118_49010.HtM  
BbS.bhkgwzx.cn/PoSt/1118_57819.HtM  
BbS.rasyi45.cn/PoSt/1118_97562.HtM  
BbS.by00ez4.cn/PoSt/1118_28059.HtM  
BbS.azlqul5.cn/PoSt/1118_34118.HtM  
BbS.z5tiiyy.cn/PoSt/1118_36384.HtM  
BbS.n9trnzh.cn/PoSt/1118_90347.HtM  
BbS.38zp1cm.cn/PoSt/1118_34379.HtM  
BbS.na2xy0k.cn/PoSt/1118_41241.HtM  
BbS.vb5kftl.cn/PoSt/1118_42674.HtM  
BbS.cjn8dgi.cn/PoSt/1118_62028.HtM  
BbS.bhkgwzx.cn/PoSt/1118_53898.HtM  
BbS.rasyi45.cn/PoSt/1118_98630.HtM  
BbS.by00ez4.cn/PoSt/1118_90659.HtM  
BbS.azlqul5.cn/PoSt/1118_02696.HtM  
BbS.z5tiiyy.cn/PoSt/1118_41148.HtM  
BbS.n9trnzh.cn/PoSt/1118_40116.HtM  
BbS.38zp1cm.cn/PoSt/1118_06465.HtM  
BbS.na2xy0k.cn/PoSt/1118_59674.HtM  
BbS.vb5kftl.cn/PoSt/1118_48963.HtM  
BbS.cjn8dgi.cn/PoSt/1118_98155.HtM  
BbS.bhkgwzx.cn/PoSt/1118_51029.HtM  
BbS.rasyi45.cn/PoSt/1118_69314.HtM  
BbS.by00ez4.cn/PoSt/1118_49963.HtM  
BbS.azlqul5.cn/PoSt/1118_89278.HtM  
BbS.z5tiiyy.cn/PoSt/1118_36703.HtM  
BbS.n9trnzh.cn/PoSt/1118_88376.HtM  
BbS.38zp1cm.cn/PoSt/1118_03169.HtM  
BbS.na2xy0k.cn/PoSt/1118_07021.HtM  
BbS.vb5kftl.cn/PoSt/1118_35500.HtM  
BbS.cjn8dgi.cn/PoSt/1118_55419.HtM  
BbS.bhkgwzx.cn/PoSt/1118_77222.HtM  
BbS.rasyi45.cn/PoSt/1118_40900.HtM  
BbS.by00ez4.cn/PoSt/1118_37648.HtM  
BbS.azlqul5.cn/PoSt/1118_11859.HtM  
BbS.z5tiiyy.cn/PoSt/1118_90260.HtM  
BbS.n9trnzh.cn/PoSt/1118_62521.HtM  
BbS.38zp1cm.cn/PoSt/1118_68146.HtM  
BbS.na2xy0k.cn/PoSt/1118_31363.HtM  
BbS.vb5kftl.cn/PoSt/1118_38681.HtM  
BbS.cjn8dgi.cn/PoSt/1118_71651.HtM  
BbS.bhkgwzx.cn/PoSt/1118_56266.HtM  
BbS.l718213.cn/PoSt/1118_76575.HtM  
BbS.epfsrpr.cn/PoSt/1118_76972.HtM  
BbS.oduz1qq.cn/PoSt/1118_45901.HtM  
BbS.ddtirdr.cn/PoSt/1118_07782.HtM  
BbS.lmq3hz3.cn/PoSt/1118_69345.HtM  
BbS.f7c4rbn.cn/PoSt/1118_12542.HtM  
BbS.c7jt2qk.cn/PoSt/1118_11716.HtM  
BbS.41gi32y.cn/PoSt/1118_40553.HtM  
BbS.xk7ehlo.cn/PoSt/1118_18905.HtM  
BbS.kq762s8.cn/PoSt/1118_33956.HtM  
BbS.l718213.cn/PoSt/1118_46747.HtM  
BbS.epfsrpr.cn/PoSt/1118_36572.HtM  
BbS.oduz1qq.cn/PoSt/1118_78843.HtM  
BbS.ddtirdr.cn/PoSt/1118_29709.HtM  
BbS.lmq3hz3.cn/PoSt/1118_92419.HtM  
BbS.f7c4rbn.cn/PoSt/1118_74738.HtM  
BbS.c7jt2qk.cn/PoSt/1118_25708.HtM  
BbS.41gi32y.cn/PoSt/1118_47655.HtM  
BbS.xk7ehlo.cn/PoSt/1118_71516.HtM  
BbS.kq762s8.cn/PoSt/1118_35833.HtM  
BbS.l718213.cn/PoSt/1118_34632.HtM  
BbS.epfsrpr.cn/PoSt/1118_83859.HtM  
BbS.oduz1qq.cn/PoSt/1118_69403.HtM  
BbS.ddtirdr.cn/PoSt/1118_83844.HtM  
BbS.lmq3hz3.cn/PoSt/1118_76641.HtM  
BbS.f7c4rbn.cn/PoSt/1118_18984.HtM  
BbS.c7jt2qk.cn/PoSt/1118_20607.HtM  
BbS.41gi32y.cn/PoSt/1118_80898.HtM  
BbS.xk7ehlo.cn/PoSt/1118_29387.HtM  
BbS.kq762s8.cn/PoSt/1118_08148.HtM  
BbS.l718213.cn/PoSt/1118_75732.HtM  
BbS.epfsrpr.cn/PoSt/1118_87415.HtM  
BbS.oduz1qq.cn/PoSt/1118_57533.HtM  
BbS.ddtirdr.cn/PoSt/1118_47368.HtM  
BbS.lmq3hz3.cn/PoSt/1118_32119.HtM  
BbS.f7c4rbn.cn/PoSt/1118_95661.HtM  
BbS.c7jt2qk.cn/PoSt/1118_38416.HtM  
BbS.41gi32y.cn/PoSt/1118_28348.HtM  
BbS.xk7ehlo.cn/PoSt/1118_72894.HtM  
BbS.kq762s8.cn/PoSt/1118_72739.HtM  
BbS.l718213.cn/PoSt/1118_42117.HtM  
BbS.epfsrpr.cn/PoSt/1118_91418.HtM  
BbS.oduz1qq.cn/PoSt/1118_79382.HtM  
BbS.ddtirdr.cn/PoSt/1118_37447.HtM  
BbS.lmq3hz3.cn/PoSt/1118_64596.HtM  
BbS.f7c4rbn.cn/PoSt/1118_47359.HtM  
BbS.c7jt2qk.cn/PoSt/1118_71352.HtM  
BbS.41gi32y.cn/PoSt/1118_45878.HtM  
BbS.xk7ehlo.cn/PoSt/1118_01078.HtM  
BbS.kq762s8.cn/PoSt/1118_94488.HtM  
BbS.l718213.cn/PoSt/1118_05292.HtM  
BbS.epfsrpr.cn/PoSt/1118_85236.HtM  
BbS.oduz1qq.cn/PoSt/1118_56228.HtM  
BbS.ddtirdr.cn/PoSt/1118_10063.HtM  
BbS.lmq3hz3.cn/PoSt/1118_16992.HtM  
BbS.f7c4rbn.cn/PoSt/1118_40583.HtM  
BbS.c7jt2qk.cn/PoSt/1118_09714.HtM  
BbS.41gi32y.cn/PoSt/1118_10041.HtM  
BbS.xk7ehlo.cn/PoSt/1118_74710.HtM  
BbS.kq762s8.cn/PoSt/1118_46159.HtM  
BbS.l718213.cn/PoSt/1118_07596.HtM  
BbS.epfsrpr.cn/PoSt/1118_72800.HtM  
BbS.oduz1qq.cn/PoSt/1118_46078.HtM  
BbS.ddtirdr.cn/PoSt/1118_75708.HtM  
BbS.lmq3hz3.cn/PoSt/1118_15390.HtM  
BbS.f7c4rbn.cn/PoSt/1118_89008.HtM  
BbS.c7jt2qk.cn/PoSt/1118_54597.HtM  
BbS.41gi32y.cn/PoSt/1118_03033.HtM  
BbS.xk7ehlo.cn/PoSt/1118_85233.HtM  
BbS.kq762s8.cn/PoSt/1118_82028.HtM  
BbS.l718213.cn/PoSt/1118_15939.HtM  
BbS.epfsrpr.cn/PoSt/1118_25712.HtM  
BbS.oduz1qq.cn/PoSt/1118_60693.HtM  
BbS.ddtirdr.cn/PoSt/1118_19654.HtM  
BbS.lmq3hz3.cn/PoSt/1118_14853.HtM  
BbS.f7c4rbn.cn/PoSt/1118_13399.HtM  
BbS.c7jt2qk.cn/PoSt/1118_79278.HtM  
BbS.41gi32y.cn/PoSt/1118_82193.HtM  
BbS.xk7ehlo.cn/PoSt/1118_19920.HtM  
BbS.kq762s8.cn/PoSt/1118_36536.HtM  
BbS.l718213.cn/PoSt/1118_72931.HtM  
BbS.epfsrpr.cn/PoSt/1118_95034.HtM  
BbS.oduz1qq.cn/PoSt/1118_76802.HtM  
BbS.ddtirdr.cn/PoSt/1118_65608.HtM  
BbS.lmq3hz3.cn/PoSt/1118_91495.HtM  
BbS.f7c4rbn.cn/PoSt/1118_97804.HtM  
BbS.c7jt2qk.cn/PoSt/1118_22200.HtM  
BbS.41gi32y.cn/PoSt/1118_13489.HtM  
BbS.xk7ehlo.cn/PoSt/1118_06426.HtM  
BbS.kq762s8.cn/PoSt/1118_02860.HtM  
BbS.l718213.cn/PoSt/1118_46136.HtM  
BbS.epfsrpr.cn/PoSt/1118_62996.HtM  
BbS.oduz1qq.cn/PoSt/1118_08819.HtM  
BbS.ddtirdr.cn/PoSt/1118_90072.HtM  
BbS.lmq3hz3.cn/PoSt/1118_33256.HtM  
BbS.f7c4rbn.cn/PoSt/1118_79468.HtM  
BbS.c7jt2qk.cn/PoSt/1118_29864.HtM  
BbS.41gi32y.cn/PoSt/1118_46301.HtM  
BbS.xk7ehlo.cn/PoSt/1118_25723.HtM  
BbS.kq762s8.cn/PoSt/1118_75784.HtM
继续阅读 »

Uni-Grid二次进入样式问题深度解析与解决方案
一、uni-grid组件概述
uni-grid是uni-app框架中用于实现网格布局的UI组件,特别适用于展示多个项目或产品的场景。它可以将子元素按照行和列的网格方式进行自动排列,保持布局的整齐和一致性。uni-grid组件提供灵活的布局选项,包括网格大小的设定、行列的对齐方式、间距调整等,使开发者能够在设计UI时保持美观性
1
2

‌主要应用场景‌:

电商分类商品列表展示
功能入口按钮布局
新闻资讯卡片展示
多项目对比展示
二、二次进入样式问题表现
uni-grid在二次进入页面时常见的样式问题主要包括:

‌少一列现象‌:第二次进入页面时,网格布局的最后一列可能消失或显示不全
7
‌样式闪烁‌:页面切换时出现短暂的布局错乱或闪烁现象
‌字节小程序嵌套问题‌:在字节跳动小程序中,由于自定义组件多一层嵌套,可能导致布局失效
8
‌边框显示异常‌:二次进入时边框可能错位或消失
‌间距变化‌:网格项之间的间距在二次进入时可能不一致
三、问题原因分析

  1. 布局计算机制
    uni-grid在首次渲染时会根据当前容器尺寸计算布局,但二次进入时可能由于以下原因导致计算不准确:

容器尺寸变化未被正确检测
缓存了错误的布局参数
响应式更新机制延迟

  1. 平台差异
    不同平台对CSS Grid布局的支持程度不同,特别是小程序环境存在额外的渲染层,可能导致样式表现不一致
    8

  2. 组件内部实现
    uni-grid组件在某些版本中存在以下问题:

列数计算逻辑缺陷
状态管理不完善
样式重置不彻底
四、解决方案与最佳实践

  1. 基础解决方案
    ‌方案一:去除边框‌

html
Copy Code
<column="4" :highlight="true" :show-border="false">
<!-- 网格项内容 -->
</uni-grid>`` 通过设置show-border="false"`可以避免边框相关的问题:ml-citation{ref="7" data="citationList"}。

方案二:固定外层容器宽度


<view style="width: 100%;">  
  <uni-grid :column="4">  
    <!-- 网格项内容 -->  
  </uni-grid>  
</view>  
2. 字节小程序特殊处理  
对于字节小程序中的嵌套问题,可以使用以下方案:  

‌方案一:使用customStyle属性  
BbS.rasyi45.cn/PoSt/1118_19299.HtM  
BbS.by00ez4.cn/PoSt/1118_37172.HtM  
BbS.azlqul5.cn/PoSt/1118_18151.HtM  
BbS.z5tiiyy.cn/PoSt/1118_83137.HtM  
BbS.n9trnzh.cn/PoSt/1118_20556.HtM  
BbS.38zp1cm.cn/PoSt/1118_67206.HtM  
BbS.na2xy0k.cn/PoSt/1118_48017.HtM  
BbS.vb5kftl.cn/PoSt/1118_70297.HtM  
BbS.cjn8dgi.cn/PoSt/1118_41500.HtM  
BbS.bhkgwzx.cn/PoSt/1118_03535.HtM  
BbS.rasyi45.cn/PoSt/1118_69627.HtM  
BbS.by00ez4.cn/PoSt/1118_51140.HtM  
BbS.azlqul5.cn/PoSt/1118_24675.HtM  
BbS.z5tiiyy.cn/PoSt/1118_48794.HtM  
BbS.n9trnzh.cn/PoSt/1118_05781.HtM  
BbS.38zp1cm.cn/PoSt/1118_78901.HtM  
BbS.na2xy0k.cn/PoSt/1118_14040.HtM  
BbS.vb5kftl.cn/PoSt/1118_77932.HtM  
BbS.cjn8dgi.cn/PoSt/1118_08901.HtM  
BbS.bhkgwzx.cn/PoSt/1118_11627.HtM  
BbS.rasyi45.cn/PoSt/1118_25034.HtM  
BbS.by00ez4.cn/PoSt/1118_40190.HtM  
BbS.azlqul5.cn/PoSt/1118_52596.HtM  
BbS.z5tiiyy.cn/PoSt/1118_95405.HtM  
BbS.n9trnzh.cn/PoSt/1118_58926.HtM  
BbS.38zp1cm.cn/PoSt/1118_55895.HtM  
BbS.na2xy0k.cn/PoSt/1118_60516.HtM  
BbS.vb5kftl.cn/PoSt/1118_83011.HtM  
BbS.cjn8dgi.cn/PoSt/1118_65087.HtM  
BbS.bhkgwzx.cn/PoSt/1118_11916.HtM  
BbS.rasyi45.cn/PoSt/1118_50730.HtM  
BbS.by00ez4.cn/PoSt/1118_87660.HtM  
BbS.azlqul5.cn/PoSt/1118_98032.HtM  
BbS.z5tiiyy.cn/PoSt/1118_57044.HtM  
BbS.n9trnzh.cn/PoSt/1118_11285.HtM  
BbS.38zp1cm.cn/PoSt/1118_65869.HtM  
BbS.na2xy0k.cn/PoSt/1118_77049.HtM  
BbS.vb5kftl.cn/PoSt/1118_28621.HtM  
BbS.cjn8dgi.cn/PoSt/1118_07305.HtM  
BbS.bhkgwzx.cn/PoSt/1118_50869.HtM  
BbS.rasyi45.cn/PoSt/1118_63530.HtM  
BbS.by00ez4.cn/PoSt/1118_55851.HtM  
BbS.azlqul5.cn/PoSt/1118_33005.HtM  
BbS.z5tiiyy.cn/PoSt/1118_64993.HtM  
BbS.n9trnzh.cn/PoSt/1118_35153.HtM  
BbS.38zp1cm.cn/PoSt/1118_18891.HtM  
BbS.na2xy0k.cn/PoSt/1118_17872.HtM  
BbS.vb5kftl.cn/PoSt/1118_94456.HtM  
BbS.cjn8dgi.cn/PoSt/1118_91569.HtM  
BbS.bhkgwzx.cn/PoSt/1118_83731.HtM  
BbS.rasyi45.cn/PoSt/1118_08124.HtM  
BbS.by00ez4.cn/PoSt/1118_96290.HtM  
BbS.azlqul5.cn/PoSt/1118_95198.HtM  
BbS.z5tiiyy.cn/PoSt/1118_45924.HtM  
BbS.n9trnzh.cn/PoSt/1118_42449.HtM  
BbS.38zp1cm.cn/PoSt/1118_35483.HtM  
BbS.na2xy0k.cn/PoSt/1118_88432.HtM  
BbS.vb5kftl.cn/PoSt/1118_73893.HtM  
BbS.cjn8dgi.cn/PoSt/1118_49010.HtM  
BbS.bhkgwzx.cn/PoSt/1118_57819.HtM  
BbS.rasyi45.cn/PoSt/1118_97562.HtM  
BbS.by00ez4.cn/PoSt/1118_28059.HtM  
BbS.azlqul5.cn/PoSt/1118_34118.HtM  
BbS.z5tiiyy.cn/PoSt/1118_36384.HtM  
BbS.n9trnzh.cn/PoSt/1118_90347.HtM  
BbS.38zp1cm.cn/PoSt/1118_34379.HtM  
BbS.na2xy0k.cn/PoSt/1118_41241.HtM  
BbS.vb5kftl.cn/PoSt/1118_42674.HtM  
BbS.cjn8dgi.cn/PoSt/1118_62028.HtM  
BbS.bhkgwzx.cn/PoSt/1118_53898.HtM  
BbS.rasyi45.cn/PoSt/1118_98630.HtM  
BbS.by00ez4.cn/PoSt/1118_90659.HtM  
BbS.azlqul5.cn/PoSt/1118_02696.HtM  
BbS.z5tiiyy.cn/PoSt/1118_41148.HtM  
BbS.n9trnzh.cn/PoSt/1118_40116.HtM  
BbS.38zp1cm.cn/PoSt/1118_06465.HtM  
BbS.na2xy0k.cn/PoSt/1118_59674.HtM  
BbS.vb5kftl.cn/PoSt/1118_48963.HtM  
BbS.cjn8dgi.cn/PoSt/1118_98155.HtM  
BbS.bhkgwzx.cn/PoSt/1118_51029.HtM  
BbS.rasyi45.cn/PoSt/1118_69314.HtM  
BbS.by00ez4.cn/PoSt/1118_49963.HtM  
BbS.azlqul5.cn/PoSt/1118_89278.HtM  
BbS.z5tiiyy.cn/PoSt/1118_36703.HtM  
BbS.n9trnzh.cn/PoSt/1118_88376.HtM  
BbS.38zp1cm.cn/PoSt/1118_03169.HtM  
BbS.na2xy0k.cn/PoSt/1118_07021.HtM  
BbS.vb5kftl.cn/PoSt/1118_35500.HtM  
BbS.cjn8dgi.cn/PoSt/1118_55419.HtM  
BbS.bhkgwzx.cn/PoSt/1118_77222.HtM  
BbS.rasyi45.cn/PoSt/1118_40900.HtM  
BbS.by00ez4.cn/PoSt/1118_37648.HtM  
BbS.azlqul5.cn/PoSt/1118_11859.HtM  
BbS.z5tiiyy.cn/PoSt/1118_90260.HtM  
BbS.n9trnzh.cn/PoSt/1118_62521.HtM  
BbS.38zp1cm.cn/PoSt/1118_68146.HtM  
BbS.na2xy0k.cn/PoSt/1118_31363.HtM  
BbS.vb5kftl.cn/PoSt/1118_38681.HtM  
BbS.cjn8dgi.cn/PoSt/1118_71651.HtM  
BbS.bhkgwzx.cn/PoSt/1118_56266.HtM  
BbS.l718213.cn/PoSt/1118_76575.HtM  
BbS.epfsrpr.cn/PoSt/1118_76972.HtM  
BbS.oduz1qq.cn/PoSt/1118_45901.HtM  
BbS.ddtirdr.cn/PoSt/1118_07782.HtM  
BbS.lmq3hz3.cn/PoSt/1118_69345.HtM  
BbS.f7c4rbn.cn/PoSt/1118_12542.HtM  
BbS.c7jt2qk.cn/PoSt/1118_11716.HtM  
BbS.41gi32y.cn/PoSt/1118_40553.HtM  
BbS.xk7ehlo.cn/PoSt/1118_18905.HtM  
BbS.kq762s8.cn/PoSt/1118_33956.HtM  
BbS.l718213.cn/PoSt/1118_46747.HtM  
BbS.epfsrpr.cn/PoSt/1118_36572.HtM  
BbS.oduz1qq.cn/PoSt/1118_78843.HtM  
BbS.ddtirdr.cn/PoSt/1118_29709.HtM  
BbS.lmq3hz3.cn/PoSt/1118_92419.HtM  
BbS.f7c4rbn.cn/PoSt/1118_74738.HtM  
BbS.c7jt2qk.cn/PoSt/1118_25708.HtM  
BbS.41gi32y.cn/PoSt/1118_47655.HtM  
BbS.xk7ehlo.cn/PoSt/1118_71516.HtM  
BbS.kq762s8.cn/PoSt/1118_35833.HtM  
BbS.l718213.cn/PoSt/1118_34632.HtM  
BbS.epfsrpr.cn/PoSt/1118_83859.HtM  
BbS.oduz1qq.cn/PoSt/1118_69403.HtM  
BbS.ddtirdr.cn/PoSt/1118_83844.HtM  
BbS.lmq3hz3.cn/PoSt/1118_76641.HtM  
BbS.f7c4rbn.cn/PoSt/1118_18984.HtM  
BbS.c7jt2qk.cn/PoSt/1118_20607.HtM  
BbS.41gi32y.cn/PoSt/1118_80898.HtM  
BbS.xk7ehlo.cn/PoSt/1118_29387.HtM  
BbS.kq762s8.cn/PoSt/1118_08148.HtM  
BbS.l718213.cn/PoSt/1118_75732.HtM  
BbS.epfsrpr.cn/PoSt/1118_87415.HtM  
BbS.oduz1qq.cn/PoSt/1118_57533.HtM  
BbS.ddtirdr.cn/PoSt/1118_47368.HtM  
BbS.lmq3hz3.cn/PoSt/1118_32119.HtM  
BbS.f7c4rbn.cn/PoSt/1118_95661.HtM  
BbS.c7jt2qk.cn/PoSt/1118_38416.HtM  
BbS.41gi32y.cn/PoSt/1118_28348.HtM  
BbS.xk7ehlo.cn/PoSt/1118_72894.HtM  
BbS.kq762s8.cn/PoSt/1118_72739.HtM  
BbS.l718213.cn/PoSt/1118_42117.HtM  
BbS.epfsrpr.cn/PoSt/1118_91418.HtM  
BbS.oduz1qq.cn/PoSt/1118_79382.HtM  
BbS.ddtirdr.cn/PoSt/1118_37447.HtM  
BbS.lmq3hz3.cn/PoSt/1118_64596.HtM  
BbS.f7c4rbn.cn/PoSt/1118_47359.HtM  
BbS.c7jt2qk.cn/PoSt/1118_71352.HtM  
BbS.41gi32y.cn/PoSt/1118_45878.HtM  
BbS.xk7ehlo.cn/PoSt/1118_01078.HtM  
BbS.kq762s8.cn/PoSt/1118_94488.HtM  
BbS.l718213.cn/PoSt/1118_05292.HtM  
BbS.epfsrpr.cn/PoSt/1118_85236.HtM  
BbS.oduz1qq.cn/PoSt/1118_56228.HtM  
BbS.ddtirdr.cn/PoSt/1118_10063.HtM  
BbS.lmq3hz3.cn/PoSt/1118_16992.HtM  
BbS.f7c4rbn.cn/PoSt/1118_40583.HtM  
BbS.c7jt2qk.cn/PoSt/1118_09714.HtM  
BbS.41gi32y.cn/PoSt/1118_10041.HtM  
BbS.xk7ehlo.cn/PoSt/1118_74710.HtM  
BbS.kq762s8.cn/PoSt/1118_46159.HtM  
BbS.l718213.cn/PoSt/1118_07596.HtM  
BbS.epfsrpr.cn/PoSt/1118_72800.HtM  
BbS.oduz1qq.cn/PoSt/1118_46078.HtM  
BbS.ddtirdr.cn/PoSt/1118_75708.HtM  
BbS.lmq3hz3.cn/PoSt/1118_15390.HtM  
BbS.f7c4rbn.cn/PoSt/1118_89008.HtM  
BbS.c7jt2qk.cn/PoSt/1118_54597.HtM  
BbS.41gi32y.cn/PoSt/1118_03033.HtM  
BbS.xk7ehlo.cn/PoSt/1118_85233.HtM  
BbS.kq762s8.cn/PoSt/1118_82028.HtM  
BbS.l718213.cn/PoSt/1118_15939.HtM  
BbS.epfsrpr.cn/PoSt/1118_25712.HtM  
BbS.oduz1qq.cn/PoSt/1118_60693.HtM  
BbS.ddtirdr.cn/PoSt/1118_19654.HtM  
BbS.lmq3hz3.cn/PoSt/1118_14853.HtM  
BbS.f7c4rbn.cn/PoSt/1118_13399.HtM  
BbS.c7jt2qk.cn/PoSt/1118_79278.HtM  
BbS.41gi32y.cn/PoSt/1118_82193.HtM  
BbS.xk7ehlo.cn/PoSt/1118_19920.HtM  
BbS.kq762s8.cn/PoSt/1118_36536.HtM  
BbS.l718213.cn/PoSt/1118_72931.HtM  
BbS.epfsrpr.cn/PoSt/1118_95034.HtM  
BbS.oduz1qq.cn/PoSt/1118_76802.HtM  
BbS.ddtirdr.cn/PoSt/1118_65608.HtM  
BbS.lmq3hz3.cn/PoSt/1118_91495.HtM  
BbS.f7c4rbn.cn/PoSt/1118_97804.HtM  
BbS.c7jt2qk.cn/PoSt/1118_22200.HtM  
BbS.41gi32y.cn/PoSt/1118_13489.HtM  
BbS.xk7ehlo.cn/PoSt/1118_06426.HtM  
BbS.kq762s8.cn/PoSt/1118_02860.HtM  
BbS.l718213.cn/PoSt/1118_46136.HtM  
BbS.epfsrpr.cn/PoSt/1118_62996.HtM  
BbS.oduz1qq.cn/PoSt/1118_08819.HtM  
BbS.ddtirdr.cn/PoSt/1118_90072.HtM  
BbS.lmq3hz3.cn/PoSt/1118_33256.HtM  
BbS.f7c4rbn.cn/PoSt/1118_79468.HtM  
BbS.c7jt2qk.cn/PoSt/1118_29864.HtM  
BbS.41gi32y.cn/PoSt/1118_46301.HtM  
BbS.xk7ehlo.cn/PoSt/1118_25723.HtM  
BbS.kq762s8.cn/PoSt/1118_75784.HtM
收起阅读 »

招聘双端原生开发 上海

招聘

插件开发 + uni小程序SDK开发

插件开发 + uni小程序SDK开发

漫步广州天河,很开心

漫步广州天河,很开心

漫步广州天河,很开心

开源VUE盲盒小程序源码多端二开搭建(app+h5+pc+小程序)带数码商城和交友盲盒系统

源码

  本文将围绕盲盒小程序源码的设计、实现及运维过程,详细介绍从项目构思到最终上线的全流程,旨在为读者提供一个全面的参考和指导。
  源码设计:n.ymzan.top
  一、项目背景与需求分析
  1.1 项目背景
  盲盒小程序旨在为用户提供一个线上购买和开启盲盒的平台,用户可以通过小程序轻松购买盲盒,并在开启后获得随机的商品。这种新颖的消费模式不仅满足了用户的猎奇心理,还通过社交分享等功能增强了用户之间的互动和粘性。
  1.2 需求分析
  在项目启动前,我们进行了详细的需求分析,主要包括以下几个方面:
  用户注册与登录:用户可以通过邮箱或手机号进行注册,支持第三方社交账号登录。
  盲盒购买:用户可以在小程序中浏览盲盒列表,选择心仪的盲盒进行购买,支持多种支付方式。
  盲盒开启:用户购买盲盒后,可以立即开启,系统根据预设的概率算法决定用户获得的商品。
  商品展示:展示盲盒内的商品信息,包括图片、描述、价格等。
  订单管理:用户可以查看自己的购买记录和订单状态,支持订单跟踪和售后服务。
  社交分享:用户可以将自己的开箱体验分享到社交平台,增加用户之间的互动和传播。
  二、技术选型与架构设计
  2.1 技术选型
  基于项目的需求,我们选择了以下技术栈进行开发:
  前端:uniapp。uniapp 是一个使用 Vue.js 开发所有前端应用的框架,支持编译到 iOS、Android、H5、以及各种小程序等多个平台,极大地提高了开发效率。
  后端:PHP TP6 框架。TP6 是一个现代化的 PHP 后端开发框架,拥有简洁的语法、丰富的功能组件和高效的性能,适合快速开发企业级应用。
  数据库:MySQL。MySQL 是一个流行的关系型数据库管理系统,支持大型数据库和事务处理,能够满足本项目的数据存储需求。
  2.2 架构设计
  项目的整体架构采用前后端分离的模式,前端负责页面展示和用户交互,后端负责业务逻辑处理和数据库操作。具体架构如下:
  前端:使用 uniapp 开发,包括页面设计、用户交互、API 接口调用等。
  后端:使用 PHP TP6 框架,包括用户注册登录、盲盒购买逻辑、数据库操作等。
  数据库:使用 MySQL 存储用户信息、盲盒信息、商品信息、订单信息等数据。
  三、开发实现
  3.1 前端开发
  3.1.1 用户注册与登录
  在 pages 文件夹下创建 register 和 login 页面,分别用于用户注册和登录。使用 uniapp 提供的表单组件和 API 接口调用功能,实现用户信息的提交和验证。
  vue
  // register.vue
  async submitForm() {
  const formData = {
  username: this.username,
  password: this.password,
  };
  try {
  const res = await uni.request({
  url: '/api/user/register',
  method: 'POST',
  data: formData,
  });
  if (res.data.code === 0) {
  uni.showToast({
  title: '注册成功',
  icon: 'success',
  });
  this.$router.push('/pages/login');
  } else {
  uni.showToast({
  title: '注册失败',
  icon: 'none',
  });
  }
  } catch (err) {
  console.error(err);
  }
  }
  3.1.2 盲盒购买与开启
  在 pages 文件夹下创建 blindbox 页面,用于展示盲盒列表和购买操作。用户点击购买按钮后,调用后端接口完成购买操作,并实时更新页面状态。
  vue
  // blindbox.vue
  async buyBlindBox(id) {
  try {
  const res = await uni.request({
  url: /api/blindbox/buy/${id},
  method: 'POST',
  });
  if (res.data.code === 0) {
  uni.showToast({
  title: '购买成功',
  icon: 'success',
  });
  this.getBlindBoxList(); // 重新加载盲盒列表
  } else {
  uni.showToast
  ({
  title: '购买失败',
  icon: 'none',
  });
  }
  // 开启盲盒
  if (res.data.opened) {
  this.openBlindBox(res.data.blindboxId);
  }
  } catch (err) {
  console.error(err);
  uni.showToast({
  title: '网络错误',
  icon: 'none',
  });
  }
  }
  async openBlindBox(blindboxId) {
  try {
  const res = await uni.request({
  url: /api/blindbox/open/${blindboxId},
  method: 'GET',
  });
  if (res.data.code === 0) {
  uni.showModal({
  title: '恭喜你!',
  content: 你获得了${res.data.product.name}!,
  showCancel: false,
  success: () => {
  // 可以添加分享到朋友圈或社交平台的逻辑
  this.shareToFriends(res.data.product);
  }
  });
  } else {
  uni.showToast({
  title: '开启失败',
  icon: 'none',
  });
  }
  } catch (err) {
  console.error(err);
  uni.showToast({
  title: '网络错误',
  icon: 'none',
  });
  }
  }
  shareToFriends(product) {
  uni.share({
  provider: 'weixin', // 指定分享到微信
  title: 我获得了${product.name}!,
  path: '/pages/blindbox/detail?productId=' + product.id, // 分享的页面路径
  success: () => {
  uni.showToast({
  title: '分享成功',
  icon: 'success',
  });
  },
  fail: () => {
  uni.showToast({
  title: '分享失败',
  icon: 'none',
  });
  }
  });
  }
  ### 3.2 后端开发
  #### 3.2.1 用户注册与登录
  在 PHP TP6 框架中,创建 User 模型和 UserController 控制器来处理用户注册和登录的逻辑。
  ```php
  // UserController.php
  public function register(Request $request)
  {
  $data = $request->post();
  $user = new User();
  $user->username = $data['username'];
  $user->password = password_hash($data['password'], PASSWORD_DEFAULT);
  if ($user->save()) {
  return json(['code' => 0, 'msg' => '注册成功']);
  } else {
  return json(['code' => 1, 'msg' => '注册失败']);
  }
  }
  public function login(Request $request)
  {
  $data = $request->post();
  $user = User::where('username', $data['username'])->find();
  if ($user && password_verify($data['password'], $user->password)) {
  // 生成Token等操作
  return json(['code' => 0, 'msg' => '登录成功', 'token' => 'your_token_here']);
  } else {
  return json(['code' => 1, 'msg' => '用户名或密码错误']);
  }
  }
  3.2.2 盲盒购买与开启
  在 BlindBox 模型和 BlindBoxController 控制器中处理盲盒的购买和开启逻辑。
  php
  // BlindBoxController.php
  public function buy($id, Request $request)
  {
  // 验证用户身份、库存等
  // ...
  $blindbox = BlindBox::find($id);
  if (!$blindbox || $blindbox->stock <= 0) {
  return json(['code' => 1, 'msg' => '盲盒不存在或库存不足']);
  }
  // 减库存、创建订单等操作
  $blindbox->stock--;
  $blindbox->save();
  // 假设这里直接开启盲盒
  $product = $this->openBlindBox($blindbox);
  return json([
  'code' => 0,
  'msg' => '购买成功',
  'opened' => true,
  'blindboxId' => $blindbox->id,
  'product' => $product,)

继续阅读 »

  本文将围绕盲盒小程序源码的设计、实现及运维过程,详细介绍从项目构思到最终上线的全流程,旨在为读者提供一个全面的参考和指导。
  源码设计:n.ymzan.top
  一、项目背景与需求分析
  1.1 项目背景
  盲盒小程序旨在为用户提供一个线上购买和开启盲盒的平台,用户可以通过小程序轻松购买盲盒,并在开启后获得随机的商品。这种新颖的消费模式不仅满足了用户的猎奇心理,还通过社交分享等功能增强了用户之间的互动和粘性。
  1.2 需求分析
  在项目启动前,我们进行了详细的需求分析,主要包括以下几个方面:
  用户注册与登录:用户可以通过邮箱或手机号进行注册,支持第三方社交账号登录。
  盲盒购买:用户可以在小程序中浏览盲盒列表,选择心仪的盲盒进行购买,支持多种支付方式。
  盲盒开启:用户购买盲盒后,可以立即开启,系统根据预设的概率算法决定用户获得的商品。
  商品展示:展示盲盒内的商品信息,包括图片、描述、价格等。
  订单管理:用户可以查看自己的购买记录和订单状态,支持订单跟踪和售后服务。
  社交分享:用户可以将自己的开箱体验分享到社交平台,增加用户之间的互动和传播。
  二、技术选型与架构设计
  2.1 技术选型
  基于项目的需求,我们选择了以下技术栈进行开发:
  前端:uniapp。uniapp 是一个使用 Vue.js 开发所有前端应用的框架,支持编译到 iOS、Android、H5、以及各种小程序等多个平台,极大地提高了开发效率。
  后端:PHP TP6 框架。TP6 是一个现代化的 PHP 后端开发框架,拥有简洁的语法、丰富的功能组件和高效的性能,适合快速开发企业级应用。
  数据库:MySQL。MySQL 是一个流行的关系型数据库管理系统,支持大型数据库和事务处理,能够满足本项目的数据存储需求。
  2.2 架构设计
  项目的整体架构采用前后端分离的模式,前端负责页面展示和用户交互,后端负责业务逻辑处理和数据库操作。具体架构如下:
  前端:使用 uniapp 开发,包括页面设计、用户交互、API 接口调用等。
  后端:使用 PHP TP6 框架,包括用户注册登录、盲盒购买逻辑、数据库操作等。
  数据库:使用 MySQL 存储用户信息、盲盒信息、商品信息、订单信息等数据。
  三、开发实现
  3.1 前端开发
  3.1.1 用户注册与登录
  在 pages 文件夹下创建 register 和 login 页面,分别用于用户注册和登录。使用 uniapp 提供的表单组件和 API 接口调用功能,实现用户信息的提交和验证。
  vue
  // register.vue
  async submitForm() {
  const formData = {
  username: this.username,
  password: this.password,
  };
  try {
  const res = await uni.request({
  url: '/api/user/register',
  method: 'POST',
  data: formData,
  });
  if (res.data.code === 0) {
  uni.showToast({
  title: '注册成功',
  icon: 'success',
  });
  this.$router.push('/pages/login');
  } else {
  uni.showToast({
  title: '注册失败',
  icon: 'none',
  });
  }
  } catch (err) {
  console.error(err);
  }
  }
  3.1.2 盲盒购买与开启
  在 pages 文件夹下创建 blindbox 页面,用于展示盲盒列表和购买操作。用户点击购买按钮后,调用后端接口完成购买操作,并实时更新页面状态。
  vue
  // blindbox.vue
  async buyBlindBox(id) {
  try {
  const res = await uni.request({
  url: /api/blindbox/buy/${id},
  method: 'POST',
  });
  if (res.data.code === 0) {
  uni.showToast({
  title: '购买成功',
  icon: 'success',
  });
  this.getBlindBoxList(); // 重新加载盲盒列表
  } else {
  uni.showToast
  ({
  title: '购买失败',
  icon: 'none',
  });
  }
  // 开启盲盒
  if (res.data.opened) {
  this.openBlindBox(res.data.blindboxId);
  }
  } catch (err) {
  console.error(err);
  uni.showToast({
  title: '网络错误',
  icon: 'none',
  });
  }
  }
  async openBlindBox(blindboxId) {
  try {
  const res = await uni.request({
  url: /api/blindbox/open/${blindboxId},
  method: 'GET',
  });
  if (res.data.code === 0) {
  uni.showModal({
  title: '恭喜你!',
  content: 你获得了${res.data.product.name}!,
  showCancel: false,
  success: () => {
  // 可以添加分享到朋友圈或社交平台的逻辑
  this.shareToFriends(res.data.product);
  }
  });
  } else {
  uni.showToast({
  title: '开启失败',
  icon: 'none',
  });
  }
  } catch (err) {
  console.error(err);
  uni.showToast({
  title: '网络错误',
  icon: 'none',
  });
  }
  }
  shareToFriends(product) {
  uni.share({
  provider: 'weixin', // 指定分享到微信
  title: 我获得了${product.name}!,
  path: '/pages/blindbox/detail?productId=' + product.id, // 分享的页面路径
  success: () => {
  uni.showToast({
  title: '分享成功',
  icon: 'success',
  });
  },
  fail: () => {
  uni.showToast({
  title: '分享失败',
  icon: 'none',
  });
  }
  });
  }
  ### 3.2 后端开发
  #### 3.2.1 用户注册与登录
  在 PHP TP6 框架中,创建 User 模型和 UserController 控制器来处理用户注册和登录的逻辑。
  ```php
  // UserController.php
  public function register(Request $request)
  {
  $data = $request->post();
  $user = new User();
  $user->username = $data['username'];
  $user->password = password_hash($data['password'], PASSWORD_DEFAULT);
  if ($user->save()) {
  return json(['code' => 0, 'msg' => '注册成功']);
  } else {
  return json(['code' => 1, 'msg' => '注册失败']);
  }
  }
  public function login(Request $request)
  {
  $data = $request->post();
  $user = User::where('username', $data['username'])->find();
  if ($user && password_verify($data['password'], $user->password)) {
  // 生成Token等操作
  return json(['code' => 0, 'msg' => '登录成功', 'token' => 'your_token_here']);
  } else {
  return json(['code' => 1, 'msg' => '用户名或密码错误']);
  }
  }
  3.2.2 盲盒购买与开启
  在 BlindBox 模型和 BlindBoxController 控制器中处理盲盒的购买和开启逻辑。
  php
  // BlindBoxController.php
  public function buy($id, Request $request)
  {
  // 验证用户身份、库存等
  // ...
  $blindbox = BlindBox::find($id);
  if (!$blindbox || $blindbox->stock <= 0) {
  return json(['code' => 1, 'msg' => '盲盒不存在或库存不足']);
  }
  // 减库存、创建订单等操作
  $blindbox->stock--;
  $blindbox->save();
  // 假设这里直接开启盲盒
  $product = $this->openBlindBox($blindbox);
  return json([
  'code' => 0,
  'msg' => '购买成功',
  'opened' => true,
  'blindboxId' => $blindbox->id,
  'product' => $product,)

收起阅读 »

基于微信/抖音开发的开源游戏小程序源码搭建

小程序

  欢迎来到我们的代码共享网站上激动人心的 HTML5 游戏世界!此类别致力于为您提供一系列迷人的前端代码片段,直接为您的网络浏览器带来交互式游戏体验。无论您是经验丰富的开发人员还是刚刚开始编码之旅,我们的 HTML5 游戏部分都提供实时预览、分步教程和可下载链接的令人愉快的组合,以帮助您了解和创建自己的游戏项目。

  源码及演示:y.wxlbyx.icu

  安装游戏小程序源码步骤
  
  1. 下载源码:首先,您需要从开发者提供的来源下载游戏小程序的源代码。通常,这些源代码会以压缩文件的形式提供,您可以将其保存到您的计算机上的一个文件夹中。
  
  2. 解压源码:解压下载的源码压缩文件。在解压缩之后,您应该能够看到一个包含游戏小程序的文件夹。
  
  3. 配置开发环境:在安装源码之前,您需要先配置好开发环境。对于小程序开发,您需要安装微信开发者工具。您可以从微信官方网站上下载并安装该工具。
  
  4. 导入项目:打开微信开发者工具,并选择“导入项目”选项。然后,选择源码文件夹,并填写项目相关的信息,如项目名称、AppID等。
  
  5. 编译和运行:导入项目后,您可以进行编译和运行。点击工具栏中的“编译”按钮可以将源码编译成小程序,并在右侧的预览窗口中显示运行结果。
  
  6. 调试和修改:如果在编译和运行过程中出现错误或问题,您可以使用微信开发者工具提供的调试工具来查找和修复问题。可以查看开发者工具文档以了解更多关于调试和修改源码的信息。
  
  通过以上步骤,您就能够成功安装和运行游戏小程序的源码。

   

  
  结语
  
  借助 HTML5、CSS 和 JavaScript 的强大力量,我们精选的游戏展示了前端 Web 开发的创造潜力。每个代码片段都带有实时预览,让您可以直接在我们的网站上玩和体验游戏。当您沉浸在动感十足的冒险中、解决令人费解的谜题或享受经典街机游戏的怀旧时刻时,感受肾上腺素的激增。
  
  但这还不是全部!我们的 HTML5 游戏部分更进一步,为每个游戏提供详细的教程。我们相信培育学习社区,这些分步指南将引导您完成代码实现,解释所使用的逻辑和技术。无论您是想了解平台游戏中的碰撞检测如何工作,还是想了解如何创建引人入胜的动画,我们的教程都能满足您的需求。
  
  更好的是所有前端代码都可以轻松下载。您可以访问每个游戏的源代码,进行试验,并修改它以满足您的喜好。这是一个绝佳的机会,可以学习现有项目、定制它们,甚至将它们用作您自己的游戏开发之旅的起点。想象一下,你拥有创造自己迷你游戏的魔力。你可以决定角色如何移动,他们的样子,以及当你赢或输时会发生什么。

继续阅读 »

  欢迎来到我们的代码共享网站上激动人心的 HTML5 游戏世界!此类别致力于为您提供一系列迷人的前端代码片段,直接为您的网络浏览器带来交互式游戏体验。无论您是经验丰富的开发人员还是刚刚开始编码之旅,我们的 HTML5 游戏部分都提供实时预览、分步教程和可下载链接的令人愉快的组合,以帮助您了解和创建自己的游戏项目。

  源码及演示:y.wxlbyx.icu

  安装游戏小程序源码步骤
  
  1. 下载源码:首先,您需要从开发者提供的来源下载游戏小程序的源代码。通常,这些源代码会以压缩文件的形式提供,您可以将其保存到您的计算机上的一个文件夹中。
  
  2. 解压源码:解压下载的源码压缩文件。在解压缩之后,您应该能够看到一个包含游戏小程序的文件夹。
  
  3. 配置开发环境:在安装源码之前,您需要先配置好开发环境。对于小程序开发,您需要安装微信开发者工具。您可以从微信官方网站上下载并安装该工具。
  
  4. 导入项目:打开微信开发者工具,并选择“导入项目”选项。然后,选择源码文件夹,并填写项目相关的信息,如项目名称、AppID等。
  
  5. 编译和运行:导入项目后,您可以进行编译和运行。点击工具栏中的“编译”按钮可以将源码编译成小程序,并在右侧的预览窗口中显示运行结果。
  
  6. 调试和修改:如果在编译和运行过程中出现错误或问题,您可以使用微信开发者工具提供的调试工具来查找和修复问题。可以查看开发者工具文档以了解更多关于调试和修改源码的信息。
  
  通过以上步骤,您就能够成功安装和运行游戏小程序的源码。

   

  
  结语
  
  借助 HTML5、CSS 和 JavaScript 的强大力量,我们精选的游戏展示了前端 Web 开发的创造潜力。每个代码片段都带有实时预览,让您可以直接在我们的网站上玩和体验游戏。当您沉浸在动感十足的冒险中、解决令人费解的谜题或享受经典街机游戏的怀旧时刻时,感受肾上腺素的激增。
  
  但这还不是全部!我们的 HTML5 游戏部分更进一步,为每个游戏提供详细的教程。我们相信培育学习社区,这些分步指南将引导您完成代码实现,解释所使用的逻辑和技术。无论您是想了解平台游戏中的碰撞检测如何工作,还是想了解如何创建引人入胜的动画,我们的教程都能满足您的需求。
  
  更好的是所有前端代码都可以轻松下载。您可以访问每个游戏的源代码,进行试验,并修改它以满足您的喜好。这是一个绝佳的机会,可以学习现有项目、定制它们,甚至将它们用作您自己的游戏开发之旅的起点。想象一下,你拥有创造自己迷你游戏的魔力。你可以决定角色如何移动,他们的样子,以及当你赢或输时会发生什么。

收起阅读 »

支付的云开发是否封装了requestVirtualPayment,微信的虚拟支付?

微信支付

支付的云开发是否封装了requestVirtualPayment,微信的虚拟支付?

如果没有什么时候加上啊,急需

支付的云开发是否封装了requestVirtualPayment,微信的虚拟支付?

如果没有什么时候加上啊,急需

音频组件uni.createInnerAudioContext(),android播放声音,来回切换10+次就没有声音了

连续点播放10+以上就没有声音了,原来是创建的实例没有销毁的问题
var innerAudioContext = uni.createInnerAudioContext();
innerAudioContext.autoplay = true;
innerAudioContext.src = '..//souds/waitpay.mp3';

innerAudioContext.onPlay(() => {
console.log('开始播放');
});

innerAudioContext.onError((res) => {
console.log('播放出错');
console.log(res.errMsg);
console.log(res.errCode);
innerAudioContext.destroy();
});

innerAudioContext.onPause((res) => {
console.log('播放完成');
innerAudioContext.destroy();//这句话
innerAudioContext.src = '';
});

继续阅读 »

连续点播放10+以上就没有声音了,原来是创建的实例没有销毁的问题
var innerAudioContext = uni.createInnerAudioContext();
innerAudioContext.autoplay = true;
innerAudioContext.src = '..//souds/waitpay.mp3';

innerAudioContext.onPlay(() => {
console.log('开始播放');
});

innerAudioContext.onError((res) => {
console.log('播放出错');
console.log(res.errMsg);
console.log(res.errCode);
innerAudioContext.destroy();
});

innerAudioContext.onPause((res) => {
console.log('播放完成');
innerAudioContext.destroy();//这句话
innerAudioContext.src = '';
});

收起阅读 »

微信小程序隐私协议最新弹框解决方案

隐私协议 微信小程序

公众号文章:
https://mp.weixin.qq.com/s?__biz=MzIyNjE5ODA5NA==&mid=2247487487&idx=1&sn=36269ceb84a1ffb0a91f10a711b274cb&chksm=e87558dedf02d1c867f0a9fad1344d7bd7dc5542849543caf824051d56b89763b9a3e242efca#rd

代码片段:
https://developers.weixin.qq.com/s/VGANOSmb7VKl

继续阅读 »

公众号文章:
https://mp.weixin.qq.com/s?__biz=MzIyNjE5ODA5NA==&mid=2247487487&idx=1&sn=36269ceb84a1ffb0a91f10a711b274cb&chksm=e87558dedf02d1c867f0a9fad1344d7bd7dc5542849543caf824051d56b89763b9a3e242efca#rd

代码片段:
https://developers.weixin.qq.com/s/VGANOSmb7VKl

收起阅读 »

#creatcavascontext这个是小程序的废弃接口

升级更新

creatcavascontext这个是小程序的废弃接口

https://uniapp.dcloud.net.cn/api/canvas/createCanvasContext.html#createcanvascontext

https://developers.weixin.qq.com/miniprogram/dev/api/canvas/wx.createCanvasContext.html


继续阅读 »

creatcavascontext这个是小程序的废弃接口

https://uniapp.dcloud.net.cn/api/canvas/createCanvasContext.html#createcanvascontext

https://developers.weixin.qq.com/miniprogram/dev/api/canvas/wx.createCanvasContext.html


收起阅读 »

实用小程序源码下载开发(附2万套uniapp小程序游戏源代码)

小程序

  从技术上讲,微信小程序游戏框架在小程序框架中加入了程序游戏库API。因此,小程序游戏只能在小程序环境下运行,既不是原生程序游戏也不是HTML5程序游戏。也就是说,小程序游戏与HTML5程序游戏紧密相关,面向HTML5程序游戏开发者——很大程度上采用了WebGL、JavaScript等HTML5技术,将HTML5程序游戏转为微信小程序游戏的工作量降到最低。
  
  源码:casgams.top/gm
  
  玩家主要通过以下渠道进入小程序游戏:
  
  ●好友或微信群邀请
  
  ●扫描程序游戏二维码
  
  ●最近玩过的程序游戏显示在小程序历史记录中,或者拉下聊天收件箱后
  
  ●发现 > 小程序,然后搜索小程序游戏
  
  ●发现 > 程序游戏 > 我的小程序游戏,然后搜索“小程序游戏”
  
  搜索“小程序游戏”(小程序游戏)将显示小程序游戏的简短列表。单击“显示完整列表”会将您带到一个隐藏的小程序游戏菜单,该菜单按最热门的程序游戏和朋友正在玩的程序游戏分类。
  
  简而言之,微信小程序游戏:
  
  1、在微信环境下运行
  
  2、使用 HTML5 和相关网络技术
  
  3、提供类似于原生程序游戏的程序游戏体验
  
  ●微信小程序游戏相对于其他类型的程序游戏有很多优势。两个最大的优势是*稳定性和可管理性。
  
  ●与原生程序游戏相比,微信的应用程序作为一个独立的平台,将用户留在微信生态系统中。
  
  结论
  
  微信小程序游戏结合了强大的获取渠道、社交程序游戏和分享以及庞大的用户群——同时无需下载任何东西即可享受近乎原生的应用体验。
  
  所有这些特性都显示了微信小程序游戏的光明前景。现在就轮到你们这些程序游戏开发者利用这个机会,打造最适合微信用户的程序游戏了!
  
  微信小程序游戏开发基础
  
  上文提到,小程序游戏的开发涉及到HTML5,熟悉HTML5的开发者上手很快——短时间内将HTML5程序游戏变成微信小程序游戏。
  
  具体来说,微信小程序游戏的开发技术可以分为三个部分:
  
  相比HTML5程序游戏,小程序游戏玩家不会被弹窗广告打扰,体验更佳。
  
  微信小程序游戏环境的一大优势是兼容HTML5程序游戏生态。也就是说,HTML5程序游戏可以更方便的转化为微信小程序游戏,不管你用什么程序游戏引擎开发的。这使得微信小程序游戏能够利用现有的大型 HTML5 生态系统的力量。
  
  除了技术优势外,微信小程序游戏还利用了这样一个事实,即它是中国最受欢迎的社交平台,能够让应用病毒式传播。小程序游戏设计的一个关键部分是利用微信的社交特性来获取新用户。
  
  微信小程序游戏主要通过好友推荐或分享链接被发现。这使得小程序游戏与以往的网页程序游戏通过广告或传统渠道获取用户到应用商店或下载链接有很大不同。
  
  第1部分。底层技术
  
  一、编程语言——微信小程序游戏只支持JavaScript(Web的主要编程语言),但也支持可以编译成JavaScript的语言,如TypeScript、CoffeeScript。
  
  其次是微信小程序游戏框架支持的JavaScript API(应用程序接口):Canvas 2D和WebGL 1.0。这些 API 中的任何一个都可用于绘制图形、创建动画或实时渲染。但是您不想同时使用一种以上的技术。另请注意,只有 WebGL 支持 3D 渲染。
  
  第2部分。中间件:程序游戏引擎
  
  直接使用 Canvas 2D 或 WebGL 制作小程序游戏有一个陡峭的学习曲线。由于您可能不想花费超过一年的时间来开发一款程序游戏,因此使用 HTML5 程序游戏引擎是一个非常明智的选择。程序游戏引擎提供的高级功能可以大大降低开发者的入门门槛,缩短开发时间。
  
  国内三大程序游戏引擎厂商Cocos Creator、Egret、Laya已经支持微信小程序游戏。目前国外流行的 HTML5 程序游戏引擎如Phaser.js、Three.js还没有直接支持,但还是可以适配使用(比如这个Phaser port for Mini Games)。
  
  三、微信SDK(软件开发包)
  
  微信小程序游戏为开发者提供了丰富的微信登录、分享、排行榜等社交功能的使用工具。
  
  了解微信小程序游戏底层结构
  
  小程序游戏既不是原生程序游戏,也不等同于 HTML5 程序游戏。但是,它的开发环境与这两种类型的程序游戏有关。小程序游戏使用HTML5相同的渲染接口。
  
  小程序游戏实际上运行在微信App的原生环境中。程序游戏的JavaScript代码不是在浏览器环境中执行的,而是在移动设备的JS VM层上的一个独立的JavaScript引擎。在 Android 平台上,它使用Google 的 V8 引擎,而在 iOS 上,它使用苹果的 JavaScript Core 引擎。
  
  当然,JS(JavaScript)引擎只负责JS逻辑的编译和运行,并没有渲染接口。
  
  小程序游戏开发者如何将他们的程序游戏连接到渲染界面,以及微信框架中提供的许多其他功能?
  
  引入了 JS-Native 脚本绑定。该技术可以桥接原生语言接口(iOS / Android 库)到脚本接口(JavaScript 库),并将 API 调用从脚本层转发到原生层以使用原生平台功能。
  
  微信JavaScript SDK已经在使用绑定技术,让微信公众号和小程序通过JavaScript API实现相册、传感器等原生设备功能。
  
  微信小程序游戏还使用绑定技术将原生平台(iOS / Android)的服务:渲染、用户数据、网络、音频和视频连接到 JavaScript 环境。小程序游戏层模块就是这样访问上图中的原生函数的。
  
  通过支持 JavaScript 环境,微信提供了一个框架,可以将 HTML5 程序游戏转换为微信小程序游戏。但一些 API 兼容性问题可能是由于缺乏真正的浏览器环境和 DOM 而引起的。
  
  为了降低 HTML5 程序游戏转小程序游戏的成本,微信团队还提供了一个“适配”脚本来支持浏览器 API。支持 HTML5 程序游戏所需的大多数浏览器功能 - 从而提高兼容性。
  
  Adapter 脚本提供了 HTML5 程序游戏所依赖的大多数浏览器界面。
  
  上图展示了微信小程序游戏中开发者可用的所有接口
  
  ●渲染界面
  
  ●浏览器适配器接口
  
  ●微信服务的微信API
  
  请注意,Browser Adapter 接口不再由官方维护,因此任何附加功能都由开发人员决定。而且它的大部分依赖DOM的功能在小程序游戏环境下是不起作用的。
  
  使用程序游戏引擎
  
  由于开发栈的复杂性,一种选择是使用程序游戏引擎开发小程序游戏。程序游戏引擎不仅将常用的程序游戏功能封装在一个高阶接口上,还试图解决H5浏览器程序游戏与微信小程序游戏环境不兼容的问题。
  
  开发人员可能需要使用不同层次的库——这取决于程序游戏的复杂性。使用程序游戏引擎时,它会为开发人员提供高级功能,同时调用这些相同的库。然后,开发人员需要学习引擎,并处理引擎未提供所有所需功能的情况。
  
  以下是程序游戏引擎提供的好处摘要:
  
  框架特点:
  
  ●对常见程序游戏开发特性的高度封装
  
  ●资源加载
  
  ●事件处理
  
  ●媒体和广播
  
  ●屏幕显示与控制
  
  ●用户输入
  
  ●附加接口,例如用于 TileMap 的 DOM 解析器
  
  编辑:
  
  ●优化程序员、设计师和经理之间的协作。
  
  ●一个好的程序游戏编辑器可以显着缩短开发周期。
  
  一般的:
  
  ●优秀的程序游戏引擎可以提供高设备兼容性和稳定的性能;
  
  ●跨平台程序游戏引擎可以让开发者同时发布HTML5程序游戏、微信小程序游戏和原生程序游戏。
  
  高效的程序游戏编辑器可以降低开发成本和维护成本。对于程序游戏开发商而言,这些因素可能是盈利的关键。
  
  4.开始搭建调试小程序游戏!
  
  Step 1. 获取微信开发者工具
  
  微信小程序开发者工具提供了编写、调试和运行小程序游戏的框架。在微信开发者网站这里下载。
  
  首次运行开发者工具时,系统会要求您使用微信帐号登录。然后您将看到用于创建您的第一个项目的表单。
  
  点击:“体验”右侧的“小程序游戏”(尝试:小程序游戏)
  
  并为源代码选择一个位置项目目录,然后将您的项目命名为项目名称。
  
  ●页面顶部是工具栏。它可以配置、编译、预览和部署程序游戏。
  
  ●左边是模拟器。程序游戏随着代码的变化而运行和更新。
  
  ●右上角是代码编辑器。
  
  ●编辑器的左侧是文件菜单。它列出了项目文件。
  
  ●右下方是调试器。它的功能类似于Chrome开发者工具!
  
  Step 2. 微信小程序游戏配置及文件导入
  
  在微信小程序游戏工程中,添加配置文件project.config.json和game.json。
  
  ●project.config.json定义您的程序游戏 AppID、名称、版本、IDE 设置和运行时配置。
  
  ●game.json提供应用程序和代码的内部配置,例如设备方向和网络超时。这个类似于微信小程序中的app.json文件!
  
  由于小程序游戏不支持 HTML 文件,入口在game.js中。您可以通过使用 require 函数将程序游戏引擎和程序游戏脚本引入game.js文件来启动程序游戏。注意: require函数的使用遵循Node.js的规范!
  
  步骤 3. 编译、测试和提交
  
  微信开发工具会监控脚本和配置的变化,实时更新程序游戏。您也可以点击页面顶部的编译按钮手动重新编译。当您需要在智能手机上预览程序游戏和测试时,您可以点击预览按钮生成二维码并扫描以玩程序游戏!
  
  生成二维码的过程其实就是压缩一个小包上传到微信CDN,所以需要一定的时间。
  
  如果微信小程序游戏遵循与小程序相同的分发规则,那么微信可能会在小程序游戏提交后对其进行审核——然后才能公开发布。也会有关于如何像小程序一样发现或分享小程序游戏的规则。

继续阅读 »

  从技术上讲,微信小程序游戏框架在小程序框架中加入了程序游戏库API。因此,小程序游戏只能在小程序环境下运行,既不是原生程序游戏也不是HTML5程序游戏。也就是说,小程序游戏与HTML5程序游戏紧密相关,面向HTML5程序游戏开发者——很大程度上采用了WebGL、JavaScript等HTML5技术,将HTML5程序游戏转为微信小程序游戏的工作量降到最低。
  
  源码:casgams.top/gm
  
  玩家主要通过以下渠道进入小程序游戏:
  
  ●好友或微信群邀请
  
  ●扫描程序游戏二维码
  
  ●最近玩过的程序游戏显示在小程序历史记录中,或者拉下聊天收件箱后
  
  ●发现 > 小程序,然后搜索小程序游戏
  
  ●发现 > 程序游戏 > 我的小程序游戏,然后搜索“小程序游戏”
  
  搜索“小程序游戏”(小程序游戏)将显示小程序游戏的简短列表。单击“显示完整列表”会将您带到一个隐藏的小程序游戏菜单,该菜单按最热门的程序游戏和朋友正在玩的程序游戏分类。
  
  简而言之,微信小程序游戏:
  
  1、在微信环境下运行
  
  2、使用 HTML5 和相关网络技术
  
  3、提供类似于原生程序游戏的程序游戏体验
  
  ●微信小程序游戏相对于其他类型的程序游戏有很多优势。两个最大的优势是*稳定性和可管理性。
  
  ●与原生程序游戏相比,微信的应用程序作为一个独立的平台,将用户留在微信生态系统中。
  
  结论
  
  微信小程序游戏结合了强大的获取渠道、社交程序游戏和分享以及庞大的用户群——同时无需下载任何东西即可享受近乎原生的应用体验。
  
  所有这些特性都显示了微信小程序游戏的光明前景。现在就轮到你们这些程序游戏开发者利用这个机会,打造最适合微信用户的程序游戏了!
  
  微信小程序游戏开发基础
  
  上文提到,小程序游戏的开发涉及到HTML5,熟悉HTML5的开发者上手很快——短时间内将HTML5程序游戏变成微信小程序游戏。
  
  具体来说,微信小程序游戏的开发技术可以分为三个部分:
  
  相比HTML5程序游戏,小程序游戏玩家不会被弹窗广告打扰,体验更佳。
  
  微信小程序游戏环境的一大优势是兼容HTML5程序游戏生态。也就是说,HTML5程序游戏可以更方便的转化为微信小程序游戏,不管你用什么程序游戏引擎开发的。这使得微信小程序游戏能够利用现有的大型 HTML5 生态系统的力量。
  
  除了技术优势外,微信小程序游戏还利用了这样一个事实,即它是中国最受欢迎的社交平台,能够让应用病毒式传播。小程序游戏设计的一个关键部分是利用微信的社交特性来获取新用户。
  
  微信小程序游戏主要通过好友推荐或分享链接被发现。这使得小程序游戏与以往的网页程序游戏通过广告或传统渠道获取用户到应用商店或下载链接有很大不同。
  
  第1部分。底层技术
  
  一、编程语言——微信小程序游戏只支持JavaScript(Web的主要编程语言),但也支持可以编译成JavaScript的语言,如TypeScript、CoffeeScript。
  
  其次是微信小程序游戏框架支持的JavaScript API(应用程序接口):Canvas 2D和WebGL 1.0。这些 API 中的任何一个都可用于绘制图形、创建动画或实时渲染。但是您不想同时使用一种以上的技术。另请注意,只有 WebGL 支持 3D 渲染。
  
  第2部分。中间件:程序游戏引擎
  
  直接使用 Canvas 2D 或 WebGL 制作小程序游戏有一个陡峭的学习曲线。由于您可能不想花费超过一年的时间来开发一款程序游戏,因此使用 HTML5 程序游戏引擎是一个非常明智的选择。程序游戏引擎提供的高级功能可以大大降低开发者的入门门槛,缩短开发时间。
  
  国内三大程序游戏引擎厂商Cocos Creator、Egret、Laya已经支持微信小程序游戏。目前国外流行的 HTML5 程序游戏引擎如Phaser.js、Three.js还没有直接支持,但还是可以适配使用(比如这个Phaser port for Mini Games)。
  
  三、微信SDK(软件开发包)
  
  微信小程序游戏为开发者提供了丰富的微信登录、分享、排行榜等社交功能的使用工具。
  
  了解微信小程序游戏底层结构
  
  小程序游戏既不是原生程序游戏,也不等同于 HTML5 程序游戏。但是,它的开发环境与这两种类型的程序游戏有关。小程序游戏使用HTML5相同的渲染接口。
  
  小程序游戏实际上运行在微信App的原生环境中。程序游戏的JavaScript代码不是在浏览器环境中执行的,而是在移动设备的JS VM层上的一个独立的JavaScript引擎。在 Android 平台上,它使用Google 的 V8 引擎,而在 iOS 上,它使用苹果的 JavaScript Core 引擎。
  
  当然,JS(JavaScript)引擎只负责JS逻辑的编译和运行,并没有渲染接口。
  
  小程序游戏开发者如何将他们的程序游戏连接到渲染界面,以及微信框架中提供的许多其他功能?
  
  引入了 JS-Native 脚本绑定。该技术可以桥接原生语言接口(iOS / Android 库)到脚本接口(JavaScript 库),并将 API 调用从脚本层转发到原生层以使用原生平台功能。
  
  微信JavaScript SDK已经在使用绑定技术,让微信公众号和小程序通过JavaScript API实现相册、传感器等原生设备功能。
  
  微信小程序游戏还使用绑定技术将原生平台(iOS / Android)的服务:渲染、用户数据、网络、音频和视频连接到 JavaScript 环境。小程序游戏层模块就是这样访问上图中的原生函数的。
  
  通过支持 JavaScript 环境,微信提供了一个框架,可以将 HTML5 程序游戏转换为微信小程序游戏。但一些 API 兼容性问题可能是由于缺乏真正的浏览器环境和 DOM 而引起的。
  
  为了降低 HTML5 程序游戏转小程序游戏的成本,微信团队还提供了一个“适配”脚本来支持浏览器 API。支持 HTML5 程序游戏所需的大多数浏览器功能 - 从而提高兼容性。
  
  Adapter 脚本提供了 HTML5 程序游戏所依赖的大多数浏览器界面。
  
  上图展示了微信小程序游戏中开发者可用的所有接口
  
  ●渲染界面
  
  ●浏览器适配器接口
  
  ●微信服务的微信API
  
  请注意,Browser Adapter 接口不再由官方维护,因此任何附加功能都由开发人员决定。而且它的大部分依赖DOM的功能在小程序游戏环境下是不起作用的。
  
  使用程序游戏引擎
  
  由于开发栈的复杂性,一种选择是使用程序游戏引擎开发小程序游戏。程序游戏引擎不仅将常用的程序游戏功能封装在一个高阶接口上,还试图解决H5浏览器程序游戏与微信小程序游戏环境不兼容的问题。
  
  开发人员可能需要使用不同层次的库——这取决于程序游戏的复杂性。使用程序游戏引擎时,它会为开发人员提供高级功能,同时调用这些相同的库。然后,开发人员需要学习引擎,并处理引擎未提供所有所需功能的情况。
  
  以下是程序游戏引擎提供的好处摘要:
  
  框架特点:
  
  ●对常见程序游戏开发特性的高度封装
  
  ●资源加载
  
  ●事件处理
  
  ●媒体和广播
  
  ●屏幕显示与控制
  
  ●用户输入
  
  ●附加接口,例如用于 TileMap 的 DOM 解析器
  
  编辑:
  
  ●优化程序员、设计师和经理之间的协作。
  
  ●一个好的程序游戏编辑器可以显着缩短开发周期。
  
  一般的:
  
  ●优秀的程序游戏引擎可以提供高设备兼容性和稳定的性能;
  
  ●跨平台程序游戏引擎可以让开发者同时发布HTML5程序游戏、微信小程序游戏和原生程序游戏。
  
  高效的程序游戏编辑器可以降低开发成本和维护成本。对于程序游戏开发商而言,这些因素可能是盈利的关键。
  
  4.开始搭建调试小程序游戏!
  
  Step 1. 获取微信开发者工具
  
  微信小程序开发者工具提供了编写、调试和运行小程序游戏的框架。在微信开发者网站这里下载。
  
  首次运行开发者工具时,系统会要求您使用微信帐号登录。然后您将看到用于创建您的第一个项目的表单。
  
  点击:“体验”右侧的“小程序游戏”(尝试:小程序游戏)
  
  并为源代码选择一个位置项目目录,然后将您的项目命名为项目名称。
  
  ●页面顶部是工具栏。它可以配置、编译、预览和部署程序游戏。
  
  ●左边是模拟器。程序游戏随着代码的变化而运行和更新。
  
  ●右上角是代码编辑器。
  
  ●编辑器的左侧是文件菜单。它列出了项目文件。
  
  ●右下方是调试器。它的功能类似于Chrome开发者工具!
  
  Step 2. 微信小程序游戏配置及文件导入
  
  在微信小程序游戏工程中,添加配置文件project.config.json和game.json。
  
  ●project.config.json定义您的程序游戏 AppID、名称、版本、IDE 设置和运行时配置。
  
  ●game.json提供应用程序和代码的内部配置,例如设备方向和网络超时。这个类似于微信小程序中的app.json文件!
  
  由于小程序游戏不支持 HTML 文件,入口在game.js中。您可以通过使用 require 函数将程序游戏引擎和程序游戏脚本引入game.js文件来启动程序游戏。注意: require函数的使用遵循Node.js的规范!
  
  步骤 3. 编译、测试和提交
  
  微信开发工具会监控脚本和配置的变化,实时更新程序游戏。您也可以点击页面顶部的编译按钮手动重新编译。当您需要在智能手机上预览程序游戏和测试时,您可以点击预览按钮生成二维码并扫描以玩程序游戏!
  
  生成二维码的过程其实就是压缩一个小包上传到微信CDN,所以需要一定的时间。
  
  如果微信小程序游戏遵循与小程序相同的分发规则,那么微信可能会在小程序游戏提交后对其进行审核——然后才能公开发布。也会有关于如何像小程序一样发现或分享小程序游戏的规则。

收起阅读 »