@doubao-apps/ai 0.0.20 → 0.0.23

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.
@@ -0,0 +1,208 @@
1
+ # Core API Mapping
2
+
3
+ > **Mapping Version**: 1.0.0
4
+ > **Source Framework**: uni-app `2.0.0` (Vue2 Options API)
5
+ > **Target Framework**: Doubao Apps (React Lynx)
6
+ > **Last Updated**: 2026-04-09
7
+
8
+ ## 官方事实依据
9
+
10
+ - uni-app `2.0.0` 系列历史归档: `https://uniapp.dcloud.net.cn/release-archive.html`
11
+ - 页面与生命周期: `https://uniapp.dcloud.io/tutorial/page.html`
12
+ - `uni.request`: `https://uniapp.dcloud.io/api/request/request.html`
13
+
14
+ ---
15
+
16
+ ## Vue2 状态管理
17
+
18
+ | uni-app 2.0.0 | Doubao Apps | 说明 |
19
+ |--------------|-------------|------|
20
+ | `data() { return { foo: 1 } }` | `const [foo, setFoo] = useState(1)` | 本地状态 |
21
+ | `this.foo = val` / `this.list = [...]` | `setFoo(val)` / `setList(...)` | 响应式更新 |
22
+ | `this.someMethod()` | 组件内普通函数 | 方法定义 |
23
+
24
+ ### 示例
25
+
26
+ ```tsx
27
+ // Before (uni-app 2.0.0)
28
+ export default {
29
+ data() {
30
+ return {
31
+ count: 0,
32
+ keyword: ''
33
+ };
34
+ },
35
+ methods: {
36
+ increment() {
37
+ this.count += 1;
38
+ }
39
+ }
40
+ }
41
+
42
+ // After (Doubao Apps)
43
+ import { definePage, useState } from '@doubao-apps/framework';
44
+
45
+ function PageView() {
46
+ const [count, setCount] = useState(0);
47
+ const [keyword, setKeyword] = useState('');
48
+
49
+ const increment = () => setCount((prev) => prev + 1);
50
+
51
+ return <view />;
52
+ }
53
+
54
+ export default definePage({
55
+ render() {
56
+ return <PageView />;
57
+ }
58
+ });
59
+ ```
60
+
61
+ ---
62
+
63
+ ## `computed`
64
+
65
+ | uni-app 2.0.0 | Doubao Apps | 说明 |
66
+ |--------------|-------------|------|
67
+ | `computed: { doubled() { return this.count * 2; } }` | `useMemo(() => count * 2, [count])` | 派生状态 |
68
+
69
+ ---
70
+
71
+ ## `watch`
72
+
73
+ | uni-app 2.0.0 | Doubao Apps | 说明 |
74
+ |--------------|-------------|------|
75
+ | `watch: { keyword(val) { ... } }` | `useEffect(() => { ... }, [keyword])` | 监听状态变化 |
76
+
77
+ ---
78
+
79
+ ## `props`
80
+
81
+ | uni-app 2.0.0 | Doubao Apps | 说明 |
82
+ |--------------|-------------|------|
83
+ | `props: { title: String }` | `interface Props { title?: string }` | 属性声明 |
84
+ | `this.title` | `props.title` | 访问方式 |
85
+
86
+ ---
87
+
88
+ ## 页面 / 组件 / 应用定义
89
+
90
+ | uni-app 2.0.0 | Doubao Apps | 说明 |
91
+ |--------------|-------------|------|
92
+ | 页面 `.vue` | `definePage({ render })` | 页面入口 |
93
+ | 组件 `.vue` | `FC<Props>` | 普通组件 |
94
+ | `App.vue` + `main.js` | `app.ts` + `defineApp({ ... })` | 应用入口 |
95
+
96
+ ### 页面输入
97
+
98
+ | uni-app 2.0.0 | Doubao Apps | 说明 |
99
+ |--------------|-------------|------|
100
+ | `onLoad(options)` 获取页面参数 | `getViewData()` / `getViewContext()` | 不要假设存在同名 `onLoad` 参数钩子 |
101
+
102
+ ---
103
+
104
+ ## `uni.*` API 映射
105
+
106
+ ### 网络
107
+
108
+ | uni-app 2.0.0 | Doubao Apps | 说明 |
109
+ |--------------|-------------|------|
110
+ | `uni.request({ ... })` | `request({ ... })` | Promise 化网络请求 |
111
+
112
+ ```tsx
113
+ // Before
114
+ uni.request({
115
+ url: '/api/list',
116
+ data: { page: 1 },
117
+ success: (res) => {
118
+ this.list = res.data.list;
119
+ }
120
+ });
121
+
122
+ // After
123
+ import { request } from '@doubao-apps/framework/api';
124
+
125
+ const res = await request({
126
+ url: '/api/list',
127
+ data: { page: 1 }
128
+ });
129
+ setList(res.data.list);
130
+ ```
131
+
132
+ ### 导航
133
+
134
+ | uni-app 2.0.0 | Doubao Apps | 说明 |
135
+ |--------------|-------------|------|
136
+ | `uni.navigateTo({ url })` | `navigateTo({ url })` | 页面跳转 |
137
+ | `uni.redirectTo({ url })` | `redirectTo({ url })` | 替换当前页 |
138
+ | `uni.navigateBack({ delta })` | `navigateBack({ delta })` | 返回 |
139
+ | `uni.reLaunch({ url })` | `reLaunch({ url })` | 重启路由栈 |
140
+ | `uni.switchTab({ url })` | 无已确认公共同名 API | 目标工程需重建 tab 导航能力或记录缺口,不能假设存在 `switchTab` |
141
+
142
+ ### UI 交互
143
+
144
+ | uni-app 2.0.0 | Doubao Apps | 说明 |
145
+ |--------------|-------------|------|
146
+ | `uni.showToast({ title, icon })` | `showToast({ message, icon, type })` | 参数名不同,必须改写 |
147
+ | `uni.showLoading(...)` | 无已确认公共同名 API | 目标侧改为页面内 loading 状态 / 自定义蒙层,或记录缺口 |
148
+ | `uni.hideLoading()` | 无已确认公共同名 API | 与 `showLoading` 配套重写 |
149
+ | `uni.showModal(...)` | 无已确认公共同名 API | 优先用页面内 `Dialog` / `Popup` 组件流重写,不做同名替换 |
150
+
151
+ ### 存储
152
+
153
+ | uni-app 2.0.0 | Doubao Apps | 说明 |
154
+ |--------------|-------------|------|
155
+ | `uni.setStorageSync(key, data)` | `setStorageSync({ key, data })` | 参数形态不同 |
156
+ | `uni.getStorageSync(key)` | `getStorageSync({ key })` | 返回值需读 `.data` |
157
+ | `uni.removeStorageSync(key)` | `removeStorageSync({ key })` | 参数形态不同 |
158
+
159
+ ### 参数改写示例
160
+
161
+ ```tsx
162
+ // Before
163
+ uni.showToast({ title: '保存成功', icon: 'success' });
164
+ uni.setStorageSync('token', token);
165
+ const token = uni.getStorageSync('token');
166
+
167
+ // After
168
+ import { getStorageSync, setStorageSync, showToast } from '@doubao-apps/framework/api';
169
+
170
+ await showToast({
171
+ message: '保存成功',
172
+ icon: 'success',
173
+ type: 'success'
174
+ });
175
+
176
+ setStorageSync({
177
+ key: 'token',
178
+ data: token
179
+ });
180
+
181
+ const storedToken = getStorageSync<string>({
182
+ key: 'token'
183
+ }).data;
184
+ ```
185
+
186
+ ---
187
+
188
+ ## 页面通信
189
+
190
+ `2.0.0` 系列发布记录中可确认 `uni.$on / $once / $off / $emit` 已进入该大版本范围。
191
+
192
+ | uni-app 2.0.0 | Doubao Apps | 说明 |
193
+ |--------------|-------------|------|
194
+ | `uni.$emit('refresh', payload)` | 显式 props / 页面输入 / 状态提升 | 优先去事件总线化 |
195
+ | `uni.$on('refresh', handler)` | 目标侧订阅能力或上层容器协调 | 避免全局事件散落 |
196
+
197
+ ---
198
+
199
+ ## 不要机械迁移的能力
200
+
201
+ - `uni.login`
202
+ - 条件编译中的原生 `wx.*` / `tt.*` / `my.*`
203
+ - `pages.json` 的 tabBar / 原生导航栏 / 下拉刷新配置
204
+ - `uni.switchTab`
205
+ - `uni.showLoading` / `uni.hideLoading` / `uni.showModal`
206
+ - `editor` 组件(需先确认目标等价物)
207
+
208
+ 这些能力需要单列处理,不属于“同名 API 替换”。
@@ -0,0 +1,133 @@
1
+ # Event Mapping
2
+
3
+ > **Mapping Version**: 1.0.0
4
+ > **Source Framework**: uni-app `2.0.0`
5
+ > **Target Framework**: Doubao Apps (React Lynx)
6
+ > **Last Updated**: 2026-04-09
7
+
8
+ ## 最关键的迁移差异
9
+
10
+ | 特性 | uni-app 2.0.0 | Doubao Apps |
11
+ |------|---------------|-------------|
12
+ | 事件绑定 | Vue 模板语法 `@tap="handleTap"` | 函数引用 `onClick={handleTap}` |
13
+ | 参数传递 | `@tap="handleTap(item)"` | `onClick={() => handleTap(item)}` |
14
+ | `v-model` | 双向绑定语法糖 | 显式 `value + onInput/onChange` |
15
+
16
+ ---
17
+
18
+ ## 点击 / 触摸事件
19
+
20
+ | uni-app 2.0.0 | Doubao Apps | 说明 |
21
+ |--------------|-------------|------|
22
+ | `@tap="handleTap"` | `onClick={handleTap}` | 常见点击 |
23
+ | `@click="handleClick"` | `onClick={handleClick}` | Web 风格点击 |
24
+ | `@longpress="handleLongPress"` | `onLongPress={handleLongPress}` | 长按 |
25
+
26
+ ### 示例
27
+
28
+ ```tsx
29
+ // Before
30
+ <view class="card" @tap="handleTap(item)">
31
+ <text>{{ item.title }}</text>
32
+ </view>
33
+
34
+ // After
35
+ <view className="card" onClick={() => handleTap(item)}>
36
+ <text>{item.title}</text>
37
+ </view>
38
+ ```
39
+
40
+ ---
41
+
42
+ ## 表单事件
43
+
44
+ | uni-app 2.0.0 | Doubao Apps | 说明 |
45
+ |--------------|-------------|------|
46
+ | `@input="handleInput"` | `onInput={handleInput}` | 输入 |
47
+ | `@change="handleChange"` | `onChange={handleChange}` 或按组件实际签名处理 | 变更 |
48
+ | `@confirm="handleConfirm"` | `onConfirm={handleConfirm}` | 键盘确认 |
49
+ | `v-model="keyword"` | `value={keyword}` + `onInput` | 受控改写 |
50
+
51
+ ### 示例
52
+
53
+ ```tsx
54
+ // Before
55
+ <input v-model="keyword" @confirm="handleSearch" />
56
+
57
+ // After
58
+ <input
59
+ value={keyword}
60
+ onInput={(e) => setKeyword(e.detail.value)}
61
+ onConfirm={handleSearch}
62
+ />
63
+ ```
64
+
65
+ ---
66
+
67
+ ## 滚动事件
68
+
69
+ | uni-app 2.0.0 | Doubao Apps | 说明 |
70
+ |--------------|-------------|------|
71
+ | `@scroll="handleScroll"` | `onScroll={handleScroll}` | 滚动中 |
72
+ | `@scrolltoupper="handleTop"` | `onScrollToUpper={handleTop}` | 滚动到顶部 |
73
+ | `@scrolltolower="loadMore"` | `onScrollToLower={loadMore}` | 滚动到底部 |
74
+
75
+ ---
76
+
77
+ ## 自定义事件 / `$emit`
78
+
79
+ Vue2 组件内常见:
80
+
81
+ ```js
82
+ this.$emit('change', value);
83
+ ```
84
+
85
+ **迁移**:
86
+
87
+ | uni-app 2.0.0 | Doubao Apps | 说明 |
88
+ |--------------|-------------|------|
89
+ | `this.$emit('change', value)` | `props.onChange?.(value)` | 显式回调 props |
90
+
91
+ ---
92
+
93
+ ## 事件对象
94
+
95
+ uni-app 事件处理器通常接收 `event`:
96
+
97
+ ```js
98
+ methods: {
99
+ handleInput(e) {
100
+ const value = e.detail.value;
101
+ }
102
+ }
103
+ ```
104
+
105
+ 迁移后仍可保留相似的 `e.detail` 读取方式,但要按目标组件真实签名校对:
106
+
107
+ - `input` 常见为 `e.detail.value`
108
+ - `switch` / `slider` 可能直接回调值
109
+ - 不要假设所有组件都传统一事件对象
110
+
111
+ ---
112
+
113
+ ## dataset 改写
114
+
115
+ 源端常见:
116
+
117
+ ```vue
118
+ <view :data-id="item.id" @tap="handleTap"></view>
119
+ ```
120
+
121
+ ```js
122
+ handleTap(e) {
123
+ const id = e.currentTarget.dataset.id;
124
+ }
125
+ ```
126
+
127
+ 迁移建议:
128
+
129
+ ```tsx
130
+ <view onClick={() => handleTap(item.id)}></view>
131
+ ```
132
+
133
+ 优先改为闭包传值,而不是继续依赖 dataset。
@@ -0,0 +1,152 @@
1
+ # Lifecycle Mapping
2
+
3
+ > **Mapping Version**: 1.0.0
4
+ > **Source Framework**: uni-app `2.0.0`
5
+ > **Target Framework**: Doubao Apps (React Lynx)
6
+ > **Last Updated**: 2026-04-09
7
+
8
+ ## 目标框架事实依据
9
+
10
+ 基于当前仓库真实接口:
11
+
12
+ - `packages/framework/src/define-api/types.ts`
13
+ - `packages/framework/src/define-api/define-app.ts`
14
+ - `packages/framework/src/define-api/define-page.ts`
15
+
16
+ 当前可确认的目标页面生命周期:
17
+
18
+ - `onCreated`
19
+ - `onMounted`
20
+ - `onShow`
21
+ - `onHide`
22
+ - `onDestroy`
23
+ - `onError`
24
+
25
+ 当前可确认的目标应用生命周期:
26
+
27
+ - `onLaunch`
28
+ - `onPageOpened`
29
+ - `onForeground`
30
+ - `onBackground`
31
+ - `onDestroy`
32
+ - `onError`
33
+
34
+ ---
35
+
36
+ ## 页面生命周期
37
+
38
+ | uni-app 2.0.0 | Doubao Apps | 迁移建议 |
39
+ |--------------|-------------|----------|
40
+ | `onLoad(options)` | 无同名参数钩子 | 页面输入通过 `getViewData()` / `getViewContext()` 获取;初始化逻辑放 `onMounted` 或 `useEffect` |
41
+ | `onShow()` | `onShow()` | 页面显示 |
42
+ | `onReady()` | `onMounted()` 或 `useEffect(() => {}, [])` | 首次渲染完成 |
43
+ | `onHide()` | `onHide()` | 页面隐藏 |
44
+ | `onUnload()` | `onDestroy()` | 页面销毁 |
45
+ | `onPullDownRefresh()` | 无直接同名钩子 | 结合页面容器 / 刷新组件重写 |
46
+ | `onReachBottom()` | 无直接同名钩子 | 结合 `scroll-view` 触底事件重写 |
47
+ | `onPageScroll(e)` | 无直接同名钩子 | 结合滚动容器事件重写 |
48
+
49
+ ### 示例
50
+
51
+ ```tsx
52
+ // Before (uni-app 2.0.0)
53
+ export default {
54
+ onLoad(options) {
55
+ this.id = options.id;
56
+ this.fetchDetail();
57
+ },
58
+ onShow() {
59
+ console.log('show');
60
+ },
61
+ onUnload() {
62
+ clearInterval(this.timer);
63
+ },
64
+ methods: {
65
+ fetchDetail() {}
66
+ }
67
+ }
68
+
69
+ // After (Doubao Apps)
70
+ import { definePage, getViewData, useEffect } from '@doubao-apps/framework';
71
+
72
+ function DetailPage() {
73
+ const input = getViewData() as { id?: string } | undefined;
74
+
75
+ useEffect(() => {
76
+ if (!input?.id) {
77
+ return;
78
+ }
79
+ // fetchDetail(input.id)
80
+ }, [input?.id]);
81
+
82
+ return <view />;
83
+ }
84
+
85
+ export default definePage({
86
+ onShow() {
87
+ console.log('show');
88
+ },
89
+ onDestroy() {
90
+ // clearInterval(...)
91
+ },
92
+ render() {
93
+ return <DetailPage />;
94
+ }
95
+ });
96
+ ```
97
+
98
+ ---
99
+
100
+ ## 组件生命周期
101
+
102
+ uni-app 组件本质上是 Vue2 组件生命周期:
103
+
104
+ | uni-app 2.0.0 | Doubao Apps | 说明 |
105
+ |--------------|-------------|------|
106
+ | `beforeCreate` | - | 一般无需保留 |
107
+ | `created` | `onCreated` 或组件初始化阶段 | 轻量初始化 |
108
+ | `mounted` | `useEffect(() => {}, [])` / `onMounted` | 挂载后 |
109
+ | `beforeDestroy` / `destroyed` | `useEffect(() => () => {}, [])` | 卸载清理 |
110
+
111
+ ---
112
+
113
+ ## 应用生命周期
114
+
115
+ | uni-app 2.0.0 (`App.vue`) | Doubao Apps (`defineApp`) | 说明 |
116
+ |--------------------------|---------------------------|------|
117
+ | `onLaunch()` | `onLaunch()` | 冷启动 |
118
+ | `onShow()` | `onForeground()` | 进入前台 |
119
+ | `onHide()` | `onBackground()` | 进入后台 |
120
+ | `onError(err)` | `onError(err)` | 错误处理 |
121
+
122
+ ### 示例
123
+
124
+ ```ts
125
+ // After (Doubao Apps)
126
+ import { defineApp } from '@doubao-apps/framework';
127
+
128
+ export default defineApp({
129
+ aiMeta: {
130
+ id: 'app',
131
+ name: 'uniapp-migrated-app'
132
+ },
133
+ onLaunch() {
134
+ console.log('app launched');
135
+ },
136
+ onForeground() {
137
+ console.log('app foreground');
138
+ },
139
+ onBackground() {
140
+ console.log('app background');
141
+ }
142
+ });
143
+ ```
144
+
145
+ ---
146
+
147
+ ## 迁移规则
148
+
149
+ 1. 不要把 uni-app 页面生命周期机械复制为目标框架同名钩子。
150
+ 2. 页面参数读取优先改为 `getViewData()`,不要依赖 `onLoad(options)` 形态继续存在。
151
+ 3. 页面滚动、触底、下拉刷新等能力通常要结合容器级重写。
152
+ 4. `App.vue` 的 `onShow/onHide` 应改为目标应用的前后台生命周期,而不是继续保留原名。
@@ -0,0 +1,139 @@
1
+ # Style Mapping
2
+
3
+ > **Mapping Version**: 1.0.0
4
+ > **Source Framework**: uni-app `2.0.0`
5
+ > **Target Framework**: Doubao Apps (React Lynx)
6
+ > **Last Updated**: 2026-04-09
7
+
8
+ ## 样式系统差异总览
9
+
10
+ | 特性 | uni-app 2.0.0 | Doubao Apps |
11
+ |------|---------------|-------------|
12
+ | 样式位置 | `.vue` 内 `<style>` | 同目录 `index.scss` |
13
+ | 类名属性 | `class="xxx"` | `className="xxx"` |
14
+ | 内联样式 | `:style="..."` / `style="..."` | `style={{...}}` 或收敛到 `index.scss` |
15
+ | 常见单位 | `rpx`, `px`, `%` | 保留原有语义并按目标样式能力校对 |
16
+ | scoped 样式 | `scoped` attribute | 用局部 class 组织代替自动 scope 注入 |
17
+
18
+ ---
19
+
20
+ ## 基本规则
21
+
22
+ ### 文件与导入
23
+
24
+ ```tsx
25
+ import './index.scss';
26
+ ```
27
+
28
+ ### 类名迁移
29
+
30
+ ```tsx
31
+ // Before
32
+ <view class="card active"></view>
33
+
34
+ // After
35
+ <view className="card active"></view>
36
+ ```
37
+
38
+ ### 内联样式迁移
39
+
40
+ ```tsx
41
+ // Before
42
+ <view :style="{ padding: padding + 'rpx' }"></view>
43
+
44
+ // After
45
+ <view style={{ padding: `${padding}rpx` }}></view>
46
+ ```
47
+
48
+ **优先级**:
49
+
50
+ 1. 静态样式放 `index.scss`
51
+ 2. 只有动态值才放 `style={{}}`
52
+
53
+ ---
54
+
55
+ ## `<style>` → `index.scss`
56
+
57
+ ### 示例
58
+
59
+ ```vue
60
+ <!-- Before -->
61
+ <style scoped lang="scss">
62
+ .page {
63
+ padding: 24rpx;
64
+ }
65
+
66
+ .card {
67
+ background: #fff;
68
+ border-radius: 16rpx;
69
+ }
70
+ </style>
71
+ ```
72
+
73
+ ```scss
74
+ /* After (index.scss) */
75
+ .page {
76
+ padding: 24rpx;
77
+ }
78
+
79
+ .card {
80
+ background: #fff;
81
+ border-radius: 16rpx;
82
+ }
83
+ ```
84
+
85
+ ---
86
+
87
+ ## 动态 class
88
+
89
+ ```tsx
90
+ // Before
91
+ <view :class="['item', { 'item--active': active }]"></view>
92
+
93
+ // After
94
+ <view className={active ? 'item item--active' : 'item'}></view>
95
+ ```
96
+
97
+ ---
98
+
99
+ ## `scoped` 样式
100
+
101
+ uni-app `scoped` 依赖编译器自动加作用域标记。迁移到 Doubao 时:
102
+
103
+ - 通过更稳定的局部 class 命名保持样式隔离
104
+ - 避免依赖深层级或编译器生成的 attribute 选择器
105
+ - 若源样式大量依赖 `scoped` 深穿透,需手工整理
106
+
107
+ ---
108
+
109
+ ## 常见单位处理
110
+
111
+ - `rpx`:优先原样保留
112
+ - `px`:原样保留并在视觉验证时校准
113
+ - `%`:原样保留
114
+ - 视口单位、复杂 `calc()`:按目标样式能力逐项核对
115
+
116
+ ---
117
+
118
+ ## 全局样式与 `pages.json`
119
+
120
+ uni-app 项目常有:
121
+
122
+ - `App.vue` 全局样式
123
+ - `uni.scss`
124
+ - `pages.json -> globalStyle`
125
+
126
+ 迁移建议:
127
+
128
+ - 页面局部样式放各自 `index.scss`
129
+ - 全局基础样式放目标工程可控的全局入口
130
+ - `pages.json` 的视觉配置(导航栏、背景色、下拉刷新)按目标工程重建,不要当普通 CSS 复制
131
+
132
+ ---
133
+
134
+ ## 样式迁移禁忌
135
+
136
+ - 不要把所有 `<style>` 内容硬改成超长内联对象
137
+ - 不要丢失 class 语义
138
+ - 不要默认 `scoped` 深层选择器在目标侧还能成立
139
+ - 不要无脑改写 `rpx` 单位