one-screen-scale 1.1.0 → 1.3.0

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/src/core.js CHANGED
@@ -1,160 +1,317 @@
1
- /**
2
- * 一屏自适应缩放 — 核心算法(框架无关)
3
- *
4
- * 两种模式:
5
- * 'contain' 一屏展示,内容不溢出,用 min(scaleX, scaleY)
6
- * 'fixed-width' 固定视觉宽度,内容可滚动,反向补高
7
- */
8
-
9
- // ---------- helpers ----------
10
-
11
- function resolveEl(el) {
12
- if (!el) return null
13
- if (typeof el === 'string') return document.querySelector(el)
14
- if (el instanceof HTMLElement) return el
15
- // Vue ref / React ref
16
- if (el.value instanceof HTMLElement) return el.value
17
- if (el.current instanceof HTMLElement) return el.current
18
- return null
19
- }
20
-
21
- // ---------- scale calculation ----------
22
-
23
- export function calculateScale({
24
- sourceWidth,
25
- sourceHeight,
26
- targetWidth = (typeof window !== 'undefined' ? window.innerWidth : 1920),
27
- targetHeight = (typeof window !== 'undefined' ? window.innerHeight : 1080),
28
- mode = 'contain',
29
- visualWidth = 450, // fixed-width 模式下的目标视觉宽度
30
- // screenWidth = (typeof window !== 'undefined' ? window.screen.width : 1920), // fixed-width 模式下的设备屏幕宽度
31
- }) {
32
- if (!sourceWidth || !sourceHeight || sourceWidth <= 0 || sourceHeight <= 0) return 1
33
-
34
- let scale
35
-
36
- if (mode === 'fixed-width') {
37
- // if(screenWidth < visualWidth){
38
- // scale = 1
39
- // }else{
40
- // scale = visualWidth / Math.max(targetWidth, screenWidth)
41
- // }
42
- // 只用视口宽:视口比目标宽才缩小,否则 1:1(保持清晰)
43
- scale = targetWidth > visualWidth ? visualWidth / targetWidth : 1
44
- } else {
45
- const sx = targetWidth / sourceWidth
46
- const sy = targetHeight / sourceHeight
47
- scale = Math.min(sx, sy)
48
- }
49
-
50
- return scale
51
- }
52
-
53
- // ---------- apply / read ----------
54
-
55
- export function applyScale(el, scale, origin = 'top center') {
56
- const target = resolveEl(el)
57
- if (!target) return
58
- target.style.transform = `scale(${scale})`
59
- target.style.transformOrigin = origin
60
- }
61
-
62
- export function getPageScale(el) {
63
- const target = resolveEl(el)
64
- if (!target) return 1
65
-
66
- const style = window.getComputedStyle(target)
67
- const t = style.transform
68
- if (!t || t === 'none') return 1
69
-
70
- // matrix(a, b, c, d, e, f) — 2d
71
- const m2 = t.match(/matrix\(([^,]+),\s*[^,]+,\s*[^,]+,\s*([^,]+)/)
72
- if (m2) return (parseFloat(m2[1]) + parseFloat(m2[2])) / 2
73
-
74
- // matrix3d — 3d
75
- const m3 = t.match(/matrix3d\(([^,]+),[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,([^,]+)\)/)
76
- if (m3) return (parseFloat(m3[1]) + parseFloat(m3[2])) / 2
77
-
78
- // scale(x, y) or scale(s)
79
- const sm = t.match(/scale\(([^)]+)\)/)
80
- if (sm) {
81
- const vals = sm[1].split(',').map(v => parseFloat(v.trim()))
82
- return vals.length >= 2 ? (vals[0] + vals[1]) / 2 : vals[0]
83
- }
84
-
85
- return 1
86
- }
87
-
88
- export function getInverseScale(el = '.share-page') {
89
- const s = getPageScale(el)
90
- return s > 0 ? 1 / s : 1
91
- }
92
-
93
- // ---------- scaler instance ----------
94
-
95
- export function createScaler(el, options = {}) {
96
- const target = resolveEl(el)
97
- if (!target) throw new Error('[one-screen-scale] element not found')
98
-
99
- const {
100
- mode = 'contain',
101
- visualWidth = 450,
102
- origin = 'top center',
103
- autoResize = true
104
- } = options
105
-
106
- let currentScale = 1
107
- let handler = null
108
-
109
- function compute() {
110
- const sw = target.offsetWidth
111
- const sh = target.offsetHeight
112
- const tw = document.documentElement.clientWidth || window.innerWidth
113
- const th = window.innerHeight
114
-
115
- return calculateScale({
116
- sourceWidth: sw,
117
- sourceHeight: sh,
118
- targetWidth: tw,
119
- targetHeight: th,
120
- mode,
121
- visualWidth,
122
- // screenWidth: window.screen.width
123
- })
124
- }
125
-
126
- function refresh() {
127
- const next = compute()
128
- if (next !== currentScale) {
129
- currentScale = next
130
- applyScale(target, next, origin)
131
- }
132
-
133
- // fixed-width 模式:反向补偿高度
134
- if (mode === 'fixed-width' && next > 0) {
135
- // target.style.width = `${Math.max(window.innerWidth, window.screen.width)}px`
136
- const viewportWidth = document.documentElement.clientWidth || window.innerWidth
137
- target.style.width = `${viewportWidth}px`
138
- target.style.height = `${Math.round(window.innerHeight / next)}px`
139
- }
140
- return currentScale
141
- }
142
-
143
- function start() {
144
- refresh()
145
- if (autoResize) {
146
- handler = () => refresh()
147
- window.addEventListener('resize', handler)
148
- }
149
- return currentScale
150
- }
151
-
152
- function stop() {
153
- if (handler) {
154
- window.removeEventListener('resize', handler)
155
- handler = null
156
- }
157
- }
158
-
159
- return { start, stop, refresh, getScale: () => currentScale }
160
- }
1
+ /**
2
+ * 一屏自适应缩放 — 核心算法(框架无关)
3
+ *
4
+ * 两种模式:
5
+ * 'contain' 一屏展示,内容不溢出,用 min(scaleX, scaleY)
6
+ * 'fixed-width' 固定视觉宽度,内容可滚动,反向补高
7
+ *
8
+ * 配套前提:H5 使用 postcss-px-to-viewport(或同类)做移动端适配。
9
+ * createScaler / 指令默认会注入基础宽高样式,保证测量与缩放生效。
10
+ *
11
+ * 图片等异步内容会改变 offsetHeight:默认用 ResizeObserver / 图片 load
12
+ * 在尺寸稳定后再 refresh,避免首屏偶发「量矮了 → scale 偏大」。
13
+ */
14
+
15
+ import { applyBaseStyles, removeBaseStyles } from './baseStyles.js'
16
+
17
+ // ---------- helpers ----------
18
+
19
+ function resolveEl(el) {
20
+ if (!el) return null
21
+ if (typeof el === 'string') return document.querySelector(el)
22
+ if (el instanceof HTMLElement) return el
23
+ // Vue ref / React ref
24
+ if (el.value instanceof HTMLElement) return el.value
25
+ if (el.current instanceof HTMLElement) return el.current
26
+ return null
27
+ }
28
+
29
+ // ---------- scale calculation ----------
30
+
31
+ export function calculateScale({
32
+ sourceWidth,
33
+ sourceHeight,
34
+ targetWidth = (typeof window !== 'undefined' ? window.innerWidth : 1920),
35
+ targetHeight = (typeof window !== 'undefined' ? window.innerHeight : 1080),
36
+ mode = 'contain',
37
+ visualWidth = 450, // fixed-width 模式下的目标视觉宽度
38
+ }) {
39
+ if (!sourceWidth || !sourceHeight || sourceWidth <= 0 || sourceHeight <= 0) return 1
40
+
41
+ let scale
42
+
43
+ if (mode === 'fixed-width') {
44
+ // 只用视口宽:视口比目标宽才缩小,否则 1:1(保持清晰)
45
+ scale = targetWidth > visualWidth ? visualWidth / targetWidth : 1
46
+ } else {
47
+ const sx = targetWidth / sourceWidth
48
+ const sy = targetHeight / sourceHeight
49
+ scale = Math.min(sx, sy)
50
+ }
51
+
52
+ return scale
53
+ }
54
+
55
+ // ---------- apply / read ----------
56
+
57
+ /** 页面 scale 变化时抛出,供 ECharts.resize / 业务监听 */
58
+ export const SCALE_CHANGE_EVENT = 'one-screen-scale-change'
59
+
60
+ export function applyScale(el, scale, origin = 'top center') {
61
+ const target = resolveEl(el)
62
+ if (!target) return
63
+ target.style.transform = `scale(${scale})`
64
+ target.style.transformOrigin = origin
65
+ // 供业务 / v-compensate 做反缩放(继承到子树)
66
+ const inv = scale > 0 ? 1 / scale : 1
67
+ target.style.setProperty('--one-screen-scale', String(scale))
68
+ target.style.setProperty('--one-screen-inverse-scale', String(inv))
69
+ if (typeof window !== 'undefined') {
70
+ window.dispatchEvent(
71
+ new CustomEvent(SCALE_CHANGE_EVENT, { detail: { scale, inverseScale: inv, el: target } })
72
+ )
73
+ }
74
+ }
75
+
76
+ export function getPageScale(el) {
77
+ const target = resolveEl(el)
78
+ if (!target) return 1
79
+
80
+ const style = window.getComputedStyle(target)
81
+ const t = style.transform
82
+ if (!t || t === 'none') return 1
83
+
84
+ // matrix(a, b, c, d, e, f) — 2d
85
+ const m2 = t.match(/matrix\(([^,]+),\s*[^,]+,\s*[^,]+,\s*([^,]+)/)
86
+ if (m2) return (parseFloat(m2[1]) + parseFloat(m2[2])) / 2
87
+
88
+ // matrix3d — 3d
89
+ const m3 = t.match(/matrix3d\(([^,]+),[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,([^,]+)\)/)
90
+ if (m3) return (parseFloat(m3[1]) + parseFloat(m3[2])) / 2
91
+
92
+ // scale(x, y) or scale(s)
93
+ const sm = t.match(/scale\(([^)]+)\)/)
94
+ if (sm) {
95
+ const vals = sm[1].split(',').map(v => parseFloat(v.trim()))
96
+ return vals.length >= 2 ? (vals[0] + vals[1]) / 2 : vals[0]
97
+ }
98
+
99
+ return 1
100
+ }
101
+
102
+ export function getInverseScale(el = '.share-page') {
103
+ const s = getPageScale(el)
104
+ return s > 0 ? 1 / s : 1
105
+ }
106
+
107
+ // ---------- scaler instance ----------
108
+
109
+ export function createScaler(el, options = {}) {
110
+ const target = resolveEl(el)
111
+ if (!target) throw new Error('[one-screen-scale] element not found')
112
+
113
+ const {
114
+ mode = 'contain',
115
+ visualWidth = 450,
116
+ origin = 'top center',
117
+ autoResize = true,
118
+ /** 是否自动注入模式所需的宽高基础样式,默认 true */
119
+ injectBaseStyles = true,
120
+ /**
121
+ * 内容尺寸变化时自动重算(图片 load、字体、DOM 撑高)。
122
+ * 解决刷新偶发「图未加载完就测量 → scale 偏大」。
123
+ */
124
+ observeContent = true,
125
+ } = options
126
+
127
+ let currentScale = 1
128
+ let resizeHandler = null
129
+ let loadHandler = null
130
+ let windowLoadHandler = null
131
+ let rafId = 0
132
+ let unlockRaf = 0
133
+ let ro = null
134
+ let refreshing = false
135
+ let lastMeasured = { w: 0, h: 0 }
136
+ // start / stop 各加一,用来丢掉停掉之后才回来的字体、帧回调
137
+ let session = 0
138
+
139
+ // fixed-width 会改 inline width/height,stop 时还原
140
+ const savedInline = {
141
+ width: target.style.width,
142
+ height: target.style.height,
143
+ transform: target.style.transform,
144
+ transformOrigin: target.style.transformOrigin,
145
+ }
146
+
147
+ function compute() {
148
+ const sw = target.offsetWidth
149
+ const sh = target.offsetHeight
150
+ const tw = document.documentElement.clientWidth || window.innerWidth
151
+ const th = window.innerHeight
152
+
153
+ lastMeasured = { w: sw, h: sh }
154
+
155
+ return calculateScale({
156
+ sourceWidth: sw,
157
+ sourceHeight: sh,
158
+ targetWidth: tw,
159
+ targetHeight: th,
160
+ mode,
161
+ visualWidth,
162
+ })
163
+ }
164
+
165
+ function refresh() {
166
+ refreshing = true
167
+ const next = compute()
168
+ currentScale = next
169
+ // 始终写入,保证首次 scale=1 时也带上 transform-origin
170
+ applyScale(target, next, origin)
171
+
172
+ // fixed-width 模式:反向补偿高度(视觉宽固定,布局宽仍用视口宽再缩小)
173
+ if (mode === 'fixed-width' && next > 0) {
174
+ const viewportWidth = document.documentElement.clientWidth || window.innerWidth
175
+ const nextW = `${viewportWidth}px`
176
+ const nextH = `${Math.round(window.innerHeight / next)}px`
177
+ // 值不变不写,避免 ResizeObserver 死循环
178
+ if (target.style.width !== nextW) target.style.width = nextW
179
+ if (target.style.height !== nextH) target.style.height = nextH
180
+ }
181
+ // 等布局提交后再放开,避免 RO 回调里立刻重入
182
+ const token = session
183
+ cancelAnimationFrame(unlockRaf)
184
+ unlockRaf = requestAnimationFrame(() => {
185
+ if (token !== session) return
186
+ refreshing = false
187
+ })
188
+ return currentScale
189
+ }
190
+
191
+ function scheduleRefresh() {
192
+ if (refreshing) return
193
+ cancelAnimationFrame(rafId)
194
+ const token = session
195
+ rafId = requestAnimationFrame(() => {
196
+ if (token !== session) return
197
+ // 尺寸没变就跳过(fixed-width 改 height 触发的 RO)
198
+ const w = target.offsetWidth
199
+ const h = target.offsetHeight
200
+ if (w === lastMeasured.w && h === lastMeasured.h && target.style.transform) {
201
+ // 视口变化仍需算:由 window.resize 路径直接 refresh
202
+ return
203
+ }
204
+ refresh()
205
+ })
206
+ }
207
+
208
+ function onWindowResize() {
209
+ refresh()
210
+ }
211
+
212
+ function start() {
213
+ session += 1
214
+ const token = session
215
+ // 复用同一实例 start 时,上一次 stop 之后留下的锁要清掉
216
+ refreshing = false
217
+ if (injectBaseStyles) {
218
+ applyBaseStyles(target, mode)
219
+ }
220
+ // 注入样式后再量尺寸
221
+ refresh()
222
+
223
+ if (autoResize) {
224
+ resizeHandler = onWindowResize
225
+ window.addEventListener('resize', resizeHandler)
226
+ }
227
+
228
+ if (observeContent && typeof window !== 'undefined') {
229
+ // 1) 子树布局尺寸变化(图片解码后撑高最常见)
230
+ if (typeof ResizeObserver !== 'undefined') {
231
+ ro = new ResizeObserver(() => scheduleRefresh())
232
+ ro.observe(target)
233
+ }
234
+
235
+ // 2) 捕获阶段听内部 img/video 的 load(含后插入的节点)
236
+ loadHandler = (e) => {
237
+ const t = e.target
238
+ if (t && (t.tagName === 'IMG' || t.tagName === 'VIDEO' || t.tagName === 'IFRAME')) {
239
+ scheduleRefresh()
240
+ }
241
+ }
242
+ target.addEventListener('load', loadHandler, true)
243
+ target.addEventListener('error', loadHandler, true)
244
+
245
+ // 3) 字体就绪。stop 之后 session 变了,这次回调直接丢掉
246
+ if (document.fonts && document.fonts.ready) {
247
+ document.fonts.ready
248
+ .then(() => {
249
+ if (token !== session) return
250
+ scheduleRefresh()
251
+ })
252
+ .catch(() => {})
253
+ }
254
+
255
+ // 4) 整页资源 load(缓存命中时可能已 complete)
256
+ if (document.readyState === 'complete') {
257
+ scheduleRefresh()
258
+ } else {
259
+ windowLoadHandler = () => scheduleRefresh()
260
+ window.addEventListener('load', windowLoadHandler, { once: true })
261
+ }
262
+
263
+ // 5) 再等两帧,覆盖首屏同步布局抖动
264
+ requestAnimationFrame(() => {
265
+ requestAnimationFrame(() => scheduleRefresh())
266
+ })
267
+ }
268
+
269
+ return currentScale
270
+ }
271
+
272
+ function stop() {
273
+ session += 1
274
+ if (resizeHandler) {
275
+ window.removeEventListener('resize', resizeHandler)
276
+ resizeHandler = null
277
+ }
278
+ if (loadHandler) {
279
+ target.removeEventListener('load', loadHandler, true)
280
+ target.removeEventListener('error', loadHandler, true)
281
+ loadHandler = null
282
+ }
283
+ if (windowLoadHandler) {
284
+ window.removeEventListener('load', windowLoadHandler)
285
+ windowLoadHandler = null
286
+ }
287
+ if (ro) {
288
+ ro.disconnect()
289
+ ro = null
290
+ }
291
+ cancelAnimationFrame(rafId)
292
+ cancelAnimationFrame(unlockRaf)
293
+ rafId = 0
294
+ unlockRaf = 0
295
+
296
+ if (injectBaseStyles) {
297
+ removeBaseStyles(target)
298
+ }
299
+ target.style.width = savedInline.width
300
+ target.style.height = savedInline.height
301
+ target.style.transform = savedInline.transform
302
+ target.style.transformOrigin = savedInline.transformOrigin
303
+ target.style.removeProperty('--one-screen-scale')
304
+ target.style.removeProperty('--one-screen-inverse-scale')
305
+ }
306
+
307
+ return { start, stop, refresh, getScale: () => currentScale }
308
+ }
309
+
310
+ export {
311
+ applyBaseStyles,
312
+ removeBaseStyles,
313
+ applyCompensateStyles,
314
+ removeCompensateStyles,
315
+ ensureBaseStyleSheet,
316
+ BASE_CLASS,
317
+ } from './baseStyles.js'
package/src/directives.js CHANGED
@@ -1,34 +1,144 @@
1
- /**
2
- * Vue 3 指令
3
- * v-fit-screen 页面级缩放
4
- * v-compensate 组件级反缩放补偿
5
- */
6
- import { createScaler } from './core.js'
7
-
8
- // ---- v-fit-screen ----
9
-
10
- export const vFitScreen = {
11
- mounted(el, binding) {
12
- const options = binding.value || {}
13
- const scaler = createScaler(el, options)
14
- scaler.start()
15
- el.__fitScreenScaler = scaler
16
- },
17
-
18
- updated(el, binding) {
19
- const scaler = el.__fitScreenScaler
20
- if (scaler) {
21
- const options = binding.value || {}
22
- // 简单处理:重新 refresh
23
- scaler.refresh()
24
- }
25
- },
26
-
27
- unmounted(el) {
28
- const scaler = el.__fitScreenScaler
29
- if (scaler) {
30
- scaler.stop()
31
- delete el.__fitScreenScaler
32
- }
33
- }
34
- }
1
+ /**
2
+ * Vue 3 指令
3
+ * v-fit-screen 页面级缩放
4
+ * v-compensate 组件级反缩放补偿(ECharts / Element Plus 等)
5
+ */
6
+ import { createScaler } from './core.js'
7
+ import { createCompensate } from './compensate.js'
8
+
9
+ function readOptions(binding) {
10
+ return binding.value && typeof binding.value === 'object' ? binding.value : {}
11
+ }
12
+
13
+ function mountScaler(el, binding) {
14
+ const options = readOptions(binding)
15
+ const scaler = createScaler(el, options)
16
+ scaler.start()
17
+ el.__fitScreenScaler = scaler
18
+ el.__fitScreenOptionsKey = JSON.stringify({
19
+ mode: options.mode || 'contain',
20
+ visualWidth: options.visualWidth,
21
+ origin: options.origin,
22
+ autoResize: options.autoResize,
23
+ injectBaseStyles: options.injectBaseStyles,
24
+ observeContent: options.observeContent,
25
+ })
26
+ }
27
+
28
+ function unmountScaler(el) {
29
+ const scaler = el.__fitScreenScaler
30
+ if (scaler) {
31
+ scaler.stop()
32
+ delete el.__fitScreenScaler
33
+ delete el.__fitScreenOptionsKey
34
+ }
35
+ }
36
+
37
+ // ---- v-fit-screen ----
38
+
39
+ export const vFitScreen = {
40
+ mounted(el, binding) {
41
+ mountScaler(el, binding)
42
+ },
43
+
44
+ updated(el, binding) {
45
+ const options = readOptions(binding)
46
+ const key = JSON.stringify({
47
+ mode: options.mode || 'contain',
48
+ visualWidth: options.visualWidth,
49
+ origin: options.origin,
50
+ autoResize: options.autoResize,
51
+ injectBaseStyles: options.injectBaseStyles,
52
+ observeContent: options.observeContent,
53
+ })
54
+
55
+ if (el.__fitScreenOptionsKey !== key) {
56
+ unmountScaler(el)
57
+ mountScaler(el, binding)
58
+ return
59
+ }
60
+
61
+ el.__fitScreenScaler?.refresh()
62
+ },
63
+
64
+ unmounted(el) {
65
+ unmountScaler(el)
66
+ },
67
+ }
68
+
69
+ function readCompensateOptions(binding) {
70
+ const value = binding?.value
71
+ const modifiers = binding?.modifiers || {}
72
+ const options = value && typeof value === 'object' ? { ...value } : {}
73
+ // v-compensate.resize-canvas / .resizeCanvas / 旧名 .echarts
74
+ if (
75
+ modifiers.resizeCanvas ||
76
+ modifiers['resize-canvas'] ||
77
+ modifiers.echarts ||
78
+ value === 'resize-canvas' ||
79
+ value === 'resizeCanvas' ||
80
+ value === 'echarts'
81
+ ) {
82
+ options.resizeCanvas = options.resizeCanvas || true
83
+ }
84
+ return options
85
+ }
86
+
87
+ function compensateOptionsKey(options) {
88
+ return JSON.stringify({
89
+ resizeCanvas: Boolean(options.resizeCanvas || options.echarts || options.echartsLib),
90
+ hasLib: Boolean(
91
+ (options.echarts && typeof options.echarts === 'object') || options.echartsLib
92
+ ),
93
+ hasOnRefresh: typeof options.onRefresh === 'function',
94
+ })
95
+ }
96
+
97
+ /**
98
+ * v-compensate — 挂在「被页面 scale 搞坏」的第三方组件外包一层。
99
+ *
100
+ * 原理与业务 WinRateChart 手写一致(JS 行内,非纯 CSS):
101
+ * transform: scale(inverse); width/height: 100% * pageScale; origin: top left
102
+ *
103
+ * 用法:
104
+ * <div class="slot"><div v-compensate><Whatever /></div></div>
105
+ * <div class="slot"><div v-compensate.resize-canvas><Chart /></div></div>
106
+ *
107
+ * `.resize-canvas` / `{ resizeCanvas: true }`:补偿后通知子树 canvas 重绘
108
+ * (探测 ECharts / Chart.js,并派发 one-screen-scale-canvas-resize)。
109
+ */
110
+ function mountCompensate(el) {
111
+ const api = createCompensate(el, () => el.__oneScreenCompensateOptions || {})
112
+ el.__oneScreenCompensateApi = api
113
+ el.__oneScreenCompensateKey = compensateOptionsKey(el.__oneScreenCompensateOptions || {})
114
+ }
115
+
116
+ export const vCompensate = {
117
+ mounted(el, binding) {
118
+ el.__oneScreenCompensateOptions = readCompensateOptions(binding)
119
+ mountCompensate(el)
120
+ },
121
+
122
+ updated(el, binding) {
123
+ const options = readCompensateOptions(binding)
124
+ const key = compensateOptionsKey(options)
125
+ el.__oneScreenCompensateOptions = options
126
+ // resizeCanvas / 图表库变了才重建监听;onRefresh 每次 refresh 现读
127
+ if (el.__oneScreenCompensateKey !== key) {
128
+ el.__oneScreenCompensateApi?.stop()
129
+ mountCompensate(el)
130
+ return
131
+ }
132
+ el.__oneScreenCompensateApi?.refresh()
133
+ },
134
+
135
+ unmounted(el) {
136
+ el.__oneScreenCompensateApi?.stop()
137
+ delete el.__oneScreenCompensateApi
138
+ delete el.__oneScreenCompensateKey
139
+ delete el.__oneScreenCompensateOptions
140
+ },
141
+ }
142
+
143
+ /** 别名,与早期注释里的命名一致 */
144
+ export const vFitCompensate = vCompensate