uview-plus 3.8.106 → 3.8.112
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/changelog.md +80 -0
- package/components/u-action-sheet/u-action-sheet.vue +3 -1
- package/components/u-calendar/u-calendar.vue +3 -1
- package/components/u-canvas/u-canvas.vue +67 -8
- package/components/u-cate-tab/u-cate-tab.vue +2 -2
- package/components/u-color-picker/u-color-picker.vue +2 -2
- package/components/u-cropper/u-cropper.vue +78 -70
- package/components/u-datetime-picker/u-datetime-picker.vue +3 -1
- package/components/u-goods-sku/u-goods-sku.vue +2 -1
- package/components/u-keyboard/u-keyboard.vue +2 -1
- package/components/u-lazy-load/u-lazy-load.vue +5 -3
- package/components/u-navbar/navbar.js +3 -1
- package/components/u-navbar/props.js +10 -0
- package/components/u-navbar/theme-vars.scss +5 -0
- package/components/u-navbar/u-navbar.vue +155 -12
- package/components/u-picker/u-picker.vue +3 -1
- package/components/u-picker-data/u-picker-data.vue +3 -2
- package/components/u-popup/u-popup.vue +38 -5
- package/components/u-poster/u-poster.vue +37 -4
- package/components/u-sticky/u-sticky.vue +2 -2
- package/libs/function/index.js +18 -0
- package/libs/theme/runtime.js +4 -0
- package/libs/theme/theme.js +6 -2
- package/libs/util/gcanvas/bridge/bridge-weex.js +0 -0
- package/libs/util/gcanvas/context-2d/FillStyleLinearGradient.js +0 -0
- package/libs/util/gcanvas/context-2d/FillStylePattern.js +0 -0
- package/libs/util/gcanvas/context-2d/FillStyleRadialGradient.js +0 -0
- package/libs/util/gcanvas/context-2d/RenderingContext.js +0 -0
- package/libs/util/gcanvas/context-webgl/ActiveInfo.js +0 -0
- package/libs/util/gcanvas/context-webgl/Buffer.js +0 -0
- package/libs/util/gcanvas/context-webgl/Framebuffer.js +0 -0
- package/libs/util/gcanvas/context-webgl/GLenum.js +0 -0
- package/libs/util/gcanvas/context-webgl/GLmethod.js +0 -0
- package/libs/util/gcanvas/context-webgl/GLtype.js +0 -0
- package/libs/util/gcanvas/context-webgl/Program.js +0 -0
- package/libs/util/gcanvas/context-webgl/Renderbuffer.js +0 -0
- package/libs/util/gcanvas/context-webgl/RenderingContext.js +0 -0
- package/libs/util/gcanvas/context-webgl/Shader.js +0 -0
- package/libs/util/gcanvas/context-webgl/ShaderPrecisionFormat.js +0 -0
- package/libs/util/gcanvas/context-webgl/Texture.js +0 -0
- package/libs/util/gcanvas/context-webgl/UniformLocation.js +0 -0
- package/libs/util/gcanvas/context-webgl/classUtils.js +0 -0
- package/libs/util/gcanvas/env/canvas.js +0 -0
- package/libs/util/gcanvas/env/image.js +0 -0
- package/libs/util/gcanvas/env/tool.js +0 -0
- package/libs/util/gcanvas/index.js +0 -0
- package/package.json +1 -1
- package/types/comps/actionSheet.d.ts +4 -0
- package/types/comps/calendar.d.ts +4 -0
- package/types/comps/datetimePicker.d.ts +4 -0
- package/types/comps/keyboard.d.ts +4 -0
- package/types/comps/navbar.d.ts +13 -0
- package/types/comps/picker.d.ts +4 -0
- package/types/comps/popup.d.ts +6 -2
- package/types/func.d.ts +11 -0
- package/types/index.d.ts +1 -0
package/changelog.md
CHANGED
|
@@ -1,3 +1,83 @@
|
|
|
1
|
+
## 3.8.112
|
|
2
|
+
feat: navbar 新增 iOS 大标题模式
|
|
3
|
+
|
|
4
|
+
新增 `mode` 属性,`ios` 值提供现代 iOS 系统应用的导航栏体验:进入页面时导航栏背景透明、标题以 34px 左对齐显示;向下滚动时大标题被压缩进导航栏,标题过渡为常规居中形态,同时出现毛玻璃磨砂背景。
|
|
5
|
+
|
|
6
|
+
- 新增 `mode` 属性,可选 `default`(默认)与 `ios`,非法值按 `default` 处理
|
|
7
|
+
- 新增 `scrollTop` 属性接收页面滚动距离,需由页面 `onPageScroll` 传入;不传时停留在大标题展开态
|
|
8
|
+
- 大标题渲染在 in-flow 层靠原生滚动位移,不经过 JS,小程序端不会因 setData 回程产生拖影
|
|
9
|
+
- 磨砂采用 0.82 不透明底色叠加 `backdrop-filter`:支持的端得到真实毛玻璃,不支持的端仍有 82% 不透明底色兜住文字可读性
|
|
10
|
+
- 玻璃与居中标题的透明度曲线分段递进(0-0.5 与 0.75-1),确保任何滚动位置都不出现两段标题文字互相透出
|
|
11
|
+
- 居中标题在淡入的同时由下方 12px 上浮就位,并带 0.15s 过渡补齐离散滚动事件之间的空隙
|
|
12
|
+
- 新增 `--up-navbar-glass-bg-color` 与 `--up-navbar-glass-blur` 主题变量,跟随明暗模式切换
|
|
13
|
+
- 新增 verify:navbar-ios-mode 校验脚本
|
|
14
|
+
|
|
15
|
+
已知边界:`ios` 模式下 `fixed` 与 `placeholder` 被忽略——固定层恒定固定,in-flow 层恒定渲染,因为该层承载的是大标题这一实际内容而非可选占位。nvue 端因缺少 filter 管线、页面非原生滚动容器、`onPageScroll` 不可靠三项约束,传入 `mode="ios"` 时整体降级为 `default`。
|
|
16
|
+
|
|
17
|
+
`default` 模式的结构、样式与属性语义完全不变。
|
|
18
|
+
|
|
19
|
+
## 3.8.111
|
|
20
|
+
fix: 修复小程序端使用交叉观察器组件时控制台报枚举实例键告警(#864)
|
|
21
|
+
|
|
22
|
+
小程序端 `uni.createIntersectionObserver(this)` 会把 Vue 实例代理直接透传给原生 API,原生内部的 `Object.keys(vm)` 命中 Vue 开发模式下的 ownKeys 拦截,从而输出告警:
|
|
23
|
+
`[Vue warn]: Avoid app logic that relies on enumerating keys on a component instance.`
|
|
24
|
+
根因是 uni-app 只为 `createSelectorQuery` 做了 `$scope` 解包,一直没有为 `createIntersectionObserver` 做同样处理。
|
|
25
|
+
|
|
26
|
+
- 新增 `upCreateIntersectionObserver(comp, options)` 公共方法:优先调用组件实例上的同名方法(内部已完成实例解包,不会外泄代理),APP 端实例上没有该方法时回退到全局 API
|
|
27
|
+
- u-lazy-load、u-sticky、u-cate-tab 三个组件改用该方法,小程序端不再产生告警
|
|
28
|
+
- u-sticky 的 `thresholds: [0.95, 0.98, 1]` 原样透传。注意不能改传 `comp.$scope`:APP 端页面的 `$scope` 仅为 `{ $getAppWebview }`,会被全局 API 误判成 options 参数,导致真实配置被静默丢弃
|
|
29
|
+
- u-parse/node 的观察器位于 `#ifdef H5 || APP-PLUS` 条件编译块内,不会编译进小程序,故保持不变
|
|
30
|
+
- 补充 `upCreateIntersectionObserver` 类型定义,新增 verify:up-create-intersection-observer 校验脚本
|
|
31
|
+
|
|
32
|
+
组件对外行为不变,APP 端调用路径与配置均保持原样。
|
|
33
|
+
|
|
34
|
+
## 3.8.110
|
|
35
|
+
feat: cropper 支持外部图片路径直接裁剪(#897)
|
|
36
|
+
|
|
37
|
+
- `chooseImage` 第二个参数新增 `imageSrc`,可传业务拍照或选图得到的本地临时路径并直接开始裁剪
|
|
38
|
+
- 有效 `imageSrc` 会跳过组件内置 `uni.chooseImage`;未传、空字符串或非字符串仍保持原选图行为
|
|
39
|
+
- 外部路径与系统选图复用同一套图片信息读取、裁剪框初始化和绘制流程
|
|
40
|
+
- “重选”按钮仍打开系统图片选择器;远程地址继续受目标平台读取能力和 H5 跨域限制
|
|
41
|
+
|
|
42
|
+
## 3.8.109
|
|
43
|
+
feat: popup 关闭事件补齐,新增 closed 事件(#902)
|
|
44
|
+
|
|
45
|
+
close 此前只在点击遮罩、点击关闭图标时发出。外部直接把 show 置为 false 时组件内部没有走过关闭动作,不会发出任何事件,业务侧就少了一个"弹窗已关闭"的统一监听点。
|
|
46
|
+
|
|
47
|
+
- u-popup: show 由 true 变 false 时补发 close,任意关闭方式都能被监听到。内部关闭走 emitClose(),它先同步置位去重标记再 emit,因此下游在 close 的同步 handler 里修改 show 数据源不会被误判成外部关闭而重复发出
|
|
48
|
+
- u-popup: 新增 closed 事件,接 u-transition 已有但一直无人监听的 afterLeave,在离场动画结束、弹窗真正消失后发出。close 是"开始关闭",closed 是"已关闭"
|
|
49
|
+
- pageInline 模式下 transition 的 show 恒为 true、不执行离场动画,收不到 afterLeave,改由 watch 补发 closed
|
|
50
|
+
- closed 透传到 u-picker、u-datetime-picker、u-action-sheet、u-keyboard、u-calendar、u-color-picker、u-picker-data、u-goods-sku。其中 u-datetime-picker、u-picker-data 包裹的是 u-picker,属二级透传;u-calendar 只从主体 popup 转发,关闭内部时间选择器不会误报
|
|
51
|
+
- 补充 popup/picker/datetimePicker/actionSheet/keyboard/calendar 的 onClosed 类型定义
|
|
52
|
+
- 新增 verify:popup-close-events 校验脚本
|
|
53
|
+
|
|
54
|
+
组件保持纯受控,渲染只依赖 show prop,未引入内部副本,老用户行为不变。
|
|
55
|
+
|
|
56
|
+
已知取舍:业务在 close 里跨 nextTick 才把 show 置为 false 时,close 会发两次。去重标记只在当次更新周期内有效是刻意的,否则残留标记会吞掉后续真实的关闭事件。这类异步确认场景应改用 closed,它只在弹窗真正消失时发出一次。
|
|
57
|
+
|
|
58
|
+
## 3.8.108(2026-08-18)
|
|
59
|
+
fix: 修复鸿蒙二维码不显示、海报文字不换行等绘图问题
|
|
60
|
+
|
|
61
|
+
鸿蒙 CanvasContext.measureText 同步返回值恒为 0,真实宽度只通过可选 callback 经 evalJSAsync 异步回传;
|
|
62
|
+
而 uni-app-plus 走 evalJSSync 同步就能拿到真值。这是同样代码在安卓
|
|
63
|
+
正常、鸿蒙异常的根因。
|
|
64
|
+
|
|
65
|
+
宽度 0 会让 drawTextWithLineClamp 里 `0 <= maxWidth` 恒成立,整段
|
|
66
|
+
文本被当成一行放得下直接输出,标题横穿并压到二维码上。
|
|
67
|
+
|
|
68
|
+
- u-canvas: 新增 #ifdef APP-HARMONY 的 callback 测量分支;measureText
|
|
69
|
+
不再把 0 当有效值外传;新增 estimateTextWidth 兜底
|
|
70
|
+
- u-poster: measureTextWidth 拿到非正数宽度时改用估算,不再 `|| 0` 静默吞掉
|
|
71
|
+
- 兜底估算区分全角/半角(全角 1.0、半角 0.56、空白 0.28)。原先的
|
|
72
|
+
length * fontSize * 0.6 会让中文短算约 40%,仍然不换行
|
|
73
|
+
- callback 超时从 1000ms 降到 300ms,并用 _harmonyMeasureUnavailable
|
|
74
|
+
锁存状态:一次换行要二分测量十几次,逐次干等会把导出拖成十几秒
|
|
75
|
+
- 新增 verify:harmony-poster-text-wrap 校验脚本
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
## 3.8.107(2026-08-18)
|
|
79
|
+
fix: 修复empty示例页面
|
|
80
|
+
|
|
1
81
|
## 3.8.106
|
|
2
82
|
feat: 让 App 原生 nvue 页面完整复用 App.up.vue 根容器
|
|
3
83
|
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
:show="show"
|
|
4
4
|
mode="bottom"
|
|
5
5
|
@close="closeHandler"
|
|
6
|
+
@closed="$emit('closed')"
|
|
6
7
|
:safeAreaInsetBottom="safeAreaInsetBottom"
|
|
7
8
|
:round="round"
|
|
8
9
|
>
|
|
@@ -156,6 +157,7 @@
|
|
|
156
157
|
*
|
|
157
158
|
* @event {Function} select 点击ActionSheet列表项时触发
|
|
158
159
|
* @event {Function} close 点击取消按钮时触发
|
|
160
|
+
* @event {Function} closed 弹窗已关闭(离场动画结束、弹窗真正消失后)触发
|
|
159
161
|
* @event {Function} getuserinfo 用户点击该按钮时,会返回获取到的用户信息,回调的 detail 数据与 wx.getUserInfo 返回的一致,openType="getUserInfo"时有效
|
|
160
162
|
* @event {Function} contact 客服消息回调,openType="contact"时有效
|
|
161
163
|
* @event {Function} getphonenumber 获取用户手机号回调,openType="getPhoneNumber"时有效
|
|
@@ -224,7 +226,7 @@
|
|
|
224
226
|
})
|
|
225
227
|
}
|
|
226
228
|
},
|
|
227
|
-
emits: ["close", "select", "update:show"],
|
|
229
|
+
emits: ["close", "closed", "select", "update:show"],
|
|
228
230
|
methods: {
|
|
229
231
|
// 关闭操作菜单事件处理
|
|
230
232
|
closeHandler() {
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
:bgColor="bgColor"
|
|
13
13
|
:closeable="!pageInline"
|
|
14
14
|
@close="close"
|
|
15
|
+
@closed="$emit('closed')"
|
|
15
16
|
:round="round"
|
|
16
17
|
:pageInline="pageInline"
|
|
17
18
|
:closeOnClickOverlay="closeOnClickOverlay"
|
|
@@ -236,6 +237,7 @@ import { t } from '../../libs/i18n'
|
|
|
236
237
|
*
|
|
237
238
|
* @event {Function()} confirm 点击确定按钮时触发 选择日期相关的返回参数
|
|
238
239
|
* @event {Function()} close 日历关闭时触发 可定义页面关闭时的回调事件
|
|
240
|
+
* @event {Function()} closed 日历已关闭(离场动画结束、弹窗真正消失后)触发
|
|
239
241
|
* @example <u-calendar :defaultDate="defaultDateMultiple" :show="show" mode="multiple" @confirm="confirm">
|
|
240
242
|
</u-calendar>
|
|
241
243
|
* */
|
|
@@ -411,7 +413,7 @@ export default {
|
|
|
411
413
|
this.start = Date.now()
|
|
412
414
|
this.init()
|
|
413
415
|
},
|
|
414
|
-
emits: ["confirm", "close"],
|
|
416
|
+
emits: ["confirm", "close", "closed"],
|
|
415
417
|
methods: {
|
|
416
418
|
addUnit,
|
|
417
419
|
padTime(num) {
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
/>
|
|
22
22
|
<!-- #endif -->
|
|
23
23
|
|
|
24
|
-
<!-- #ifdef APP-PLUS -->
|
|
24
|
+
<!-- #ifdef APP-PLUS || APP-HARMONY -->
|
|
25
25
|
<!-- #ifndef APP-NVUE -->
|
|
26
26
|
<canvas
|
|
27
27
|
class="u-canvas__canvas"
|
|
@@ -203,7 +203,7 @@ export default {
|
|
|
203
203
|
size: true
|
|
204
204
|
},
|
|
205
205
|
(res) => {
|
|
206
|
-
// #ifdef APP-PLUS
|
|
206
|
+
// #ifdef APP-PLUS || APP-HARMONY
|
|
207
207
|
resolve(res || {
|
|
208
208
|
width: this.actualWidth,
|
|
209
209
|
height: this.actualHeight
|
|
@@ -232,7 +232,7 @@ export default {
|
|
|
232
232
|
return this._webViewContext;
|
|
233
233
|
// #endif
|
|
234
234
|
|
|
235
|
-
// #ifdef APP-PLUS
|
|
235
|
+
// #ifdef APP-PLUS || APP-HARMONY
|
|
236
236
|
return uni.createCanvasContext(this.canvasId, this);
|
|
237
237
|
// #endif
|
|
238
238
|
|
|
@@ -364,7 +364,7 @@ export default {
|
|
|
364
364
|
measureText: (text, state) => {
|
|
365
365
|
const matched = String(state.font || '').match(/(\d+(?:\.\d+)?)px/);
|
|
366
366
|
const fontSize = matched ? Number(matched[1]) : this.fontSize;
|
|
367
|
-
return { width:
|
|
367
|
+
return { width: this.estimateTextWidth(text, fontSize) };
|
|
368
368
|
}
|
|
369
369
|
});
|
|
370
370
|
this.ctx = this._webViewContext;
|
|
@@ -646,18 +646,77 @@ export default {
|
|
|
646
646
|
}
|
|
647
647
|
return this.callContext('strokeText', String(text), x, y, maxWidth);
|
|
648
648
|
},
|
|
649
|
+
/**
|
|
650
|
+
* 按字形宽度估算文本宽度
|
|
651
|
+
* @description 当平台无法给出真实测量值时的兜底。必须区分全角/半角:
|
|
652
|
+
* 汉字、假名、全角标点约占一个字号,按半角的 0.6 估算会短 40%,
|
|
653
|
+
* 中文海报因此算出"整段都放得下"而不换行。
|
|
654
|
+
* @param {String} text 待测量文本
|
|
655
|
+
* @param {Number} [fontSize] 字号,默认取组件当前字号
|
|
656
|
+
* @returns {Number} 估算宽度(px)
|
|
657
|
+
* @author jry ijry@qq.com
|
|
658
|
+
*/
|
|
659
|
+
estimateTextWidth(text, fontSize) {
|
|
660
|
+
const size = Number(fontSize) || Number(this.fontSize) || 12;
|
|
661
|
+
const FULL_WIDTH = /[ᄀ-ᅟ⺀-〾ぁ-㏿㐀-䶿一-鿿ꀀ-가-힣豈-︰--⦆¢-₩]/;
|
|
662
|
+
return Array.from(String(text)).reduce((width, char) => {
|
|
663
|
+
if (FULL_WIDTH.test(char)) return width + size;
|
|
664
|
+
if (/\s/.test(char)) return width + size * 0.28;
|
|
665
|
+
return width + size * 0.56;
|
|
666
|
+
}, 0);
|
|
667
|
+
},
|
|
649
668
|
measureText(text) {
|
|
650
669
|
if (this.ctx && typeof this.ctx.measureText === 'function') {
|
|
651
|
-
|
|
670
|
+
const metrics = this.ctx.measureText(String(text));
|
|
671
|
+
const width = Number(metrics && metrics.width);
|
|
672
|
+
// 鸿蒙同步测量恒为 0(真实值只走 callback),上下文未就绪时其他
|
|
673
|
+
// 平台也可能返回 0。绝不能把 0 交给调用方——换行逻辑会把它当成
|
|
674
|
+
// "宽度足够",于是整段文本挤成一行。
|
|
675
|
+
if (width > 0) return metrics;
|
|
652
676
|
}
|
|
653
677
|
return {
|
|
654
|
-
width:
|
|
678
|
+
width: this.estimateTextWidth(text)
|
|
655
679
|
};
|
|
656
680
|
},
|
|
657
681
|
measureTextAsync(text) {
|
|
658
682
|
if (this.ctx && typeof this.ctx.measureTextAsync === 'function') {
|
|
659
683
|
return this.ctx.measureTextAsync(String(text));
|
|
660
684
|
}
|
|
685
|
+
|
|
686
|
+
// #ifdef APP-HARMONY
|
|
687
|
+
// 鸿蒙的 CanvasContext.measureText 同步返回值恒为 0,真实宽度只通过
|
|
688
|
+
// callback(webview.evalJSAsync) 回传,因此必须走回调形式。
|
|
689
|
+
if (this.ctx && typeof this.ctx.measureText === 'function' && !this._harmonyMeasureUnavailable) {
|
|
690
|
+
return new Promise((resolve) => {
|
|
691
|
+
let settled = false;
|
|
692
|
+
// evalJSAsync 并非所有鸿蒙版本都提供,回调可能永远不来,
|
|
693
|
+
// 必须兜底避免上层 await 永久挂起。且一旦超时就标记为不可用:
|
|
694
|
+
// 单次换行要二分测量十几次,逐次干等会把导出拖成十几秒。
|
|
695
|
+
const timer = setTimeout(() => {
|
|
696
|
+
if (settled) return;
|
|
697
|
+
settled = true;
|
|
698
|
+
this._harmonyMeasureUnavailable = true;
|
|
699
|
+
resolve({ width: this.estimateTextWidth(text) });
|
|
700
|
+
}, 300);
|
|
701
|
+
const done = (metrics) => {
|
|
702
|
+
if (settled) return;
|
|
703
|
+
settled = true;
|
|
704
|
+
clearTimeout(timer);
|
|
705
|
+
const width = Number(metrics && metrics.width);
|
|
706
|
+
resolve({ width: width > 0 ? width : this.estimateTextWidth(text) });
|
|
707
|
+
};
|
|
708
|
+
try {
|
|
709
|
+
const sync = this.ctx.measureText(String(text), done);
|
|
710
|
+
// 若该平台其实同步返回了有效值,直接采用
|
|
711
|
+
const syncWidth = Number(sync && sync.width);
|
|
712
|
+
if (syncWidth > 0) done(sync);
|
|
713
|
+
} catch (error) {
|
|
714
|
+
done(null);
|
|
715
|
+
}
|
|
716
|
+
});
|
|
717
|
+
}
|
|
718
|
+
// #endif
|
|
719
|
+
|
|
661
720
|
return Promise.resolve(this.measureText(text));
|
|
662
721
|
},
|
|
663
722
|
createLinearGradient(x0, y0, x1, y1) {
|
|
@@ -800,8 +859,8 @@ export default {
|
|
|
800
859
|
let destWidth = hasDestWidth ? options.destWidth : width;
|
|
801
860
|
let destHeight = hasDestHeight ? options.destHeight : height;
|
|
802
861
|
|
|
803
|
-
// MP、H5 和 APP-
|
|
804
|
-
// #ifdef MP || H5 || APP-PLUS
|
|
862
|
+
// MP、H5、APP-PLUS 和 APP-HARMONY 保持逻辑绘制坐标,只提升默认导出像素。
|
|
863
|
+
// #ifdef MP || H5 || APP-PLUS || APP-HARMONY
|
|
805
864
|
if (!hasDestWidth) {
|
|
806
865
|
destWidth = Math.round(width * this.dpr);
|
|
807
866
|
}
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
</view>
|
|
48
48
|
</template>
|
|
49
49
|
<script>
|
|
50
|
-
import { addUnit, sleep } from '../../libs/function/index';
|
|
50
|
+
import { addUnit, sleep, upCreateIntersectionObserver } from '../../libs/function/index';
|
|
51
51
|
export default {
|
|
52
52
|
name: 'up-cate-tab',
|
|
53
53
|
props: {
|
|
@@ -179,7 +179,7 @@
|
|
|
179
179
|
this._observerList = [];
|
|
180
180
|
|
|
181
181
|
this.tabList.map((val, index) => {
|
|
182
|
-
let observer =
|
|
182
|
+
let observer = upCreateIntersectionObserver(this);
|
|
183
183
|
this._observerList.push(observer);
|
|
184
184
|
// 检测相交状态
|
|
185
185
|
observer.relativeTo('.u-cate-tab__right-box', {
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
:style="{backgroundColor: value}" >
|
|
5
5
|
<slot></slot>
|
|
6
6
|
</view>
|
|
7
|
-
<up-popup :show="show" mode="bottom" round="10" @close="close" :closeOnClickOverlay="true">
|
|
7
|
+
<up-popup :show="show" mode="bottom" round="10" @close="close" @closed="$emit('closed')" :closeOnClickOverlay="true">
|
|
8
8
|
<view class="up-color-picker__content">
|
|
9
9
|
<view class="up-color-picker__header">
|
|
10
10
|
<text class="up-color-picker__title">选择颜色</text>
|
|
@@ -267,7 +267,7 @@ export default {
|
|
|
267
267
|
mounted() {
|
|
268
268
|
this.initColor()
|
|
269
269
|
},
|
|
270
|
-
emits: ['update:modelValue', 'confirm', 'close'],
|
|
270
|
+
emits: ['update:modelValue', 'confirm', 'close', 'closed'],
|
|
271
271
|
methods: {
|
|
272
272
|
// 初始化颜色
|
|
273
273
|
initColor() {
|
|
@@ -221,68 +221,71 @@
|
|
|
221
221
|
}
|
|
222
222
|
this.hideImg();
|
|
223
223
|
},
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
this.
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
|
|
224
|
+
loadImage(path) {
|
|
225
|
+
uni.showLoading({ mask: true });
|
|
226
|
+
this.imgPath = path;
|
|
227
|
+
uni.getImageInfo({
|
|
228
|
+
src: path,
|
|
229
|
+
success: r => {
|
|
230
|
+
this.imgWidth = r.width;
|
|
231
|
+
this.imgHeight = r.height;
|
|
232
|
+
this.path = path;
|
|
233
|
+
if (!this.hasSel) {
|
|
234
|
+
let style = this.selStyle || {};
|
|
235
|
+
if (this.arWidth && this.arHeight) {
|
|
236
|
+
let areaWidth = this.arWidth.indexOf('rpx') >= 0 ? parseInt(this.arWidth) * this.pxRatio : parseInt(this.arWidth),
|
|
237
|
+
areaHeight = this.arHeight.indexOf('rpx') >= 0 ? parseInt(this.arHeight) * this.pxRatio : parseInt(this.arHeight);
|
|
238
|
+
style.width = areaWidth + 'px';
|
|
239
|
+
style.height = areaHeight + 'px';
|
|
240
|
+
style.top = (this.windowHeight - areaHeight - tabHeight) / 2 + 'px';
|
|
241
|
+
style.left = (this.windowWidth - areaWidth) / 2 + 'px';
|
|
242
|
+
} else {
|
|
243
|
+
uni.showModal({
|
|
244
|
+
title: t("up.cropper.emptyWidhtOrHeight"),
|
|
245
|
+
showCancel: false
|
|
246
|
+
})
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
this.selStyle = style;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
if (this.noBar) {
|
|
253
|
+
this.drawInit(true);
|
|
254
|
+
} else {
|
|
255
|
+
uni.hideTabBar({
|
|
256
|
+
complete: () => {
|
|
257
|
+
this.drawInit(true);
|
|
258
|
+
}
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
},
|
|
262
|
+
fail: () => {
|
|
263
|
+
uni.showToast({
|
|
264
|
+
title: "error3",
|
|
265
|
+
duration: 2000,
|
|
266
|
+
})
|
|
267
|
+
},
|
|
268
|
+
complete() {
|
|
269
|
+
uni.hideLoading();
|
|
270
|
+
}
|
|
271
|
+
});
|
|
272
|
+
},
|
|
273
|
+
select() {
|
|
274
|
+
if (this.fSelecting) return;
|
|
275
|
+
this.fSelecting = true;
|
|
276
|
+
setTimeout(() => { this.fSelecting = false; }, 500);
|
|
277
|
+
uni.chooseImage({
|
|
278
|
+
count: 1,
|
|
279
|
+
sizeType: ['original', 'compressed'],
|
|
280
|
+
sourceType: ['album', 'camera'],
|
|
281
|
+
success: (r) => {
|
|
282
|
+
this.loadImage(r.tempFilePaths[0]);
|
|
283
|
+
},
|
|
284
|
+
fail: () => {
|
|
285
|
+
this.$emit('cancel')
|
|
286
|
+
}
|
|
287
|
+
})
|
|
288
|
+
},
|
|
286
289
|
async confirm() {
|
|
287
290
|
if (this.fUploading) return;
|
|
288
291
|
this.fUploading = true;
|
|
@@ -725,9 +728,10 @@
|
|
|
725
728
|
uni.hideLoading();
|
|
726
729
|
}
|
|
727
730
|
});
|
|
728
|
-
},
|
|
729
|
-
chooseImage(index = undefined, params = undefined, data = undefined) {
|
|
730
|
-
|
|
731
|
+
},
|
|
732
|
+
chooseImage(index = undefined, params = undefined, data = undefined) {
|
|
733
|
+
const imageSrc = typeof params?.imageSrc === 'string' ? params.imageSrc.trim() : '';
|
|
734
|
+
if (params) {
|
|
731
735
|
console.log(params)
|
|
732
736
|
let areaWidth = params.areaWidth || this.areaWidth,
|
|
733
737
|
areaHeight = params.areaHeight || this.areaHeight,
|
|
@@ -774,11 +778,15 @@
|
|
|
774
778
|
// console.log(this.selStyle);
|
|
775
779
|
this.hasSel = true;
|
|
776
780
|
}
|
|
777
|
-
}
|
|
778
|
-
this.rtn = data;
|
|
779
|
-
this.indx = index;
|
|
780
|
-
|
|
781
|
-
|
|
781
|
+
}
|
|
782
|
+
this.rtn = data;
|
|
783
|
+
this.indx = index;
|
|
784
|
+
if (imageSrc) {
|
|
785
|
+
this.loadImage(imageSrc);
|
|
786
|
+
return;
|
|
787
|
+
}
|
|
788
|
+
this.select();
|
|
789
|
+
},
|
|
782
790
|
rotate() {
|
|
783
791
|
// #ifdef APP-PLUS
|
|
784
792
|
if (this.platform === 'android') {
|
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
:maskClass="maskClass"
|
|
34
34
|
:maskStyle="resolvedMaskStyle"
|
|
35
35
|
@close="close"
|
|
36
|
+
@closed="$emit('closed')"
|
|
36
37
|
@cancel="cancel"
|
|
37
38
|
@confirm="confirm"
|
|
38
39
|
@change="change"
|
|
@@ -93,6 +94,7 @@
|
|
|
93
94
|
* @property {Boolean} closeOnClickOverlay 是否允许点击遮罩关闭选择器 ( 默认 false )
|
|
94
95
|
* @property {Array} defaultIndex 各列的默认索引
|
|
95
96
|
* @event {Function} close 关闭选择器时触发
|
|
97
|
+
* @event {Function} closed 选择器已关闭(离场动画结束、弹窗真正消失后)触发
|
|
96
98
|
* @event {Function} confirm 点击确定按钮,返回当前选择的值
|
|
97
99
|
* @event {Function} change 当选择值变化时触发
|
|
98
100
|
* @event {Function} cancel 点击取消按钮
|
|
@@ -191,7 +193,7 @@
|
|
|
191
193
|
}
|
|
192
194
|
},
|
|
193
195
|
// #ifdef VUE3
|
|
194
|
-
emits: ['close', 'cancel', 'confirm', 'change', 'update:modelValue'],
|
|
196
|
+
emits: ['close', 'closed', 'cancel', 'confirm', 'change', 'update:modelValue'],
|
|
195
197
|
// #endif
|
|
196
198
|
methods: {
|
|
197
199
|
toInt(value, fallback = 0) {
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
:pageInline="pageInline"
|
|
11
11
|
:border-radius="20"
|
|
12
12
|
@close="close"
|
|
13
|
+
@closed="$emit('closed')"
|
|
13
14
|
>
|
|
14
15
|
<view class="up-goods-sku-container" :style="{padding: pageInline ? '0px' : ''}">
|
|
15
16
|
<view class="up-goods-sku__header">
|
|
@@ -175,7 +176,7 @@
|
|
|
175
176
|
},
|
|
176
177
|
watch: {
|
|
177
178
|
},
|
|
178
|
-
emits: ['open', 'confirm', 'close'],
|
|
179
|
+
emits: ['open', 'confirm', 'close', 'closed'],
|
|
179
180
|
created() {
|
|
180
181
|
if (this.pageInline) {
|
|
181
182
|
this.show = true;
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
:show="show"
|
|
8
8
|
:safeAreaInsetBottom="safeAreaInsetBottom"
|
|
9
9
|
@close="popupClose"
|
|
10
|
+
@closed="$emit('closed')"
|
|
10
11
|
:zIndex="zIndex"
|
|
11
12
|
:customStyle="popupStyle"
|
|
12
13
|
>
|
|
@@ -111,7 +112,7 @@
|
|
|
111
112
|
}
|
|
112
113
|
}
|
|
113
114
|
},
|
|
114
|
-
emits: ["change", "close", "confirm", "cancel", "backspace"],
|
|
115
|
+
emits: ["change", "close", "closed", "confirm", "cancel", "backspace"],
|
|
115
116
|
methods: {
|
|
116
117
|
change(e) {
|
|
117
118
|
this.$emit('change', e);
|
|
@@ -20,7 +20,8 @@
|
|
|
20
20
|
import {
|
|
21
21
|
addUnit,
|
|
22
22
|
guid,
|
|
23
|
-
rpx2px
|
|
23
|
+
rpx2px,
|
|
24
|
+
upCreateIntersectionObserver
|
|
24
25
|
} from '../../libs/function/index.js';
|
|
25
26
|
/**
|
|
26
27
|
* lazyLoad 懒加载
|
|
@@ -211,10 +212,11 @@
|
|
|
211
212
|
|
|
212
213
|
setTimeout(() => {
|
|
213
214
|
// #ifndef APP-NVUE
|
|
214
|
-
//
|
|
215
|
+
// 这里是组件内获取布局状态,不能直传Vue实例给uni.createIntersectionObserver,
|
|
216
|
+
// 否则小程序内部会Object.keys(vm)导致告警,统一走upCreateIntersectionObserver
|
|
215
217
|
// this.disconnectObserver('contentObserver');
|
|
216
218
|
// nvue 里不支持
|
|
217
|
-
const contentObserver =
|
|
219
|
+
const contentObserver = upCreateIntersectionObserver(this);
|
|
218
220
|
// 要理解这里怎么计算的,请看这个:
|
|
219
221
|
// https://blog.csdn.net/qq_25324335/article/details/83687695
|
|
220
222
|
contentObserver.relativeToViewport({
|
|
@@ -94,6 +94,16 @@ export const props = defineMixin({
|
|
|
94
94
|
titleStyle: {
|
|
95
95
|
type: [String, Object],
|
|
96
96
|
default: () => defProps.navbar.titleStyle
|
|
97
|
+
},
|
|
98
|
+
// 导航栏模式,default-常规,ios-大标题磨砂模式
|
|
99
|
+
mode: {
|
|
100
|
+
type: String,
|
|
101
|
+
default: () => defProps.navbar.mode
|
|
102
|
+
},
|
|
103
|
+
// 页面滚动距离,仅 ios 模式使用,由页面 onPageScroll 传入
|
|
104
|
+
scrollTop: {
|
|
105
|
+
type: [String, Number],
|
|
106
|
+
default: () => defProps.navbar.scrollTop
|
|
97
107
|
}
|
|
98
108
|
}
|
|
99
109
|
})
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
page,
|
|
3
3
|
body {
|
|
4
4
|
--up-navbar-bg-color: #ffffff;
|
|
5
|
+
--up-navbar-glass-bg-color: rgba(255, 255, 255, 0.82);
|
|
6
|
+
--up-navbar-glass-blur: 20px;
|
|
5
7
|
}
|
|
6
8
|
|
|
7
9
|
@media (prefers-color-scheme: dark) {
|
|
@@ -9,13 +11,16 @@ body {
|
|
|
9
11
|
page,
|
|
10
12
|
body {
|
|
11
13
|
--up-navbar-bg-color: #1c1c1e;
|
|
14
|
+
--up-navbar-glass-bg-color: rgba(28, 28, 30, 0.82);
|
|
12
15
|
}
|
|
13
16
|
}
|
|
14
17
|
|
|
15
18
|
[data-up-theme='light'] {
|
|
16
19
|
--up-navbar-bg-color: #ffffff;
|
|
20
|
+
--up-navbar-glass-bg-color: rgba(255, 255, 255, 0.82);
|
|
17
21
|
}
|
|
18
22
|
|
|
19
23
|
[data-up-theme='dark'] {
|
|
20
24
|
--up-navbar-bg-color: #1c1c1e;
|
|
25
|
+
--up-navbar-glass-bg-color: rgba(28, 28, 30, 0.82);
|
|
21
26
|
}
|