更新时间:2024-06-05 03:14:27下载pdf
本文主要以 basic-ts-0.59 为例介绍了其包含的具体功能及如何使用。如需查看更多资源,请前往 tuya-panel-demo Github 仓库。
说明: 此项目依赖
TYSdk.mobile.mobileInfo.appRnVersion
5.28 以上,如 App 版本过低,请前往 涂鸦面板-RN 重新下载。
├── .babelrc ├── .eslintignore ├── .eslintrc.base.js ├── .eslintrc.js ├── .gitignore ├── .npmrc ├── .prettierignore ├── .prettierrc.js ├── .versionrc ├── CHANGELOG.md ├── README-zh_CN.md ├── README.md ├── index.android.js // 安卓入口 ├── index.ios.js // iOS 入口 ├── index.js // 安卓入口(为了兼容) ├── package.json ├── rn-cli.config.js ├── src │ ├── api // 放置项目中用到的一系列云端 API │ ├── components // 放置项目中用到的复用的功能组件 │ ├── composeLayout.tsx // 封装处理了面板内部所需要的一些`设备事件`和`设备信息` │ ├── config // 放置面板内部一些常用的配置文件 │ ├── i18n // 放置多语言配置文件 │ ├── main.tsx // 项目入口文件,继承自 `NavigatorLayout`,通过重写 `hookRoute` 方法将必要的配置传入,例如背景、topbar 等。重写 `renderScene` 方法控制路由跳转 │ ├── models // 放置 redux 相关的代码 │ ├── pages // 放置项目的各个页面级别的组件 │ ├── res // 放置本地资源,包括图片,svg path 等 │ └── utils // 放置面板内部会用到的常用工具方法等 ├── tsconfig.json // ts 配置文件 └── yarn.lock
放置项目中用到的一系列云端 API。
定义 API
import { TYSdk } from 'tuya-panel-kit';
// tips: TYSdk.apiRequest 提供了泛型支持可使代码更加美观
export const someApiFn = () => {
return TYSdk.apiRequest<any>('tuya.some.api.name', {});
};
使用 API
import * as api from '@api';
api.someApiFn().then(data => console.log(data));
放置项目中用到的复用的功能组件
放置面板内部常用的配置文件
放置多语言配置文件,具体多余的使用方式可参考国际化多语言
放置 redux 相关的代码,内部的 common 模块封装了常用的 state 以及 actions。
dpState:当前设备的 DP 点状态
import { View } from 'react-native';
import { TYText } from 'tuya-panel-kit';
import { useSelector } from '@models';
const SomeFCComponent: React.FC = () => {
const dpState = useSelector(state => state.dpState);
return (
<View>
<TYText text={JSON.stringify(dpState)} />
</View>
);
};
import { View } from 'react-native';
import { useDispatch } from 'react-redux';
import { TYSdk, TYText, Button } from 'tuya-panel-kit';
import { useSelector, actions } from '@models';
const SomeFCComponent: React.FC = () => {
const dispatch = useDispatch();
const handleClick = () => {
dispatch(actions.common.updateDp({ yourDpCode: 'yourDpValue' }));
// 也可以直接通过 TYSdk device 中的方法直接下发
// TYSdk.device.putDeviceData({ yourDpCode: 'yourDpValue' });
};
return (
<View>
<Button text="下发 DP" onPress={handleClick} />
</View>
);
};
devInfo:当前设备的信息
import { View } from 'react-native';
import { TYText } from 'tuya-panel-kit';
import { useSelector } from '@models';
const SomeFCComponent: React.FC = () => {
const devInfo = useSelector(state => state.devInfo);
return (
<View>
<TYText text={JSON.stringify(devInfo)} />
</View>
);
};
logs:DP 点下发上报日志信息,仅该项目需要。
放置项目的各个页面级别的组件,其中在本项目中内置了以下两个页面:
consoleLayout
为 DP 下发和上报的日志输出组件、contentLayout
为 DP 的交互控制下方组件;放置本地资源,包括图片、svg path 等。可以通过 @res
引用其 index.ts 文件。src/res 内置了 read.js 文件可用于快速遍历新增图片文件生成 index.ts 文件导出,具体使用命令可参考下方示例。
$ node src/res/read.js
[ 'button',
'button',
'tuya_decrease',
'tuya_goto_icon',
'tuya_increase',
'tuya_select_icon' ]
const button = require('./button.png');
const tuya_decrease = require('./tuya_decrease.png');
const tuya_goto_icon = require('./tuya_goto_icon.png');
const tuya_increase = require('./tuya_increase.png');
const tuya_select_icon = require('./tuya_select_icon.png');
export default { button, tuya_decrease, tuya_goto_icon, tuya_increase, tuya_select_icon };
放置面板内部的常用工具方法等。
封装处理了面板内部所需要的一些设备事件
和设备信息
。
高阶函数 composeLayout
支持实现以下功能:
composeLayout
处理原始的devInfo
,初始化redux store
。composeLayout
监听设备变更相关的事件,并实时更新相应的redux store
。component
与redux store
关联。import _ from "lodash";
import PropTypes from "prop-types";
import React, { Component } from "react";
import { Provider, connect } from "react-redux";
import { TYSdk, Theme } from "tuya-panel-kit";
import {
devInfoChange,
deviceChange,
responseUpdateDp,
} from "./redux/modules/common";
import theme from "./config/theme";
const TYEvent = TYSdk.event;
const TYDevice = TYSdk.device;
/**
*
* @param {Object} store - redux store
* @param {ReactComponent} component - 需要连接到 redux store 的组件,通常为 main
*/
const composeLayout = (store, component) => {
const NavigatorLayoutContainer = connect(_.identity)(component);
const { dispatch } = store;
/**
* 此处监听了`设备数据变更`事件,
* 每当 DP 点数据变更时,会将变更的 DP 点状态同步更新至 `redux`。
* 同理当设备信息变更时,也会将变更的设备信息值同步更新至 `redux`。
*/
TYEvent.on("deviceDataChange", (data) => {
switch (data.type) {
case "dpData":
dispatch(responseUpdateDp(data.payload));
break;
default:
dispatch(deviceChange(data.payload));
break;
}
});
/**
* 此处监听了`网络状态变更事件`事件,
* 每当设备信息变更时,会将变更的设备信息值同步更新至 `redux`。
*/
TYEvent.on("networkStateChange", (data) => {
dispatch(deviceChange(data));
});
class PanelComponent extends Component {
static propTypes = {
// eslint-disable-next-line
devInfo: PropTypes.object.isRequired,
};
/**
* 如果面板进入时,`devInfo`已经存在(通常存在)
* 这里会调用 setDeviceInfo 将原始的 devInfo 处理一下,并置入`redux`
*
* 如果面板进入时,`devInfo` 不存在,
* 那么调用 getDeviceInfo 异步获取处理完成的 `devInfo`,并置入`redux`
*/
constructor(props) {
super(props);
if (props && props.devInfo && props.devInfo.devId) {
TYDevice.setDeviceInfo(props.devInfo);
TYDevice.getDeviceInfo().then((data) => dispatch(devInfoChange(data)));
// eslint-disable-next-line
} else if (props.preload) {
// do something
} else {
TYDevice.getDeviceInfo().then((data) => dispatch(devInfoChange(data)));
}
}
render() {
return (
<Provider store={store}>
<Theme theme={theme}>
<NavigatorLayoutContainer />
</Theme>
</Provider>
);
}
}
return PanelComponent;
};
export default composeLayout;
MainLayout
入口组件继承NavigatorLayout
,主要帮助面板内部管理多页面。
import React from 'react';
import { StatusBar } from 'react-native';
import { Dispatch } from 'redux';
import {
TYSdk,
NavigatorLayout,
NavigationOptions,
DeprecatedNavigator,
DeprecatedNavigatorRoute,
} from 'tuya-panel-kit';
import composeLayout from './composeLayout';
import { store, ReduxState } from './models';
import Home from './pages/home';
import Setting from './pages/setting';
console.disableYellowBox = true;
type Props = ReduxState & { dispatch: Dispatch };
// 谨慎使用,生成环境上不要开启,console 打印层次过深会导致性能问题
// if (__DEV__) {
// console.log('TYSdk :', TYSdk);
// }
class MainLayout extends NavigatorLayout<Props> {
/**
*
* @desc hookRoute 可以在这里针对特定路由执行控制处理,可控制的参数参考 [NavigationOptions](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/tuya-panel-kit/index.d.ts) 类型描述
*/
hookRoute(route: DeprecatedNavigatorRoute): NavigationOptions {
const routeProps: NavigationOptions = {};
switch (route.id) {
case 'main':
break;
case 'setting':
routeProps.title = 'Setting';
routeProps.background = {
'3%': '#f82232',
'90%': '#FF624C',
};
break;
default:
break;
}
return {
...routeProps,
renderStatusBar: () => <StatusBar barStyle="default" />,
};
}
/**
* @desc
* 在此您可以通过 route 中的 ID 判断使用哪个页面组件
* 如果有额外的 props 需要传递给页面组件的,可以在此进行传递
* 注意:route 参数来自于 TYSdk.Navigator.push
* 如果调用了 TYSdk.Navigator.push({ id: 'setting', title: 'Setting Page' });
* 则会在推入路由栈时 hookRoute 和 renderScene 这个周期里会接受到 route = { id: 'setting', title: 'Setting Page' },
* 但要注意的是,首页的 route 参数是固定的,为 { 'id': 'main', 'initialRoute': true }
*
* @param {Object} route - route对象
* @param {object} navigator - Navigator对象,具体使用方法可参考https://facebook.github.io/react-native/docs/0.43/navigator.html
*/
renderScene(route: DeprecatedNavigatorRoute, navigator: DeprecatedNavigator) {
let component;
switch (route.id) {
case 'main':
component = <Home />;
break;
case 'setting':
component = <Setting />;
break;
default:
break;
}
return component;
}
}
export default composeLayout(store, MainLayout);
该内容对您有帮助吗?
是意见反馈该内容对您有帮助吗?
是意见反馈