该插件目录中的home页面顶部有两个按钮(设备、菜谱),请帮我梳理并跟踪:在代码逻辑上,从调起插件开始是怎么跳转到菜谱页面的
1. 插件入口
index.js 用 MIOT 的 Package.entry 指定根组件为 Root:
/**
* 指定插件入口
*/
Package.entry(Root, () => { console.log('root loaded') })
2. Root → 主界面栈
root.js 用 StateContextProvider 包住 App(即 main/page/index.js 导出的带导航的应用):
return (
<SafeAreaProvider>
<StateContextProvider>
<View style={{ flex: 1 }}>
<MenuProvider
...
>
<App />
</MenuProvider>
</View>
</StateContextProvider>
</SafeAreaProvider>
3. 导航栈:首屏是 Home
main/page/index.js 里用 createStackNavigator,initialRouteName 为 'Home'(约 301 行附近)。「菜谱」并不是单独一个 Stack 路由,而是和「设备」同屏、通过横向分页切换。
Home 的 headerTitle 被设成自定义的 TopTabbar,也就是顶部的「设备 / 菜谱」两个按钮:
const Nav = createStackNavigator({
Home: {
screen: Home,
navigationOptions: ({ navigation }) => ({
headerTitle: <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<TopTabbar navigation={navigation} />
</View>,
4. 顶部 Tab:点击「菜谱」时改 MobX 状态
TopTabbar 里维护 tabList:0 = 设备,1 = 菜谱。点击某个 Tab 时调用 componentState.setTopTabberIndex(index):
const TopTabbar = observer(() => {
const componentState = useComponentState()
const deviceState = useDeviceState()
const { topTabberIndex } = componentState
...
const tabList = [
{ name: '设备', },
{ name: '菜谱', disabled: [400, 5, 6].includes(deviceState.deviceStatus) },
]
...
const onPress = (tab, index) => {
componentState.setTopTabberIndex(index)
}
topTabberIndex 定义在 createComponentStore 里,默认 0(设备):
function createComponentStore(defaultValue = {}) {
return makeAutoObservable({
//头部选项组件序号控制
topTabberIndex: 0,
...
setTopTabberIndex(value) {
this.topTabberIndex = value
},
5. Home 主体:横向 ScrollView 切到第二页 = 菜谱 UI
Home/index.js 里 ScrollViewWithTopTabber 是一个横向、分页、且 scrollEnabled={false} 的 ScrollView,内部两个等宽页面:
-
第 0 页:
PageSwitcher(按设备状态显示DeviceController/WorkingStatus等)+Sider -
第 1 页:
CookMenu(菜谱页内容)
const ScrollViewWithTopTabber = observer(({ navigation }) => {
const componentState = useComponentState()
const scrollRef = useRef(null)
useEffect(() => {
scrollRef.current.scrollTo({ x: componentState.topTabberIndex * UIConfig.width, animated: true })
}, [componentState.topTabberIndex])
return (
<ScrollView
ref={scrollRef}
...
scrollEnabled={false}
...
>
<View style={{ height: '100%', width: UIConfig.width }}>
<PageSwitcher navigation={navigation} />
<Sider />
</View>
<View style={{ height: '100%', width: UIConfig.width }}>
<CookMenu navigation={navigation} />
</View>
</ScrollView>
)
})
当 topTabberIndex 变为 1 时,useEffect 执行 scrollTo({ x: UIConfig.width }),视觉上滑到第二页,即 CookMenu。
6. 菜谱页本身:CookMenu.js
第二页渲染的 CookMenu 负责菜谱列表、分类、搜索栏(可 navigate('SearchPage'))等:
const CookMenu = ({ navigation }) => {
console.log('home')
const tagList = useCategory.useCategoryList()
...
return (
<View style={{ flex: 1, height: '100%' }}>
<View style={{ paddingHorizontal: UIConfig.rpxToPx(20) }}>
<SearchBar />
流程小结(逻辑链)
| 步骤 | 位置 | 行为 |
|---|---|---|
| 1 | index.js |
Package.entry(Root) 启动插件 |
| 2 | root.js |
App(main/page/index.js)挂载 |
| 3 | main/page/index.js |
StackNavigator 打开 Home,标题栏为 TopTabbar
|
| 4 | 用户点「菜谱」 |
TopTabbar → setTopTabberIndex(1)
|
| 5 | Home/index.js |
topTabberIndex === 1 → ScrollView scrollTo 到第二页 |
| 6 | 第二页 | 渲染 CookMenu,即菜谱界面 |
要点:这里没有 navigation.navigate('CookMenu') 之类的路由跳转;「设备 / 菜谱」是同一 Home 路由下的双栏分页,靠 componentState.topTabberIndex + 横向 ScrollView.scrollTo 切换。若设备状态为 400/5/6,「菜谱」Tab 会 disabled,无法点到索引 1。