阅读时间:1 分钟
0 字
初始化配置
dux.ts 是应用真正被创建出来的地方。
最小写法
ts
import { createUni, defineUniConfig, resolveDuxConfig } from '@duxweb/uni'
import duxConfig from './dux.config'
import { routerManifest } from './runtime/router/manifest'
const config = resolveDuxConfig(duxConfig)
export const dux = createUni(defineUniConfig({
...config.runtime,
appName: config.app.name, // 应用名
tabBarMode: routerManifest.config.router.tabBarMode, // 当前 tabBar 模式
pages: routerManifest.pages, // 最终页面清单
modules: config.modules, // 当前模块列表
}))这里主要负责什么
text
读取 dux.config.ts
注入自动生成的页面和 manifest
注入扫描后的模块
创建 createUni() 应用实例
挂接应用级能力request
ts
request: {
getHeaders: () => ({
'X-App': config.app.name, // 每次请求带应用标识
}),
sign: async request => {
const ts = String(Date.now())
return {
query: {
...(request.query || {}),
ts, // 给 query 追加时间戳
},
}
},
}这里适合接:
text
header
sign
adapter
错误拦截继续看:请求配置
authProvider
ts
import { simpleAuthProvider } from '@duxweb/uni'
authProvider: simpleAuthProvider({
path: {
login: '/login',
check: '/check',
logout: '/logout',
},
method: {
login: 'POST',
check: 'GET',
logout: 'POST',
},
route: {
login: '/pages/auth/login',
index: '/pages/home/index',
},
})继续看:认证与会话
auth
ts
auth: {
autoCheckOnLaunch: true, // 默认 true,启动时自动校验
autoCheckOnShow: true, // 默认 true,回前台时自动校验
checkTtl: 300000, // 默认 5 分钟,前台校验节流时间
path: '/passport/check', // 可选,覆盖默认 check 接口
method: 'POST', // 可选,覆盖默认 check 方法
}适合:
text
希望启动时自动恢复登录态
希望 App 回前台时自动校验会话
不想在页面或模块里手动写 useCheck()默认行为是:
text
本地有 token 时,launch 自动 check
回前台且超过 checkTtl 时,show 自动 check
login 成功后不额外重复 checkdataProvider
ts
import { simpleDataProvider } from '@duxweb/uni'
dataProvider: simpleDataProvider({
apiUrl: '/api', // 统一 API 前缀
})继续看:数据查询
permission
ts
permission: {
redirectTo: '/pages/system/forbidden/index', // 无权限时跳转到统一页面
}它会和页面里的:
json
{
"auth": true,
"permission": "orders.read"
}一起工作。
socket
ts
socket: {
url: 'wss://example.com/ws',
auth: true, // 连接时自动带认证 token
connectOnLaunch: false, // 应用启动时不自动连接
connectOnLogin: true, // 登录成功后自动连接
disconnectOnLogout: true, // 退出登录时自动断开
keepAliveOnHide: true, // 应用切到后台时保持连接
}ts
sockets: {
chat: {
url: 'wss://example.com/ws/chat',
auth: true,
connectOnLogin: true,
},
notice: {
url: 'wss://example.com/ws/notice',
auth: true,
connectOnLaunch: true,
},
}适合:
text
客服
通知
消息流
全局在线状态如果你的业务是“登录后再建立全局长连接”,这就是推荐配置。
这里的 socket 是:
text
应用默认的那一条全局 WebSocket 连接配置这里的 sockets 是:
text
应用里的命名全局 WebSocket 连接集合如果你有多条 WebSocket:
text
默认主连接 => 放在 socket 里统一管理
命名全局连接 => 放在 sockets.xxx 里统一管理
页面局部连接 => 用 useSocket()这样页面里通常只需要:
ts
import { useSocketManager } from '@duxweb/uni'
const manager = useSocketManager()
manager.sendJson({
event: 'chat.message',
data: {
text: 'hello',
},
})命名全局连接则可以这样读:
ts
import { useSocketManager } from '@duxweb/uni'
const chatSocket = useSocketManager('chat')
chatSocket.sendJson({
event: 'chat.message',
data: {
text: 'hello',
},
})其他页面再通过:
ts
manager.subscribe('chat.message', handler)或者:
ts
useListener('socket:chat.message', handler)来消费消息即可。
如果监听的是命名全局连接,则事件名会变成:
ts
useListener('socket:chat:message', handler)
useListener('socket:chat:chat.message', handler)一条默认连接加两条命名连接的完整示例
ts
import {
createUni,
defineUniConfig,
resolveDuxConfig,
simpleAuthProvider,
simpleDataProvider,
} from '@duxweb/uni'
import duxConfig from './dux.config'
import { routerManifest } from './runtime/router/manifest'
const config = resolveDuxConfig(duxConfig)
export const dux = createUni(defineUniConfig({
...config.runtime,
appName: config.app.name,
tabBarMode: routerManifest.config.router.tabBarMode,
pages: routerManifest.pages,
modules: config.modules,
authProvider: simpleAuthProvider({
path: {
login: '/login',
check: '/check',
logout: '/logout',
},
}),
dataProvider: simpleDataProvider({
apiUrl: '/api',
}),
socket: {
url: 'wss://example.com/ws/main',
auth: true,
connectOnLogin: true,
},
sockets: {
chat: {
url: 'wss://example.com/ws/chat',
auth: true,
connectOnLogin: true,
},
notice: {
url: 'wss://example.com/ws/notice',
auth: true,
connectOnLaunch: true,
},
},
}))推荐职责拆分:
text
socket => 主业务连接、默认通知
sockets.chat => 聊天、客服、IM
sockets.notice => 系统推送、公告流storage / storageKey
ts
runtime: {
storageKey: 'my-app-session', // 自定义本地会话 key
}如果你要换底层存储实现,也是在这里接 storage。
一份完整示例
ts
import {
createUni,
defineUniConfig,
resolveDuxConfig,
simpleAuthProvider,
simpleDataProvider,
} from '@duxweb/uni'
import duxConfig from './dux.config'
import { routerManifest } from './runtime/router/manifest'
const config = resolveDuxConfig(duxConfig)
export const dux = createUni(defineUniConfig({
...config.runtime,
appName: config.app.name,
tabBarMode: routerManifest.config.router.tabBarMode,
pages: routerManifest.pages,
modules: config.modules,
request: {
getHeaders: () => ({
'X-App': config.app.name,
}),
},
authProvider: simpleAuthProvider({
path: {
login: '/login',
check: '/check',
logout: '/logout',
},
}),
dataProvider: simpleDataProvider({
apiUrl: '/api',
}),
permission: {
redirectTo: '/pages/system/forbidden/index',
},
socket: {
url: 'wss://example.com/ws',
auth: true,
},
}))不要把什么放进来
text
页面组件代码
模块内部业务逻辑
模块自己的监听器和中间件
页面级表单逻辑这些应该回到:
text
src/modules/*
页面里的 Hook
模块 index.ts