Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
B
basic-vue-admin
概览
概览
详情
活动
周期分析
版本库
存储库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
Basic
basic-vue-admin
Commits
e3e4a1f1
提交
e3e4a1f1
authored
8月 12, 2023
作者:
test
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat: 优化 ipc 通信以及部分前端内容优化
上级
aaf9c031
隐藏空白字符变更
内嵌
并排
正在显示
14 个修改的文件
包含
147 行增加
和
127 行删除
+147
-127
electron-builder.yml
electron-builder.yml
+1
-1
config.ts
src-electron/main/config.ts
+8
-0
handler.ts
src-electron/main/handler.ts
+30
-32
index.ts
src-electron/main/index.ts
+15
-12
log.ts
src-electron/main/log.ts
+3
-2
store.ts
src-electron/main/store.ts
+12
-10
update.ts
src-electron/main/update.ts
+3
-3
client.ts
src/store/modules/client.ts
+5
-5
AboutModal.vue
src/views/main-example/components/AboutModal.vue
+2
-2
AboutModal.vue
src/views/main/components/AboutModal.vue
+36
-33
Footer.vue
src/views/main/components/Footer.vue
+4
-13
Header.vue
src/views/main/components/Header.vue
+16
-13
config.ts
src/views/main/config.ts
+11
-0
index.vue
src/views/main/index.vue
+1
-1
没有找到文件。
electron-builder.yml
浏览文件 @
e3e4a1f1
...
...
@@ -26,4 +26,4 @@ nsis:
deleteAppDataOnUninstall
:
false
publish
:
provider
:
generic
url
:
https://
example
.com/auto-updates
url
:
https://
client.yiring
.com/auto-updates
src-electron/main/config.ts
0 → 100644
浏览文件 @
e3e4a1f1
export
const
app
=
{
// 应用名称
name
:
'basic-electron-client'
,
// 密钥
key
:
'yiring.com'
,
// 调试模式
debug
:
false
,
}
src-electron/main/handler.ts
浏览文件 @
e3e4a1f1
...
...
@@ -5,41 +5,39 @@ import type { SettingStore } from '/#/store'
export
async
function
useHandler
(
win
:
BrowserWindow
,
store
:
ElectronStore
<
SettingStore
>
)
{
// ==================== ipc handle ===================
// 关闭程序
ipcMain
.
handle
(
'close'
,
()
=>
{
win
.
close
()
app
.
quit
()
})
// 重新加载
ipcMain
.
handle
(
'reload'
,
()
=>
{
win
.
reload
()
})
// 打开 F12
ipcMain
.
handle
(
'debug'
,
()
=>
{
win
.
webContents
.
toggleDevTools
()
})
// 最大化
ipcMain
.
handle
(
'max'
,
()
=>
{
if
(
win
.
isMaximized
())
{
win
.
restore
()
}
else
{
win
.
maximize
()
ipcMain
.
handle
(
'window:action'
,
(
_
,
action
:
string
)
=>
{
switch
(
action
)
{
// 关闭程序
case
'close'
:
win
.
close
()
app
.
quit
()
break
// 重新加载
case
'reload'
:
win
.
reload
()
break
// 打开 F12
case
'debug'
:
win
.
webContents
?.
toggleDevTools
()
break
// 最大化/还原
case
'max'
:
win
.
isMaximized
()
?
win
.
restore
()
:
win
.
maximize
()
break
// 最小化
case
'min'
:
win
.
minimize
()
break
// 置顶/取消置顶
case
'top'
:
win
.
setAlwaysOnTop
(
!
win
.
isAlwaysOnTop
())
break
default
:
console
.
warn
(
'[window:action] unknow'
,
action
)
break
}
})
// 最小化
ipcMain
.
handle
(
'min'
,
()
=>
{
win
.
minimize
()
})
// 置顶
ipcMain
.
handle
(
'top'
,
(
_
,
value
:
boolean
)
=>
{
win
.
setAlwaysOnTop
(
value
)
})
// 设置窗口是否总在最前
if
(
store
.
get
(
'system.alwaysOnTop'
))
{
win
.
setAlwaysOnTop
(
true
)
...
...
src-electron/main/index.ts
浏览文件 @
e3e4a1f1
...
...
@@ -17,28 +17,31 @@ process.env.PUBLIC = app.isPackaged ? __dirname : path.join(process.env.DIST_ELE
async
function
createWindow
():
Promise
<
BrowserWindow
>
{
// Create the browser window.
const
mainWindow
=
new
BrowserWindow
({
width
:
900
,
height
:
685
,
show
:
false
,
autoHideMenuBar
:
true
,
// icon: path.join(__dirname, '../../build/electron/icon.ico'),
webPreferences
:
{
preload
:
path
.
join
(
__dirname
,
'../preload/index.js'
),
sandbox
:
false
,
// Warning: Enable nodeIntegration and disable contextIsolation is not secure in production
// Consider using contextBridge.exposeInMainWorld
// Read more on https://www.electronjs.org/docs/latest/tutorial/context-isolation
nodeIntegration
:
true
,
contextIsolation
:
false
,
sandbox
:
false
,
},
// 窗口大小
width
:
900
,
height
:
685
,
// icon
...(
process
.
platform
===
'linux'
?
{
icon
:
path
.
join
(
__dirname
,
'../../build/electron/icon.ico'
)
}
:
{}),
// 隐藏菜单栏
autoHideMenuBar
:
true
,
// 默认不显示
show
:
false
,
// 无边框
frame
:
false
,
// 自定义 titleBar
// titleBarStyle: 'hidden',
// titleBarOverlay: {
// height: 32,
// },
})
mainWindow
.
on
(
'ready-to-show'
,
()
=>
{
...
...
src-electron/main/log.ts
浏览文件 @
e3e4a1f1
import
os
from
'node:os'
import
log
from
'electron-log'
import
{
app
}
from
'./config'
log
.
transports
.
file
.
maxSize
=
1002430
log
.
transports
.
file
.
format
=
'[{y}-{m}-{d} {h}:{i}:{s}.{ms}] [{level}]{scope} {text}'
// 需要保存的
了
路径
log
.
transports
.
file
.
resolvePath
=
()
=>
`
${
os
.
homedir
()}
\\Documents\\
multi-screen-control-client
.log`
// 需要保存的路径
log
.
transports
.
file
.
resolvePath
=
()
=>
`
${
os
.
homedir
()}
\\Documents\\
${
app
.
name
}
.log`
// 全局的 console.info 写进日志文件
console
.
info
=
log
.
info
...
...
src-electron/main/store.ts
浏览文件 @
e3e4a1f1
import
type
{
BrowserWindow
}
from
'electron'
import
type
{
SettingStore
}
from
'/#/store'
import
Store
from
'electron-store'
import
{
machineIdSync
}
from
'node-machine-id'
import
type
{
BrowserWindow
}
from
'electron'
import
{
ipcMain
}
from
'electron'
import
{
autoUpdater
}
from
'electron-updater'
import
{
machineIdSync
}
from
'node-machine-id'
import
{
app
}
from
'./config'
export
async
function
useStore
(
_win
:
BrowserWindow
)
{
// 初始化配置
const
store
=
new
Store
<
SettingStore
>
({
name
:
'basic-electron-client-config'
,
name
:
app
.
name
,
encryptionKey
:
app
.
key
,
clearInvalidConfig
:
true
,
encryptionKey
:
'yiring.com'
,
defaults
:
{
system
:
{
// 机器码
machineId
:
machineIdSync
().
toUpperCase
(),
// 调试模式
debug
:
false
,
debug
:
app
.
debug
,
// 是否总在最前
alwaysOnTop
:
false
,
// 检查更新地址
...
...
@@ -26,13 +29,11 @@ export async function useStore(_win: BrowserWindow) {
// ==================== ipc handle ===================
// 获取配置
ipcMain
.
handle
(
'store
-
get'
,
(
_
,
key
)
=>
{
ipcMain
.
handle
(
'store
:
get'
,
(
_
,
key
)
=>
{
return
store
.
get
(
key
)
})
// 设置配置
ipcMain
.
handle
(
'store-set'
,
(
_
,
key
,
value
)
=>
{
console
.
log
(
'store-set'
,
key
,
value
)
ipcMain
.
handle
(
'store:set'
,
(
_
,
key
,
value
)
=>
{
if
(
key
===
'system'
)
{
const
oldValue
=
store
.
get
(
key
)
if
(
oldValue
?.
feedURL
!==
value
.
feedURL
)
{
...
...
@@ -47,9 +48,10 @@ export async function useStore(_win: BrowserWindow) {
}
store
.
set
(
key
,
value
)
console
.
log
(
'store:set'
,
key
,
value
)
})
// 重置配置
ipcMain
.
handle
(
'store
-
reset'
,
(
_
,
keys
)
=>
{
ipcMain
.
handle
(
'store
:
reset'
,
(
_
,
keys
)
=>
{
store
.
reset
(
keys
)
})
...
...
src-electron/main/update.ts
浏览文件 @
e3e4a1f1
...
...
@@ -23,7 +23,7 @@ export async function useUpdater(win: BrowserWindow, store: ElectronStore<Settin
function
sendUpdateMessageToWindow
(
body
:
{
type
:
MessageType
;
text
:
string
})
{
log
.
info
(
`
${
body
.
type
}
:
${
body
.
text
}
`
)
win
.
webContents
.
send
(
'updater
-
message'
,
body
)
win
.
webContents
.
send
(
'updater
:
message'
,
body
)
}
autoUpdater
.
on
(
'checking-for-update'
,
()
=>
{
...
...
@@ -55,7 +55,7 @@ export async function useUpdater(win: BrowserWindow, store: ElectronStore<Settin
})
// 监听界面发送的检查更新事件
ipcMain
.
on
(
'
checkForUpdate
'
,
()
=>
{
ipcMain
.
on
(
'
updater:check
'
,
()
=>
{
checkForUpdate
()
})
...
...
@@ -73,7 +73,7 @@ export async function useUpdater(win: BrowserWindow, store: ElectronStore<Settin
}
}
catch
(
error
:
any
)
{
log
.
info
(
`[检查更新] 出现异常:
${
error
}
`
)
win
.
webContents
.
send
(
'app
-
notify'
,
{
win
.
webContents
.
send
(
'app
:
notify'
,
{
type
:
'error'
,
message
:
error
.
message
,
})
...
...
src/store/modules/client.ts
浏览文件 @
e3e4a1f1
...
...
@@ -14,7 +14,7 @@ export const useClientStore = defineStore('app-client', () => {
}
async
function
getSystem
()
{
system
.
value
=
await
ipc
.
invokeAsync
<
ISystem
>
(
'store
-
get'
,
'system'
)
system
.
value
=
await
ipc
.
invokeAsync
<
ISystem
>
(
'store
:
get'
,
'system'
)
return
system
.
value
}
...
...
@@ -23,21 +23,21 @@ export const useClientStore = defineStore('app-client', () => {
const
machineId
=
system
.
value
.
machineId
system
.
value
=
value
system
.
value
.
machineId
=
machineId
ipc
.
invoke
(
'store
-
set'
,
'system'
,
toRaw
(
system
.
value
))
ipc
.
invoke
(
'store
:
set'
,
'system'
,
toRaw
(
system
.
value
))
}
function
setDebug
(
debug
:
boolean
):
void
{
system
.
value
.
debug
=
debug
ipc
.
invoke
(
'store
-
set'
,
'system'
,
toRaw
(
system
.
value
))
ipc
.
invoke
(
'store
:
set'
,
'system'
,
toRaw
(
system
.
value
))
}
function
setAlwaysOnTop
(
alwaysOnTop
:
boolean
):
void
{
system
.
value
.
alwaysOnTop
=
alwaysOnTop
ipc
.
invoke
(
'store
-
set'
,
'system'
,
toRaw
(
system
.
value
))
ipc
.
invoke
(
'store
:
set'
,
'system'
,
toRaw
(
system
.
value
))
}
async
function
reset
(...
keys
:
[
'system'
])
{
ipc
.
invoke
(
'store
-
reset'
,
keys
)
ipc
.
invoke
(
'store
:
reset'
,
keys
)
await
init
()
}
...
...
src/views/main-example/components/AboutModal.vue
浏览文件 @
e3e4a1f1
...
...
@@ -24,8 +24,8 @@
// 监听检查更新事件
let
hide
=
null
ipc
.
on
(
'updater
-
message'
,
(
_e
,
body
:
{
type
:
MessageType
;
text
:
string
})
=>
{
console
.
log
(
'updater
-
message'
,
body
)
ipc
.
on
(
'updater
:
message'
,
(
_e
,
body
:
{
type
:
MessageType
;
text
:
string
})
=>
{
console
.
log
(
'updater
:
message'
,
body
)
const
{
type
,
text
}
=
body
if
(
type
===
'checking-for-update'
||
type
===
'download-progress'
)
{
...
...
src/views/main/components/AboutModal.vue
浏览文件 @
e3e4a1f1
<
script
setup
lang=
"tsx"
>
import
dayjs
from
'dayjs'
import
{
BasicModal
}
from
'/@/components/Modal'
import
{
Icon
}
from
'/@/components/Icon'
import
{
app
}
from
'../config'
import
{
useElectron
}
from
'@/hooks/electron/useElectron'
import
{
useMessage
}
from
'@/hooks/web/useMessage'
import
{
getEnvText
}
from
'/@/utils/env'
...
...
@@ -19,41 +19,45 @@
const
{
ipcRenderer
:
ipc
}
=
useElectron
()
const
{
createMessage
}
=
useMessage
()
const
startYear
=
2023
const
currentYear
=
dayjs
().
year
()
const
yearText
=
ref
<
string
>
(
currentYear
===
startYear
?
`
${
currentYear
}
`
:
`
${
startYear
}
-
${
currentYear
}
`
)
const
loading
=
ref
<
boolean
>
(
false
)
const
versions
=
reactive
({
...
window
.
electron
.
process
.
versions
})
const
isDebug
=
computed
(()
=>
clientStore
.
system
?.
debug
)
const
versions
=
reactive
({
...
window
.
electron
.
process
.
versions
})
// 监听检查更新事件
let
hide
=
null
ipc
.
on
(
'updater-message'
,
(
_e
,
body
:
{
type
:
MessageType
;
text
:
string
})
=>
{
console
.
log
(
'updater-message'
,
body
)
const
{
type
,
text
}
=
body
if
(
type
===
'checking-for-update'
||
type
===
'download-progress'
)
{
loading
.
value
=
true
hide
=
createMessage
.
loading
({
key
:
'updating'
,
content
:
text
,
duration
:
0
,
})
}
else
if
(
type
===
'update-available'
||
type
===
'update-not-available'
||
type
===
'update-downloaded'
)
{
createMessage
.
success
(
text
)
}
else
if
(
type
===
'error'
)
{
if
(
text
.
startsWith
(
'net::'
))
{
createMessage
.
warn
(
'检查更新失败: 请检查网络或者更新源配置'
)
}
else
{
createMessage
.
error
(
`检查更新失败:
${
text
}
`
)
onMounted
(()
=>
{
ipc
.
on
(
'updater:message'
,
(
_e
,
body
:
{
type
:
MessageType
;
text
:
string
})
=>
{
console
.
log
(
'updater:message'
,
body
)
const
{
type
,
text
}
=
body
if
(
type
===
'checking-for-update'
||
type
===
'download-progress'
)
{
loading
.
value
=
true
hide
=
createMessage
.
loading
({
key
:
'updating'
,
content
:
text
,
duration
:
0
,
})
}
else
if
(
type
===
'update-available'
||
type
===
'update-not-available'
||
type
===
'update-downloaded'
)
{
createMessage
.
success
(
text
)
}
else
if
(
type
===
'error'
)
{
if
(
text
.
startsWith
(
'net::'
))
{
createMessage
.
warn
(
'检查更新失败: 请检查网络或者更新源配置'
)
}
else
{
createMessage
.
error
(
`检查更新失败:
${
text
}
`
)
}
}
}
if
(
type
===
'error'
||
type
===
'update-downloaded'
||
type
===
'update-not-available'
)
{
loading
.
value
=
false
hide
?.()
}
if
(
type
===
'error'
||
type
===
'update-downloaded'
||
type
===
'update-not-available'
)
{
loading
.
value
=
false
hide
?.()
}
})
})
// 发送检查更新
function
checkUpdate
()
{
ipc
.
send
(
'updater:check'
)
}
</
script
>
<
template
>
...
...
@@ -72,7 +76,6 @@
<div
class=
"app-icon relative"
>
<img
src=
"/logo.png"
/>
</div>
<!-- <div class="app-name">{{ $app.name }}</div> -->
<div
class=
"app-description"
>
{{ $app.description }}
</div>
<div
class=
"app-version"
>
<a-tooltip>
...
...
@@ -89,7 +92,7 @@
</div>
<!-- 检查版本更新按钮 -->
<div
class=
"app-check-update-action"
>
<a-button
type=
"dashed"
:loading=
"loading"
@
click=
"
ipc.send('checkForUpdate')
"
>
<a-button
type=
"dashed"
:loading=
"loading"
@
click=
"
checkUpdate
"
>
<Icon
icon=
"ant-design:bulb-outlined"
v-show=
"!loading"
/>
检查更新
</a-button>
...
...
@@ -97,11 +100,11 @@
</div>
<!-- 版本信息 -->
<div
class=
"about-footer"
>
<div
class=
"company"
>
长沙壹润信息科技发展有限公司
</div>
<div
class=
"company"
>
{{ app.copyright.company }}
</div>
<div
class=
"copyright"
>
<span>
Copyright © {{
yearText
}}
</span>
<span>
Copyright © {{
app.copyright.year
}}
</span>
<span
class=
"link"
>
<a
target=
"_blank"
href=
"https://yiring.com"
>
YiRing.com
</a>
<a
target=
"_blank"
:href=
"app.copyright.link"
>
{{ app.copyright.text }}
</a>
</span>
</div>
</div>
...
...
src/views/main/components/Footer.vue
浏览文件 @
e3e4a1f1
<
script
setup
lang=
"ts"
>
import
dayjs
from
'dayjs'
import
{
LinkOutlined
}
from
'@ant-design/icons-vue'
const
year
=
ref
(
dayjs
().
year
())
const
company
=
ref
<
string
>
(
'长沙壹润信息科技发展有限公司'
)
const
copyright
=
reactive
({
link
:
'https://yiring.com'
,
text
:
'YiRing.com'
,
})
import
{
app
}
from
'../config'
</
script
>
<
template
>
<div
class=
"footer"
>
<div
class=
"company"
>
{{
company
}}
</div>
<div
class=
"company"
>
{{
app
.
copyright
.
company
}}
</div>
<div
class=
"copyright"
>
<span>
Copyright ©
{{
year
}}
</span>
<span>
Copyright ©
{{
app
.
copyright
.
year
}}
</span>
<span
class=
"link"
>
<LinkOutlined
/>
<a
target=
"_blank"
:href=
"copyright.link"
>
{{
copyright
.
text
}}
</a>
<a
target=
"_blank"
:href=
"app.copyright.link"
>
{{
app
.
copyright
.
text
}}
</a>
</span>
</div>
</div>
...
...
src/views/main/components/Header.vue
浏览文件 @
e3e4a1f1
...
...
@@ -17,13 +17,13 @@
const
[
aboutRegister
,
{
openModal
:
openAboutModal
}]
=
useModal
()
const
[
settingRegister
,
{
openModal
:
openSettingModal
}]
=
useModal
()
function
handle
(
action
:
'reload'
|
'debug'
|
'min'
|
'max'
|
'close'
|
'top'
)
{
function
handle
Action
(
action
:
'reload'
|
'debug'
|
'min'
|
'max'
|
'close'
|
'top'
)
{
if
(
action
===
'close'
)
{
createConfirm
({
iconType
:
'warning'
,
content
:
'确认关闭应用吗?'
,
onOk
()
{
ipc
.
invoke
(
action
)
ipc
.
invoke
(
'window:action'
,
action
)
},
})
return
...
...
@@ -32,11 +32,10 @@
if
(
action
===
'top'
)
{
clientStore
.
setAlwaysOnTop
(
!
isAlwaysOnTop
.
value
)
createMessage
.
success
(
`应用
${
isAlwaysOnTop
.
value
?
''
:
'取消'
}
置顶`
)
ipc
.
invoke
(
action
,
isAlwaysOnTop
.
value
)
return
}
ipc
.
invoke
(
action
)
ipc
.
invoke
(
'window:action'
,
action
)
}
function
about
()
{
...
...
@@ -48,8 +47,8 @@
}
// 监听全局通知
ipc
.
on
(
'app
-
notify'
,
(
_
,
body
)
=>
{
console
.
log
(
'app
-
notify'
,
body
)
ipc
.
on
(
'app
:
notify'
,
(
_
,
body
)
=>
{
console
.
log
(
'app
:
notify'
,
body
)
if
(
body
?.
message
.
startsWith
(
'net::'
))
{
createMessage
.
warn
(
'更新源访问失败,请检查网络或者更新源配置'
)
...
...
@@ -70,12 +69,12 @@
</a-space>
<a-space
class=
"btns"
>
<a-tooltip
title=
"重新加载"
v-if=
"isDebug"
>
<a-button
type=
"text"
primary
@
click=
"handle('reload')"
>
<a-button
type=
"text"
primary
@
click=
"handle
Action
('reload')"
>
<Icon
icon=
"ant-design:reload-outlined"
:size=
"22"
/>
</a-button>
</a-tooltip>
<a-tooltip
title=
"调试"
v-if=
"isDebug"
>
<a-button
type=
"text"
primary
@
click=
"handle('debug')"
>
<a-button
type=
"text"
primary
@
click=
"handle
Action
('debug')"
>
<Icon
icon=
"ant-design:bug-outlined"
:size=
"22"
/>
</a-button>
</a-tooltip>
...
...
@@ -90,22 +89,26 @@
</a-button>
</a-tooltip>
<a-tooltip
:title=
"isAlwaysOnTop ? '取消置顶' : '置顶'"
>
<a-button
type=
"text"
primary
@
click=
"handle('top')"
:class=
"
{ actived: isAlwaysOnTop }">
<Icon
icon=
"ph:push-pin-duotone"
:size=
"22"
:color=
"isAlwaysOnTop ? 'green' : '#000'"
/>
<a-button
type=
"text"
primary
@
click=
"handleAction('top')"
:class=
"
{ actived: isAlwaysOnTop }">
<Icon
:icon=
"isAlwaysOnTop ? 'ph:push-pin-fill' : 'ph:push-pin'"
:size=
"22"
:color=
"isAlwaysOnTop ? 'green' : '#000'"
/>
</a-button>
</a-tooltip>
<a-tooltip
title=
"最小化"
>
<a-button
type=
"text"
primary
@
click=
"handle('min')"
>
<a-button
type=
"text"
primary
@
click=
"handle
Action
('min')"
>
<Icon
icon=
"ant-design:minus-outlined"
:size=
"22"
/>
</a-button>
</a-tooltip>
<a-tooltip
title=
"缩放"
>
<a-button
type=
"text"
primary
@
click=
"handle('max')"
>
<a-button
type=
"text"
primary
@
click=
"handle
Action
('max')"
>
<Icon
icon=
"uil:window-maximize"
:size=
"22"
/>
</a-button>
</a-tooltip>
<a-tooltip
title=
"关闭应用"
>
<a-button
type=
"text"
primary
@
click=
"handle('close')"
class=
"close"
>
<a-button
type=
"text"
primary
@
click=
"handle
Action
('close')"
class=
"close"
>
<Icon
icon=
"ant-design:close-outlined"
:size=
"22"
/>
</a-button>
</a-tooltip>
...
...
src/views/main/config.ts
0 → 100644
浏览文件 @
e3e4a1f1
const
startYear
=
2023
const
endYear
=
new
Date
().
getFullYear
()
export
const
app
=
{
copyright
:
{
text
:
'YiRing'
,
link
:
'https://yiring.com'
,
company
:
'长沙壹润信息科技发展有限公司'
,
year
:
startYear
===
endYear
?
`
${
startYear
}
`
:
`
${
startYear
}
-
${
endYear
}
`
,
},
}
src/views/main/index.vue
浏览文件 @
e3e4a1f1
...
...
@@ -4,7 +4,7 @@
import
Footer
from
'./components/Footer.vue'
onMounted
(()
=>
{
postMessage
({
payload
:
'loaded'
},
'*'
)
nextTick
(()
=>
postMessage
({
payload
:
'loaded'
},
'*'
)
)
})
</
script
>
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论