uview-plus 3.7.36 → 3.8.32

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.
Files changed (132) hide show
  1. package/README.md +0 -1
  2. package/changelog.md +2047 -1782
  3. package/components/u-action-sheet/u-action-sheet.vue +54 -16
  4. package/components/u-agreement/u-agreement.vue +2 -1
  5. package/components/u-alert/u-alert.vue +8 -10
  6. package/components/u-button/u-button.vue +35 -5
  7. package/components/u-calendar/calendar.js +1 -0
  8. package/components/u-calendar/header.vue +98 -9
  9. package/components/u-calendar/month.vue +10 -7
  10. package/components/u-calendar/props.js +5 -0
  11. package/components/u-calendar/u-calendar.vue +109 -2
  12. package/components/u-car-keyboard/u-car-keyboard.vue +7 -7
  13. package/components/u-card/u-card.vue +6 -6
  14. package/components/u-cascader/u-cascader.vue +32 -12
  15. package/components/u-cate-tab/u-cate-tab.vue +49 -48
  16. package/components/u-cell/u-cell.vue +24 -4
  17. package/components/u-cell-group/u-cell-group.vue +10 -3
  18. package/components/u-checkbox/u-checkbox.vue +6 -6
  19. package/components/u-choose/u-choose.vue +9 -4
  20. package/components/u-city-locate/u-city-locate.vue +28 -22
  21. package/components/u-color-picker/u-color-picker.vue +15 -15
  22. package/components/u-cropper/u-cropper.vue +409 -387
  23. package/components/u-datetime-picker/u-datetime-picker.vue +79 -10
  24. package/components/u-dragsort/u-dragsort.vue +3 -0
  25. package/components/u-dropdown/u-dropdown.vue +15 -2
  26. package/components/u-dropdown-item/u-dropdown-item.vue +3 -3
  27. package/components/u-form-item/u-form-item.vue +6 -1
  28. package/components/u-gap/u-gap.vue +5 -1
  29. package/components/u-goods-sku/u-goods-sku.vue +16 -15
  30. package/components/u-index-anchor/u-index-anchor.vue +13 -2
  31. package/components/u-index-list/u-index-list.vue +18 -5
  32. package/components/u-input/input.js +3 -3
  33. package/components/u-input/u-input.vue +27 -5
  34. package/components/u-keyboard/u-keyboard.vue +11 -6
  35. package/components/u-loading-page/loadingPage.js +1 -1
  36. package/components/u-loading-page/u-loading-page.vue +18 -12
  37. package/components/u-navbar/navbar.js +2 -3
  38. package/components/u-navbar/theme-vars.scss +21 -0
  39. package/components/u-navbar/u-navbar.vue +30 -6
  40. package/components/u-notice-bar/theme-vars.scss +25 -0
  41. package/components/u-notice-bar/u-notice-bar.vue +24 -5
  42. package/components/u-number-box/numberBox.js +4 -4
  43. package/components/u-number-box/u-number-box.vue +27 -13
  44. package/components/u-number-keyboard/u-number-keyboard.vue +6 -6
  45. package/components/u-picker/picker.js +43 -43
  46. package/components/u-picker/u-picker.vue +14 -2
  47. package/components/u-popup/popup.js +1 -1
  48. package/components/u-popup/u-popup.vue +14 -6
  49. package/components/u-poster/u-poster.vue +12 -10
  50. package/components/u-pull-refresh/u-pull-refresh.vue +6 -6
  51. package/components/u-qrcode/qrcode.js +35 -29
  52. package/components/u-qrcode/u-qrcode.vue +17 -12
  53. package/components/u-radio/u-radio.vue +6 -6
  54. package/components/u-rate/rate.js +2 -2
  55. package/components/u-rate/u-rate.vue +98 -21
  56. package/components/u-search/search.js +3 -3
  57. package/components/u-search/u-search.vue +29 -6
  58. package/components/u-select/u-select.vue +141 -73
  59. package/components/u-signature/u-signature.vue +35 -16
  60. package/components/u-skeleton/u-skeleton.vue +7 -2
  61. package/components/u-slider/u-slider.vue +30 -31
  62. package/components/u-steps-item/u-steps-item.vue +20 -17
  63. package/components/u-subsection/theme-vars.scss +41 -0
  64. package/components/u-subsection/u-subsection.vue +69 -16
  65. package/components/u-swipe-action-item/u-swipe-action-item.vue +11 -5
  66. package/components/u-switch/theme-vars.scss +41 -0
  67. package/components/u-switch/u-switch.vue +44 -15
  68. package/components/u-tabbar/u-tabbar.vue +5 -5
  69. package/components/u-tabbar-item/u-tabbar-item.vue +16 -5
  70. package/components/u-table/u-table.vue +18 -3
  71. package/components/u-table2/tableRow.vue +43 -41
  72. package/components/u-table2/u-table2.vue +56 -50
  73. package/components/u-tabs/u-tabs.vue +14 -1
  74. package/components/u-tag/theme-vars.scss +21 -0
  75. package/components/u-tag/u-tag.vue +17 -7
  76. package/components/u-td/u-td.vue +5 -3
  77. package/components/u-text/text.js +1 -1
  78. package/components/u-text/u-text.vue +15 -13
  79. package/components/u-textarea/props.js +2 -2
  80. package/components/u-textarea/textarea.js +1 -1
  81. package/components/u-textarea/u-textarea.vue +115 -61
  82. package/components/u-th/u-th.vue +5 -4
  83. package/components/u-title/u-title.vue +1 -0
  84. package/components/u-toast/u-toast.vue +13 -9
  85. package/components/u-tooltip/u-tooltip.vue +1 -0
  86. package/components/u-tree/u-tree.vue +491 -51
  87. package/components/u-upload/u-upload.vue +34 -6
  88. package/index.js +178 -27
  89. package/index.scss +5 -1
  90. package/libs/config/color.js +1 -2
  91. package/libs/config/config.js +2 -0
  92. package/libs/config/props.js +1 -1
  93. package/libs/css/theme-vars-core.scss +201 -0
  94. package/libs/css/theme-vars.scss +1 -0
  95. package/libs/function/index.js +7 -7
  96. package/libs/mixin/mixin.js +111 -4
  97. package/libs/root/index.js +151 -0
  98. package/libs/root/nvue-root.vue +72 -0
  99. package/libs/root/page.js +269 -0
  100. package/libs/root/root-toast-host.vue +31 -0
  101. package/libs/root/root.js +44 -0
  102. package/libs/root/runtime.js +11 -0
  103. package/libs/root/utils.js +115 -0
  104. package/libs/theme/runtime.js +392 -0
  105. package/libs/theme/theme.js +682 -0
  106. package/libs/util/gcanvas/bridge/bridge-weex.js +0 -0
  107. package/libs/util/gcanvas/context-2d/FillStyleLinearGradient.js +0 -0
  108. package/libs/util/gcanvas/context-2d/FillStylePattern.js +0 -0
  109. package/libs/util/gcanvas/context-2d/FillStyleRadialGradient.js +0 -0
  110. package/libs/util/gcanvas/context-2d/RenderingContext.js +0 -0
  111. package/libs/util/gcanvas/context-webgl/ActiveInfo.js +0 -0
  112. package/libs/util/gcanvas/context-webgl/Buffer.js +0 -0
  113. package/libs/util/gcanvas/context-webgl/Framebuffer.js +0 -0
  114. package/libs/util/gcanvas/context-webgl/GLenum.js +0 -0
  115. package/libs/util/gcanvas/context-webgl/GLmethod.js +0 -0
  116. package/libs/util/gcanvas/context-webgl/GLtype.js +0 -0
  117. package/libs/util/gcanvas/context-webgl/Program.js +0 -0
  118. package/libs/util/gcanvas/context-webgl/Renderbuffer.js +0 -0
  119. package/libs/util/gcanvas/context-webgl/RenderingContext.js +0 -0
  120. package/libs/util/gcanvas/context-webgl/Shader.js +0 -0
  121. package/libs/util/gcanvas/context-webgl/ShaderPrecisionFormat.js +0 -0
  122. package/libs/util/gcanvas/context-webgl/Texture.js +0 -0
  123. package/libs/util/gcanvas/context-webgl/UniformLocation.js +0 -0
  124. package/libs/util/gcanvas/context-webgl/classUtils.js +0 -0
  125. package/libs/util/gcanvas/env/canvas.js +0 -0
  126. package/libs/util/gcanvas/env/image.js +0 -0
  127. package/libs/util/gcanvas/env/tool.js +0 -0
  128. package/libs/util/gcanvas/index.js +0 -0
  129. package/package.json +3 -2
  130. package/theme.scss +113 -32
  131. package/types/comps/qrcode.d.ts +6 -0
  132. package/types/index.d.ts +47 -2
@@ -2,9 +2,21 @@ import { defineMixin } from '../vue'
2
2
  import { deepMerge, $parent, sleep } from '../function/index'
3
3
  import test from '../function/test'
4
4
  import route from '../util/route'
5
+ import {
6
+ applyNativeThemeUI,
7
+ applyNativeThemeUIDeferred,
8
+ getThemeCardStyle,
9
+ getThemeIsDark,
10
+ getThemePageStyle,
11
+ getThemeVar,
12
+ getThemeVarsForStyle,
13
+ syncThemeRuntimeFromStorage
14
+ } from '../theme/runtime'
5
15
  // #ifdef APP-NVUE
6
16
  // 由于weex为阿里的KPI业绩考核的产物,所以不支持百分比单位,这里需要通过dom查询组件的宽度
7
- const dom = uni.requireNativePlugin('dom')
17
+ const dom = (typeof uni !== 'undefined' && uni && typeof uni.requireNativePlugin === 'function')
18
+ ? uni.requireNativePlugin('dom')
19
+ : null
8
20
  // #endif
9
21
 
10
22
  export const mixin = defineMixin({
@@ -31,21 +43,51 @@ export const mixin = defineMixin({
31
43
  }
32
44
  },
33
45
  data() {
34
- return {}
46
+ return {
47
+ __upPageThemeChangeHandler: null,
48
+ upThemeVersion: 0
49
+ }
35
50
  },
36
51
  onLoad() {
37
52
  // getRect挂载到$u上,因为这方法需要使用in(this),所以无法把它独立成一个单独的文件导出
38
- this.$u.getRect = this.$uGetRect
53
+ this.upBindGetRect()
54
+ this.upInitThemeVersion()
55
+ if (this.upIsPageScope()) {
56
+ this.upApplyNativeThemeUI()
57
+ if (typeof uni !== 'undefined' && typeof uni.$on === 'function' && !this.__upPageThemeChangeHandler) {
58
+ this.__upPageThemeChangeHandler = () => {
59
+ this.upApplyNativeThemeUI()
60
+ }
61
+ uni.$on('uThemeChange', this.__upPageThemeChangeHandler)
62
+ }
63
+ }
64
+ },
65
+ onShow() {
66
+ if (this.upIsPageScope()) {
67
+ this.upApplyNativeThemeUI()
68
+ }
39
69
  },
40
70
  created() {
41
71
  // 组件当中,只有created声明周期,为了能在组件使用,故也在created中将方法挂载到$u
42
- this.$u.getRect = this.$uGetRect
72
+ this.upBindGetRect()
73
+ this.upInitThemeVersion()
74
+ if (typeof uni !== 'undefined' && typeof uni.$on === 'function') {
75
+ this.__uThemeChangeHandler = (payload = {}) => {
76
+ this.upSyncThemeVersion(payload)
77
+ this.chacheU = null
78
+ if (typeof this.$forceUpdate === 'function') {
79
+ this.$forceUpdate()
80
+ }
81
+ }
82
+ uni.$on('uThemeChange', this.__uThemeChangeHandler)
83
+ }
43
84
  },
44
85
  computed: {
45
86
  // 在2.x版本中,将会把$u挂载到uni对象下,导致在模板中无法使用uni.$u.xxx形式
46
87
  // 所以这里通过computed计算属性将其附加到this.$u上,就可以在模板或者js中使用uni.$u.xxx
47
88
  // 只在nvue环境通过此方式引入完整的$u,其他平台会出现性能问题,非nvue则按需引入(主要原因是props过大)
48
89
  $u() {
90
+ this.upThemeVersion
49
91
  // #ifndef APP-NVUE
50
92
  // 在非nvue端,移除props,http,mixin等对象,避免在小程序setData时数据过大影响性能
51
93
  let mergeU = deepMerge(uni.$u, {
@@ -63,6 +105,22 @@ export const mixin = defineMixin({
63
105
  return uni.$u
64
106
  // #endif
65
107
  },
108
+ upThemeIsDark() {
109
+ this.upThemeVersion
110
+ return getThemeIsDark(this.$u)
111
+ },
112
+ upThemeVars() {
113
+ this.upThemeVersion
114
+ return getThemeVarsForStyle(this.$u)
115
+ },
116
+ upThemePageStyle() {
117
+ this.upThemeVersion
118
+ return getThemePageStyle(this.$u)
119
+ },
120
+ upThemeCardStyle() {
121
+ this.upThemeVersion
122
+ return getThemeCardStyle(this.$u)
123
+ },
66
124
  /**
67
125
  * 生成bem规则类名
68
126
  * 由于微信小程序,H5,nvue之间绑定class的差异,无法通过:class="[bem()]"的形式进行同用
@@ -98,6 +156,47 @@ export const mixin = defineMixin({
98
156
  }
99
157
  },
100
158
  methods: {
159
+ upBindGetRect() {
160
+ const upU = this.$u || (typeof uni !== 'undefined' ? uni.$u : null)
161
+ if (upU) {
162
+ upU.getRect = this.$uGetRect
163
+ } else if (typeof uni !== 'undefined') {
164
+ uni.$u = {
165
+ getRect: this.$uGetRect
166
+ }
167
+ }
168
+ },
169
+ upReadThemeVersion() {
170
+ return Number((typeof uni !== 'undefined' && uni.$u && uni.$u.theme && uni.$u.theme.version) || 0)
171
+ },
172
+ upInitThemeVersion() {
173
+ const version = this.upReadThemeVersion()
174
+ if (version) {
175
+ this.upThemeVersion = version
176
+ }
177
+ },
178
+ upSyncThemeVersion(payload = {}) {
179
+ const version = Number(payload.version || this.upReadThemeVersion() || 0)
180
+ this.upThemeVersion = version || Number(this.upThemeVersion || 0) + 1
181
+ },
182
+ upIsPageScope() {
183
+ return !!(this.$page || this.route || this.$options?.mpType === 'page')
184
+ },
185
+ upHasProp(propName) {
186
+ const vnodeProps = this.$?.vnode?.props || {}
187
+ const kebabName = propName.replace(/[A-Z]/g, (s) => `-${s.toLowerCase()}`)
188
+ return Object.prototype.hasOwnProperty.call(vnodeProps, propName)
189
+ || Object.prototype.hasOwnProperty.call(vnodeProps, kebabName)
190
+ },
191
+ upThemeVar(varName, fallbackColor) {
192
+ this.upThemeVersion
193
+ return getThemeVar(varName, fallbackColor, this.$u)
194
+ },
195
+ upApplyNativeThemeUI() {
196
+ syncThemeRuntimeFromStorage(this.$u)
197
+ this.upSyncThemeVersion()
198
+ applyNativeThemeUIDeferred(this.$u)
199
+ },
101
200
  // 跳转某一个页面
102
201
  openPage(urlKey = 'url') {
103
202
  const url = this[urlKey]
@@ -200,6 +299,14 @@ export const mixin = defineMixin({
200
299
  }
201
300
  })
202
301
  }
302
+ if (typeof uni !== 'undefined' && typeof uni.$off === 'function' && this.__uThemeChangeHandler) {
303
+ uni.$off('uThemeChange', this.__uThemeChangeHandler)
304
+ this.__uThemeChangeHandler = null
305
+ }
306
+ if (typeof uni !== 'undefined' && typeof uni.$off === 'function' && this.__upPageThemeChangeHandler) {
307
+ uni.$off('uThemeChange', this.__upPageThemeChangeHandler)
308
+ this.__upPageThemeChangeHandler = null
309
+ }
203
310
  }
204
311
  })
205
312
 
@@ -0,0 +1,151 @@
1
+ import { dirname, relative, resolve } from 'node:path'
2
+ import { fileURLToPath } from 'node:url'
3
+ import process from 'node:process'
4
+ import { existsSync, mkdirSync, statSync, writeFileSync } from 'node:fs'
5
+
6
+ import { createFilter, normalizePath } from 'vite'
7
+
8
+ import { transformNvuePage, transformPage } from './page.js'
9
+ import { rebuildUpApp, registerUpApp } from './root.js'
10
+ import { loadPagesJson, normalizePlatformPath, toArray } from './utils.js'
11
+
12
+ const rootLibPath = normalizePath(dirname(fileURLToPath(import.meta.url)))
13
+
14
+ export default function UniUpRoot(options = {}) {
15
+ const rootOptions = {
16
+ enabledVirtualHost: false,
17
+ enabledGlobalRef: false,
18
+ rootFileName: 'App.up',
19
+ autoCreateRootFile: true,
20
+ excludePages: [],
21
+ ...options,
22
+ }
23
+ const rootFileName = String(rootOptions.rootFileName || 'App.up').replace(/\.vue$/i, '')
24
+
25
+ const detectProjectRoot = () => {
26
+ const cwd = normalizePath(process.env.INIT_CWD || process.cwd())
27
+ const envInputDir = process.env.UNI_INPUT_DIR ? normalizePath(process.env.UNI_INPUT_DIR) : ''
28
+ const cliRootPath = normalizePath(resolve(cwd, 'src'))
29
+ const hbuilderRootPath = cwd
30
+
31
+ const isPageRoot = (path) => existsSync(resolve(path, 'pages.json'))
32
+
33
+ if (envInputDir && isPageRoot(envInputDir)) {
34
+ const projectType = envInputDir.endsWith('/src') ? 'cli' : 'hbuilder'
35
+ return { rootPath: envInputDir, projectType }
36
+ }
37
+
38
+ if (isPageRoot(cliRootPath)) {
39
+ return { rootPath: cliRootPath, projectType: 'cli' }
40
+ }
41
+
42
+ if (isPageRoot(hbuilderRootPath)) {
43
+ return { rootPath: hbuilderRootPath, projectType: 'hbuilder' }
44
+ }
45
+
46
+ return {
47
+ rootPath: envInputDir || cliRootPath,
48
+ projectType: envInputDir && !envInputDir.endsWith('/src') ? 'hbuilder' : 'cli',
49
+ }
50
+ }
51
+
52
+ const projectInfo = detectProjectRoot()
53
+ const rootPath = normalizePath(projectInfo.rootPath)
54
+ const appUpPath = normalizePath(resolve(rootPath, `${rootFileName}.vue`))
55
+ const rootToastHostPath = normalizePath(resolve(rootLibPath, 'root-toast-host.vue'))
56
+ const nvueRootPath = normalizePath(resolve(rootPath, 'uni_modules/uview-plus/libs/root/nvue-root.vue'))
57
+ const themeRuntimePath = normalizePath(resolve(rootPath, 'uni_modules/uview-plus/libs/theme/runtime.js'))
58
+ const pagesPath = normalizePath(resolve(rootPath, 'pages.json'))
59
+ const excludedPaths = toArray(rootOptions.excludePages)
60
+ .filter(Boolean)
61
+ .map(path => normalizePath(resolve(rootPath, path)))
62
+
63
+ const mainFiles = [
64
+ normalizePath(resolve(rootPath, 'main.ts')),
65
+ normalizePath(resolve(rootPath, 'main.js')),
66
+ ]
67
+
68
+ const getRelativeImportPath = (fromFile, toFile) => {
69
+ let importPath = normalizePath(relative(dirname(fromFile), toFile))
70
+ if (!importPath.startsWith('.')) {
71
+ importPath = `./${importPath}`
72
+ }
73
+ return importPath
74
+ }
75
+
76
+ let pagesJson = []
77
+ let pagesJsonMtimeMs = 0
78
+ let hasPlatformPlugin = false
79
+
80
+ const ensureRootFile = () => {
81
+ if (!rootOptions.autoCreateRootFile) return
82
+ if (existsSync(appUpPath)) return
83
+
84
+ const defaultRootSfc = `<template>
85
+ \t<UpRootView />
86
+ </template>
87
+ `
88
+
89
+ mkdirSync(dirname(appUpPath), { recursive: true })
90
+ writeFileSync(appUpPath, defaultRootSfc, 'utf-8')
91
+ }
92
+
93
+ const refreshPagesJson = () => {
94
+ if (!existsSync(pagesPath)) return
95
+ const mtimeMs = statSync(pagesPath).mtimeMs
96
+ if (mtimeMs === pagesJsonMtimeMs && pagesJson.length) return
97
+ pagesJson = loadPagesJson(pagesPath, rootPath)
98
+ pagesJsonMtimeMs = mtimeMs
99
+ }
100
+
101
+ return {
102
+ name: 'vite-plugin-uni-up-root',
103
+ enforce: 'pre',
104
+ configResolved({ plugins }) {
105
+ hasPlatformPlugin = plugins.some(v => v.name === 'vite-plugin-uni-platform')
106
+ },
107
+ buildStart() {
108
+ ensureRootFile()
109
+ refreshPagesJson()
110
+ },
111
+ async transform(code, id) {
112
+ let ms = null
113
+ const isSfcBlock = id.includes('?')
114
+ const cleanId = normalizePath(id.split('?')[0])
115
+
116
+ const filterMain = createFilter(mainFiles)
117
+ if (filterMain(cleanId)) {
118
+ ms = await registerUpApp(code, rootFileName, getRelativeImportPath(cleanId, rootToastHostPath))
119
+ }
120
+
121
+ const filterUpRoot = createFilter(appUpPath)
122
+ if (filterUpRoot(cleanId)) {
123
+ ms = await rebuildUpApp(code, rootOptions.enabledVirtualHost)
124
+ }
125
+
126
+ refreshPagesJson()
127
+ const pageId = hasPlatformPlugin ? normalizePlatformPath(cleanId) : cleanId
128
+ const filterPage = createFilter(pagesJson, excludedPaths)
129
+ if (!isSfcBlock && filterPage(pageId)) {
130
+ if (cleanId.endsWith('.nvue')) {
131
+ ms = await transformNvuePage(
132
+ code,
133
+ getRelativeImportPath(cleanId, nvueRootPath),
134
+ getRelativeImportPath(cleanId, themeRuntimePath),
135
+ rootOptions.enabledGlobalRef
136
+ )
137
+ } else {
138
+ ms = await transformPage(code, rootOptions.enabledGlobalRef)
139
+ }
140
+ }
141
+
142
+ if (ms) {
143
+ return {
144
+ code: ms.toString(),
145
+ map: ms.generateMap({ hires: true }),
146
+ }
147
+ }
148
+ return null
149
+ },
150
+ }
151
+ }
@@ -0,0 +1,72 @@
1
+ <template>
2
+ <view class="up-nvue-root" :style="rootStyle">
3
+ <slot />
4
+ </view>
5
+ </template>
6
+
7
+ <script>
8
+ import { applyNativeThemeUI, getThemePageStyle, getThemeVarsForStyle, syncThemeRuntimeFromStorage } from '../theme/runtime.js'
9
+
10
+ export default {
11
+ name: 'UpNvueRoot',
12
+ data() {
13
+ return {
14
+ rootStyle: {
15
+ ...getThemeVarsForStyle(),
16
+ ...getThemePageStyle()
17
+ },
18
+ minPageHeight: '0px'
19
+ }
20
+ },
21
+ created() {
22
+ this.syncPageHeight()
23
+ this.refreshRootStyle()
24
+ this.themeChangeHandler = () => {
25
+ this.refreshRootStyle()
26
+ }
27
+ if (typeof uni !== 'undefined' && typeof uni.$on === 'function') {
28
+ uni.$on('uThemeChange', this.themeChangeHandler)
29
+ }
30
+ },
31
+ mounted() {
32
+ this.refreshRootStyle()
33
+ },
34
+ beforeUnmount() {
35
+ if (this.themeChangeHandler && typeof uni !== 'undefined' && typeof uni.$off === 'function') {
36
+ uni.$off('uThemeChange', this.themeChangeHandler)
37
+ }
38
+ this.themeChangeHandler = null
39
+ },
40
+ methods: {
41
+ syncPageHeight() {
42
+ let windowHeight = 0
43
+ try {
44
+ if (typeof uni !== 'undefined' && typeof uni.getWindowInfo === 'function') {
45
+ windowHeight = Number((uni.getWindowInfo() || {}).windowHeight || 0)
46
+ } else if (typeof uni !== 'undefined' && typeof uni.getSystemInfoSync === 'function') {
47
+ windowHeight = Number((uni.getSystemInfoSync() || {}).windowHeight || 0)
48
+ }
49
+ } catch (e) {
50
+ windowHeight = 0
51
+ }
52
+ this.minPageHeight = `${windowHeight || 0}px`
53
+ },
54
+ refreshRootStyle() {
55
+ syncThemeRuntimeFromStorage()
56
+ this.rootStyle = {
57
+ ...getThemeVarsForStyle(),
58
+ ...getThemePageStyle(),
59
+ minHeight: this.minPageHeight,
60
+ width: '750rpx'
61
+ }
62
+ applyNativeThemeUI()
63
+ }
64
+ }
65
+ }
66
+ </script>
67
+
68
+ <style>
69
+ .up-nvue-root {
70
+ width: 750rpx;
71
+ }
72
+ </style>
@@ -0,0 +1,269 @@
1
+ import { MagicString } from 'vue/compiler-sfc'
2
+
3
+ import { findNode, parseSFC } from './utils.js'
4
+
5
+ function getPageRootRefSource(sfc, enabledGlobalRef = false) {
6
+ const pageTempAttrs = sfc.template?.attrs
7
+ if (pageTempAttrs && pageTempAttrs.root) {
8
+ return `ref="${pageTempAttrs.root}"`
9
+ }
10
+ return enabledGlobalRef ? 'ref="uniUpRoot"' : ''
11
+ }
12
+
13
+ function ensureNvueNavigationBar(pageMetaSource) {
14
+ const navigationBarSource = '<navigation-bar :front-color="upThemeNavFrontColor" :background-color="upThemeNavBgColor" />'
15
+ if (!pageMetaSource) return `<page-meta>${navigationBarSource}</page-meta>`
16
+ if (pageMetaSource.indexOf('navigation-bar') > -1 || pageMetaSource.indexOf('NavigationBar') > -1) {
17
+ return pageMetaSource
18
+ }
19
+ return pageMetaSource.replace(/<page-meta([^>]*)>/i, `<page-meta$1>${navigationBarSource}`)
20
+ }
21
+
22
+ function wrapTemplate(ms, sfc, tagName, rootRefSource = '', withNvueNavigationBar = false) {
23
+ const pageTempStart = sfc.template?.loc.start.offset
24
+ const pageTempEnd = sfc.template?.loc.end.offset
25
+
26
+ let pageMetaSource = ''
27
+ const pageMetaNode = findNode(sfc, 'PageMeta')
28
+
29
+ if (pageMetaNode) {
30
+ pageMetaSource = pageMetaNode.loc.source
31
+ const metaTempStart = pageMetaNode.loc.start.offset
32
+ const metaTempEnd = pageMetaNode.loc.end.offset
33
+ ms.remove(metaTempStart, metaTempEnd)
34
+ }
35
+
36
+ if (withNvueNavigationBar) {
37
+ pageMetaSource = ensureNvueNavigationBar(pageMetaSource)
38
+ }
39
+
40
+ if (pageTempStart != null && pageTempEnd != null) {
41
+ ms.appendLeft(pageTempStart, `\n${pageMetaSource}\n<${tagName} ${rootRefSource}>`)
42
+ ms.appendRight(pageTempEnd, `\n</${tagName}>\n`)
43
+ }
44
+ }
45
+
46
+ export async function transformPage(code, enabledGlobalRef = false) {
47
+ const sfc = await parseSFC(code)
48
+ const ms = new MagicString(code)
49
+
50
+ wrapTemplate(ms, sfc, 'global-up-root', getPageRootRefSource(sfc, enabledGlobalRef))
51
+
52
+ return ms
53
+ }
54
+
55
+ function ensureOptionsComponent(ms, scriptContent) {
56
+ if (scriptContent.includes('UpNvueRoot')) return
57
+
58
+ const componentsMatch = scriptContent.match(/components\s*:\s*\{/)
59
+ if (componentsMatch) {
60
+ ms.appendLeft(componentsMatch.index + componentsMatch[0].length, ' UpNvueRoot,')
61
+ return
62
+ }
63
+
64
+ const exportDefaultMatch = scriptContent.match(/export\s+default\s+(?:defineComponent\s*\()?\s*\{/)
65
+ if (exportDefaultMatch) {
66
+ ms.appendLeft(
67
+ exportDefaultMatch.index + exportDefaultMatch[0].length,
68
+ '\n components: { UpNvueRoot },'
69
+ )
70
+ }
71
+ }
72
+
73
+ function ensureOptionsThemeMixin(ms, scriptContent) {
74
+ if (scriptContent.includes('__upNvueThemeMixin')) return
75
+
76
+ const mixinsMatch = scriptContent.match(/mixins\s*:\s*\[/)
77
+ if (mixinsMatch) {
78
+ ms.appendLeft(mixinsMatch.index + mixinsMatch[0].length, ' __upNvueThemeMixin,')
79
+ return
80
+ }
81
+
82
+ const exportDefaultMatch = scriptContent.match(/export\s+default\s+(?:defineComponent\s*\()?\s*\{/)
83
+ if (exportDefaultMatch) {
84
+ ms.appendLeft(
85
+ exportDefaultMatch.index + exportDefaultMatch[0].length,
86
+ '\n mixins: [__upNvueThemeMixin],'
87
+ )
88
+ }
89
+ }
90
+
91
+ function getScriptSetupImports(componentImportPath, runtimeImportPath) {
92
+ return `import UpNvueRoot from '${componentImportPath}'
93
+ import { computed as __upComputed, onBeforeUnmount as __upOnBeforeUnmount, onMounted as __upOnMounted, ref as __upRef } from 'vue'
94
+ import { onShow as __upOnShow } from '@dcloudio/uni-app'
95
+ import {
96
+ applyNativeThemeUI as __upApplyNativeThemeUI,
97
+ applyNativeThemeUIDeferred as __upApplyNativeThemeUIDeferred,
98
+ getThemeCardStyle as __upGetThemeCardStyle,
99
+ getThemeIsDark as __upGetThemeIsDark,
100
+ getThemePageStyle as __upGetThemePageStyle,
101
+ getThemeVar as __upThemeVar,
102
+ syncThemeRuntimeFromStorage as __upSyncThemeRuntimeFromStorage
103
+ } from '${runtimeImportPath}'
104
+
105
+ const __upThemeVersion = __upRef(0)
106
+ let __upThemeChangeHandler = null
107
+ const __upReadThemeVersion = () => Number((typeof uni !== 'undefined' && uni.$u && uni.$u.theme && uni.$u.theme.version) || 0)
108
+ const __upSyncThemeVersion = (payload = {}) => {
109
+ const version = Number(payload.version || __upReadThemeVersion() || 0)
110
+ __upThemeVersion.value = version || Number(__upThemeVersion.value || 0) + 1
111
+ }
112
+ __upOnMounted(() => {
113
+ __upSyncThemeRuntimeFromStorage()
114
+ __upSyncThemeVersion()
115
+ __upApplyNativeThemeUI()
116
+ if (typeof uni !== 'undefined' && typeof uni.$on === 'function') {
117
+ __upThemeChangeHandler = (payload = {}) => {
118
+ __upSyncThemeRuntimeFromStorage()
119
+ __upSyncThemeVersion(payload)
120
+ __upApplyNativeThemeUI()
121
+ }
122
+ uni.$on('uThemeChange', __upThemeChangeHandler)
123
+ }
124
+ })
125
+ __upOnShow(() => {
126
+ __upSyncThemeRuntimeFromStorage()
127
+ __upSyncThemeVersion()
128
+ __upApplyNativeThemeUIDeferred()
129
+ })
130
+ __upOnBeforeUnmount(() => {
131
+ if (typeof uni !== 'undefined' && typeof uni.$off === 'function' && __upThemeChangeHandler) {
132
+ uni.$off('uThemeChange', __upThemeChangeHandler)
133
+ __upThemeChangeHandler = null
134
+ }
135
+ })
136
+ const upThemeVar = (varName, fallbackColor) => {
137
+ __upThemeVersion.value
138
+ return __upThemeVar(varName, fallbackColor)
139
+ }
140
+ const upThemeCardStyle = __upComputed(() => {
141
+ __upThemeVersion.value
142
+ return __upGetThemeCardStyle()
143
+ })
144
+ const upThemePageStyle = __upComputed(() => {
145
+ __upThemeVersion.value
146
+ return __upGetThemePageStyle()
147
+ })
148
+ const upThemeIsDark = __upComputed(() => {
149
+ __upThemeVersion.value
150
+ return __upGetThemeIsDark()
151
+ })
152
+ const upThemeNavFrontColor = __upComputed(() => {
153
+ __upThemeVersion.value
154
+ return __upGetThemeIsDark() ? '#ffffff' : '#000000'
155
+ })
156
+ const upThemeNavBgColor = __upComputed(() => {
157
+ __upThemeVersion.value
158
+ return __upThemeVar('--up-navbar-bg-color', __upGetThemeIsDark() ? '#1c1c1e' : '#ffffff')
159
+ })
160
+ `
161
+ }
162
+
163
+ function getOptionsImports(componentImportPath, runtimeImportPath) {
164
+ return `import UpNvueRoot from '${componentImportPath}'
165
+ import {
166
+ applyNativeThemeUI as __upApplyNativeThemeUI,
167
+ applyNativeThemeUIDeferred as __upApplyNativeThemeUIDeferred,
168
+ getThemeCardStyle as __upGetThemeCardStyle,
169
+ getThemeIsDark as __upGetThemeIsDark,
170
+ getThemePageStyle as __upGetThemePageStyle,
171
+ getThemeVar as __upThemeVar,
172
+ syncThemeRuntimeFromStorage as __upSyncThemeRuntimeFromStorage
173
+ } from '${runtimeImportPath}'
174
+
175
+ const __upNvueThemeMixin = {
176
+ data() {
177
+ return {
178
+ __upNvueThemeVersion: 0,
179
+ __upNvueThemeChangeHandler: null
180
+ }
181
+ },
182
+ created() {
183
+ __upSyncThemeRuntimeFromStorage()
184
+ this.__upSyncNvueThemeVersion()
185
+ __upApplyNativeThemeUI()
186
+ if (typeof uni !== 'undefined' && typeof uni.$on === 'function') {
187
+ this.__upNvueThemeChangeHandler = (payload = {}) => {
188
+ __upSyncThemeRuntimeFromStorage()
189
+ this.__upSyncNvueThemeVersion(payload)
190
+ __upApplyNativeThemeUI()
191
+ }
192
+ uni.$on('uThemeChange', this.__upNvueThemeChangeHandler)
193
+ }
194
+ },
195
+ onShow() {
196
+ __upSyncThemeRuntimeFromStorage()
197
+ this.__upSyncNvueThemeVersion()
198
+ __upApplyNativeThemeUIDeferred()
199
+ },
200
+ beforeUnmount() {
201
+ if (typeof uni !== 'undefined' && typeof uni.$off === 'function' && this.__upNvueThemeChangeHandler) {
202
+ uni.$off('uThemeChange', this.__upNvueThemeChangeHandler)
203
+ this.__upNvueThemeChangeHandler = null
204
+ }
205
+ },
206
+ computed: {
207
+ upThemeCardStyle() {
208
+ this.__upNvueThemeVersion
209
+ return __upGetThemeCardStyle()
210
+ },
211
+ upThemePageStyle() {
212
+ this.__upNvueThemeVersion
213
+ return __upGetThemePageStyle()
214
+ },
215
+ upThemeIsDark() {
216
+ this.__upNvueThemeVersion
217
+ return __upGetThemeIsDark()
218
+ },
219
+ upThemeNavFrontColor() {
220
+ this.__upNvueThemeVersion
221
+ return __upGetThemeIsDark() ? '#ffffff' : '#000000'
222
+ },
223
+ upThemeNavBgColor() {
224
+ this.__upNvueThemeVersion
225
+ return __upThemeVar('--up-navbar-bg-color', __upGetThemeIsDark() ? '#1c1c1e' : '#ffffff')
226
+ }
227
+ },
228
+ methods: {
229
+ __upReadNvueThemeVersion() {
230
+ return Number((typeof uni !== 'undefined' && uni.$u && uni.$u.theme && uni.$u.theme.version) || 0)
231
+ },
232
+ __upSyncNvueThemeVersion(payload = {}) {
233
+ const version = Number(payload.version || this.__upReadNvueThemeVersion() || 0)
234
+ this.__upNvueThemeVersion = version || Number(this.__upNvueThemeVersion || 0) + 1
235
+ },
236
+ upThemeVar(varName, fallbackColor) {
237
+ this.__upNvueThemeVersion
238
+ return __upThemeVar(varName, fallbackColor)
239
+ }
240
+ }
241
+ }
242
+ `
243
+ }
244
+
245
+ export async function transformNvuePage(
246
+ code,
247
+ componentImportPath,
248
+ runtimeImportPath,
249
+ enabledGlobalRef = false
250
+ ) {
251
+ const sfc = await parseSFC(code)
252
+ const ms = new MagicString(code)
253
+
254
+ wrapTemplate(ms, sfc, 'UpNvueRoot', getPageRootRefSource(sfc, enabledGlobalRef), true)
255
+
256
+ if (sfc.scriptSetup) {
257
+ ms.appendLeft(sfc.scriptSetup.loc.start.offset, getScriptSetupImports(componentImportPath, runtimeImportPath))
258
+ } else if (sfc.script) {
259
+ ms.appendLeft(sfc.script.loc.start.offset, getOptionsImports(componentImportPath, runtimeImportPath))
260
+ ensureOptionsComponent(ms, sfc.script.content)
261
+ ensureOptionsThemeMixin(ms, sfc.script.content)
262
+ } else {
263
+ ms.append(
264
+ `\n<script>\n${getOptionsImports(componentImportPath, runtimeImportPath)}export default {\n components: { UpNvueRoot },\n mixins: [__upNvueThemeMixin]\n}\n</script>\n`
265
+ )
266
+ }
267
+
268
+ return ms
269
+ }
@@ -0,0 +1,31 @@
1
+ <template>
2
+ <up-toast ref="upGlobalToastRef" />
3
+ <up-notify ref="upGlobalNotifyRef" />
4
+ </template>
5
+
6
+ <script setup>
7
+ import { onBeforeUnmount, onMounted, ref } from 'vue'
8
+
9
+ const upGlobalToastRef = ref(null)
10
+ const upGlobalNotifyRef = ref(null)
11
+
12
+ onMounted(() => {
13
+ if (typeof uni === 'undefined' || !uni.$u) return
14
+ if (typeof uni.$u.setRootToastRef === 'function') {
15
+ uni.$u.setRootToastRef(upGlobalToastRef.value)
16
+ }
17
+ if (typeof uni.$u.setRootNotifyRef === 'function') {
18
+ uni.$u.setRootNotifyRef(upGlobalNotifyRef.value)
19
+ }
20
+ })
21
+
22
+ onBeforeUnmount(() => {
23
+ if (typeof uni === 'undefined' || !uni.$u) return
24
+ if (typeof uni.$u.setRootToastRef === 'function') {
25
+ uni.$u.setRootToastRef(null)
26
+ }
27
+ if (typeof uni.$u.setRootNotifyRef === 'function') {
28
+ uni.$u.setRootNotifyRef(null)
29
+ }
30
+ })
31
+ </script>