面板是 IoT 智能设备在 App 终端上的产品形态。创建产品之前,首先来了解一下什么是面板,以及面板和产品、设备之间的关系。

1.1 面板是什么?

  1. 面板是运行在 智能生活 App、OEM App(涂鸦定制 App)上的界面交互程序,用于控制智能设备的运行,展示智能设备实时状态。
  2. 产品将面板与智能设备联系起来,产品描述了其具备的功能、在 App 上面板显示的名称、智能设备拥有的功能点等。
  3. 智能设备是搭载了涂鸦智能模组的设备,通常在设备上都会贴有一张二维码。使用 智能生活 App 扫描二维码,即可在 App 中获取并安装该设备的控制面板。

1.2 产品、面板、设备关系

下图描述了产品、面板和设备三者之间的关系:

1.3 创建产品

由于产品定义了面板和设备所拥有的功能点,所以在开发一个智能设备面板之前,首先需要创建一个产品,定义产品有哪些功能点,然后再在面板中一一实现这些功能点。

注册登录 涂鸦开发者平台,并在平台创建产品:

  1. 单击页面左侧 产品 > 产品开发,在 产品开发 页面单击 创建产品
  2. 以大家电为例,在 标准类目 下选择 大家电,产品品类选择 空调
  3. 选择智能化方式和产品方案,并完善产品信息,在产品名称 处填写 万能面板,其余选项保持默认即可。

  1. 单击 创建产品 按钮,完成产品创建。

产品创建完成后,进入到 添加标准功能 页面,这里列出了空调类目下可选的标准功能。单击 全部选择,然后单击 确定 完成产品初始功能点设置。

在完成产品创建和功能设置后,就可以开始 面板小程序 的开发流程。请先前往 涂鸦小程序开发者平台 完成平台的注册登录。

单击 新建,然后在 小程序信息 页,填写 小程序名称万能面板小程序类型 选择 面板小程序,然后单击 确定 完成创建。

安装并打开小程序 IDE 工具(前往下载小程序 IDE),使用涂鸦开发者平台账号登录 IDE。

4.1 创建项目代码

  1. 单击 新建,在创建智能小程序页面配置以下信息:
    • 项目路径:保持默认即可。
    • 项目名称:填写 万能面板
    • 关联智能小程序:选择第 3 步在小程序平台创建的面板小程序。
    • 调试产品:选择第 1 步在开发者平台创建的产品。
    完成后,单击 下一步
  2. 选择模板 页面,选择 面板 SDM 通用模板 并单击 创建,生成 Ray 面板项目(Ray 类似 Taro,是一个多端研发框架,编写一套代码编译到多端)。

4.2 启动项目

  1. 进入项目后,单击账户图标,出现二维码后,使用 智能生活 App 扫描二维码授权登录。
  2. App 授权登陆后,单击设备工具图标,然后单击右上角 添加虚拟设备
  3. 使用 智能生活 App 扫描虚拟设备二维码。
  4. 扫描后,项目会重新编译加载,获取到设备信息并加载渲染面板。涂鸦小程序 IDE 工具导入小程序后会自动安装依赖,并实时编译运行。

如果出现 Error(MiniKit 不存在指定的版本 2.3.3) 类似的错误提示,单击 环境配置 > Kit 管理,选择推荐的版本即可。

面板小程序的开发主要围绕开发者平台、小程序开发平台、小程序 IDE 之间进行,整体流程参考下图:

前面的步骤结束后,一个面板小程序的创建流程即完成,接下来进入到实际代码的开发教程。

6.1 代码目录结构

首先了解项目的目录结构,单击工具栏在 Visual Studio Code 中打开项目代码。

如果提示没有 code 命令,需要在 Visual Studio Code 帮助中选择 显示所有命令,搜索 code 安装即可,可参考 Visual Studio Code 官方文档 操作。

然后在 Visual Studio Code 中可以看到项目代码的文件目录结构。

6.2 配置页面路由

编写代码主要在 pages 文件夹中进行。创建你的页面代码,然后将路由地址配置到 src/routes.config.ts 文件中。

关于其他文件的说明,会在下文开发步骤的介绍中提及。

7.1 使用 SDM 智能设备模型状态管理读取设备数据

关于 SDM 智能设备模型文档,请查看 SDM 智能设备模型参考文档

  1. 在 IDE 中单击设备工具插件中的 智能设备模型,然后单击 注入数据到当前项目
  2. 在 IDE 中单击 在 VS Code 打开 按钮,打开 Visual Studio Code 编辑器。
  3. 打开 src/devices/schema.ts 文件,在生成的 Schema 列表后设置 as const,以便于类型提示,并在 src/devices/index.ts 中使用 deviceSchema 类型。
  4. src/devices/index 中你可以看到 SDM 的初始化逻辑,简化一下就是:
    // 创建 SDM 智能设备模型
    const value = new SmartDeviceModel({ deviceId });
    
    value.init(); // 执行初始化
    
    // 初始化完成事件
    value.onInitialized(() => {
        ��始化完成后可以进行设备信息获取和操作
        �� value.getDpSchema()
        ...
    });
    
    ``
  5. src/app.tsx 应用根组件设置如下,使用 SdmProvider 将智能设备模型实例放在 Context 中:

import React, { Component } from ‘react' import { SdmProvider } from "@ray-js/panel-sdk"; import { devices } from ‘@/devices'; import { initPanelEnvironment } from "@ray-js/ray";

initPanelEnvironment({ useDefaultOffline: true });

class App extends Component {
	render() {
        return <SdmProvider value={devices.common}>{this.props.children}</SdmProvider>
	}
}
```
  1. 修改 src/pages/home/index.tsx 文件,输入以下代码:
    import React from "react";
    
    import { useDpSchema, useProps } from "@ray-js/panel-sdk";
    import { View } from "@ray-js/ray";
    
    export default () => {
    // 项目启动时,会自动拉取开发者平台 productId 对应的产品 schema 信息
    const dpSchema = useDpSchema();
    
    // 从设备模型中读取 dpState 数据
    const dpState = useProps(state => state); // 获取所有 dpState
    const switch = useProps(state => state.switch); // 获取 dpCode 为 switch 的值
    
    console.log("dpSchema", dpSchema); // 打印查看 dpSchema 内容
    console.log("dpState", dpState); // 打印查看 dpState 内容
    
    return <View>hello world</View>;
    };
    
    ``注意 useProps 使用时,建议精确到读取哪个 DP,例如精确到读取 switch state => state.switch,只有当 switch 变化时组件才会重新渲染。

7.2 IDE 调试器 Console 打印日志

查看 IDE 调试 Console,可以看到打印出 devInfo 内容。

代码中获取 devInfo:

import { useDevInfo } from "@ray-js/panel-sdk";

const devInfo = useDevInfo();
console.log("devInfo:", devInfo);

7.3 devInfo 字段说明

在 IDE 调试器 Console 面板中默认可以看到有很多输出,其中最重要的就是 devInfo ,即设备信息(Device Information)。

需要了解 devInfo 中几个重要的属性:

通常代码中获取 devInfo 是通过 useDevInfo API 来读取。(本文中的 DP 即 "功能点",来自开发者平台功能定义。)

7.4 获取产品功能定义(Schema)

使用 useDpSchema 可以获取到产品的功能定义

import { useDpSchema, useProps } from "@ray-js/panel-sdk";

const dpSchema = useDpSchema(); // 功能点定义
const dpState = useProps((state) => state); // 设备功能点状态

遍历 Schema 可以获取到产品所有的 DP 功能点及属性:

schema.map((item) => {
	// item.code
	// item.property
	// ...
	return <Text>{item.name}</Text>;
});

这里根据 item.property.type 可以判断并渲染不同类型 DP 功能点的 UI 展示。

8.1 使用 rpx 单位

Ray 开发样式使用 Less 语言,支持 CSS Module,新建文件 index.module.less,编写内容例如:src/pages/home/index.module.less

.container {
	border-radius: 24rpx;
	background-color: #fff;
	margin-bottom: 24rpx;
}

rpx 单位是 Ray 框架提供的特有单位,能够做到不同设备上的自适应。

8.2 使用 CSS Module 方式添加样式

在代码中使用样式:

import React from "react";

import { useDpSchema } from "@ray-js/panel-sdk";
import { View } from "@ray-js/components";
import styles from "./index.module.less"; // 注意样式引入方式

export default () => {
	const dpSchema = useDpSchema();

	// 添加 className
	return <View className={styles.container}>hello world</View>;
};

9.1 功能定义 Schema 的结构

通过 Console 日志可以了解到 Schema 的数据结构:

详细请参考文档 自定义功能

9.2 渲染 Schema 数据展示

src/home/index.tsx 编写输入以下代码:

import React from "react";

import { useDevInfo, useDpSchema, useProps } from "@ray-js/panel-sdk";
import { View } from "@ray-js/components";

export default () => {
	const dpSchema = useDpSchema();
	const dpState = useProps((state) => state);

	console.log("dpSchema", dpSchema);
	console.log("dpState", dpState);

	return (
		<View>
			{Object.keys(dpSchema || {}).map((dpCode) => {
				// 遍历渲染每个功能点
				return (
					<View key={dpCode}>
						{dpCode}: {dpState[dpCode]}
					</View>
				);
			})}
		</View>
	);
};

重新编译,可以看到 IDE 左边面板中显示了所有 DP 的 Code 及对应设备状态 :

10.1 Bool 功能点数据结构

在 IDE Console 面板中,可以看到 Bool 类型功能点的数据结构,例如:

{
	dptype: "obj";
	id: "39";
	type: "bool";
}

10.2 安装扩展组件库

使用工具包 @ray-js/components-ty 提供的开关组件 TySwitch 来渲染,执行以下命令,安装 Ray 提供的扩展组件库:

yarn add @ray-js/components-ty

10.3 使用开关组件 TySwitch

继续编写代码,输入以下内容:

因为是 Bool 类型 DP,所以在 actions 中有 toggle 方法,调用时会使 DP 值在 truefalse 之间切换。

import React from "react";

import { useDpSchema } from "@ray-js/panel-sdk";
import { TySwitch } from "@ray-js/components-ty";
import { View } from "@ray-js/components";

const BoolCard = ({ dpCode }) => {
	const dpValue = useProps((state) => state[dpCode]);
	const actions = useActions();
	return (
		<View>
			{dpCode}:{" "}
			<TySwitch
				checked={dpValue}
				onChange={() => {
					actions[dpCode].toggle();
				}}
			/>
		</View>
	);
};

export default () => {
	const dpSchema = useDpSchema();
	const dpState = useProps((state) => state);

	console.log("dpSchema", dpSchema);

	return (
		<View>
			{Object.keys(dpSchema || {}).map((dpCode) => {
				const props = dpSchema[dpCode];
				// 判断如果是 bool 类型,返回 TySwitch
				if (props.type === "bool") {
					return <BoolCard dpCode={dpCode} />;
				}
				return (
					<View key={dpCode}>
						{dpCode}: {dpState[dpCode]}
					</View>
				);
			})}
		</View>
	);
};

编译后,IDE 中渲染界面如下图所示,能看到所有的 Bool 型 DP 已经成功渲染出了开关组件

10.4 功能点多语言获取

DP 在功能定义时,在产品信息中已经有相应的多语言文本,这里使用 src/i18n 下的 Strings 工具获取 DP 文本,输入以下代码:

import React from "react";

import { useDpSchema, useProps } from "@ray-js/panel-sdk";
import { TySwitch } from "@ray-js/components-ty";
import { View } from "@ray-js/components";
import Strings from "@/i18n";

export default () => {
	const dpSchema = useDpSchema();
	const dpState = useProps((state) => state);

	console.log("dpSchema", dpSchema);

	return (
		<View>
			{Object.keys(dpSchema || {}).map((dpCode) => {
				const props = dpSchema[dpCode];
				if (props.type === "bool") {
					// 使用 Strings.getDpLang 方法获取多语言
					return (
						<View>
							{Strings.getDpLang(dpCode)}:{" "}
							<TySwitch checked={dpState[dpCode]} />
						</View>
					);
				}
				return (
					<View key={dpCode}>
						{dpCode}: {dpState[dpCode]}
					</View>
				);
			})}
		</View>
	);
};

再次编译查看 IDE 渲染结果,可以看到所有的 Bool 类型 DP 文本都已显示出中文:

此时 Bool 类型 DP 功能点的 UI 渲染已完成。

11.1 使用下发 DP 功能点 API

上文介绍了如何编写代码渲染 DP 点,但是要控制设备运行,还需要进行 DP 下,使用 SDM 智能设备模型 提供的 Hooks useActions 下发能力,例如:

import { useActions } from "@ray-js/panel-sdk";

const actions = useActions();

// 下发给对应设备,actions.xxx 中的 xxx 是 dpCode,set 是下发指令的方法,传入 dpValue 调用即可下发指令
actions.switch.set(true); // 下发 switch 为 true
actions.switch.on(); // 打开当前布尔类型功能点
actions.switch.off(); // 关闭当前布尔类型功能点
actions.switch.toggle(); // 在 true 和 false 之间切换 bool 值

11.2 下发 Bool 开关功能点

现在来示例开关功能点的 DP 下发 操作的代码编写。

首先实现 Bool 下发上报组件:

import React from "react";

import { useActions, useProps } from "@ray-js/panel-sdk";
import { View } from "@ray-js/components";

const BoolCard = ({ dpCode }) => {
	const actions = useActions();
	const dpValue = useProps((state) => state[dpCode]);
	return (
		<View>
			{dpCode}:{" "}
			<TySwitch checked={dpValue} onChange={() => actions[dpCode].toggle()} />
		</View>
	);
};

对于 Bool 类型的 DP 功能点,以 switch 开关 DP 点的 actions 为例,actions.xxx 会有以下几个工具方法:

actions.switch.on; // switch 功能点下发 true
actions.switch.off; // switch 功能点下发 false
actions.switch.toggle; // switch 功能点 true/false 切换下发
export default () => {
	const schema = useDpSchema();
	const dpState = useProps((state) => state);
	const actions = useActions();

	return (
		<View>
			{Object.keys(schema || {}).map((dpCode) => {
				const props = schema[dpCode];
				// 判断如果是 bool 类型,返回 TySwitch
				if (props.type === "bool") {
					return <BoolCard key={dpCode} dpCode={dpCode} />;
				}
				return (
					<View key={dpCode}>
						{dpCode}: {dpState[dpCode]}
					</View>
				);
			})}
		</View>
	);
};

11.3 虚拟设备插件调试

IDE 编译后运行,使用虚拟设备插件进行调试。在调试器 Virtual Device 面板中,选择 可视化面板,单击调试器中的开关,可以看到左边模拟器中的开关收到了 DP 上报,并做出了相同的切换动作。

12.1 Enum 功能点数据结构

Enum 类型 DP 点的 Schema 属性配置如下:

{
	dptype: "obj";
	id: "20";
	range: ["cancel", "1h", "2h", "3h", "4h", "5h", "6h"];
	type: "enum";
}

12.2 使用弹窗组件 TyActionsheet 和列表组件 TyCell

range 中的即枚举条目,使用 @ray-js/components-ty 中的 ActionSheet 弹窗组件 + Cell 列表组件 进行渲染,编写以下代码。

首先实现 Enum 枚举展示控制组件:

import React from "react";

import { useActions, useProps } from "@ray-js/panel-sdk";
import { View } from "@ray-js/components";
import Strings from "@/i18n";

const EnumCard = ({ dpCode }) => {
	const actions = useActions();
	const dpValue = useProps((state) => state[dpCode]);

	const [showEnumDp, setShowEnumDp] = useState(null);

	return (
		<View>
			{Strings.getDpLang(dpCode)}:
			<Button onClick={() => setShowEnumDp(dpCode)}>
				{Strings.getDpLang(dpCode, dpState[dpCode])}
			</Button>
			<TyActionsheet
				header={Strings.getDpLang(dpCode)}
				show={showEnumDp === dpCode}
				onCancel={() => setShowEnumDp(null)}
			>
				<View style={{ overflow: "auto", height: "200rpx" }}>
					<TyCell.Row
						rowKey="title"
						dataSource={props.range.map((item) => ({
							title: Strings.getDpLang(dpCode, item),
							onClick: () => {
								actions[dpCode].set(item);
							},
						}))}
					/>
				</View>
			</TyActionsheet>
		</View>
	);
};

对于 Enum 类型的 DP 功能点,以 work_mode 工作模式 DP 点的 actions 为例,actions.xxx 会有以下几个工具方法:

actions.work_mode.set("white"); // work_mode 下发 white
actions.work_mode.next(); // 切换下一个枚举
actions.work_mode.prev(); // 切换上一个枚举
actions.work_mode.random(); // 切换到随机一个枚举值

遍历 Schema 渲染:

import React, { useState } from "react";

import { useDpSchema, useProps } from "@ray-js/panel-sdk";
import { TyActionsheet, TyCell, TySwitch } from "@ray-js/components-ty";
import { Button, ScrollView, View } from "@ray-js/components";
import Strings from "@/i18n";

export default () => {
	const schema = useDpSchema();
	const dpState = useProps((state) => state);

	console.log("schema", schema);

	const [showEnumDp, setShowEnumDp] = useState(null);

	return (
		<View>
			{Object.keys(schema).map((dpCode) => {
				const props = schema[dpCode];
				// 这里为了文章篇幅,忽略其他类型的。本地代码可复制上节 bool 类型的到这里
				if (props.type === "enum") {
					return <EnumCard key={dpCode} dpCode={dpCode} />;
				}
				return (
					<View key={dpCode}>
						{dpCode}: {dpState[dpCode]}
					</View>
				);
			})}
		</View>
	);
};

单击按钮,触发 ActionSheet 弹窗,弹窗中使用 Cell 列表组件 渲染多个枚举项,效果如下:

13.1 String 功能点数据结构

String 类型 DP 点的 Schema 属性配置如下:

{
	dptype: "obj";
	id: "20";
	type: "string";
}

13.2 使用输入组件 Input

首先实现 Input 输入组件:

import React from "react";

import { useActions, useProps } from "@ray-js/panel-sdk";
import { Input } from "@ray-js/components";
import Strings from "@/i18n";

const InputCard = ({ dpCode }) => {
	const actions = useActions();
	const dpValue = useProps((state) => state[dpCode]);

	const [showEnumDp, setShowEnumDp] = useState(null);

	return (
		<Input
			value={dpState[dpCode]}
			onInput={(event) => {
				actions[dpCode].set(event.detail.value);
			}}
		/>
	);
};

对于 String 类型的 DP 功能点,以 name 名称 DP 点的 actions 为例,actions.xxx 会有以下几个工具方法:

actions.name.set("my device"); // name 下发 my device

遍历 Schema 渲染:

import { useDpSchema, useActions } from "@ray-js/panel-sdk";
import { Input } from "@ray-js/components";

export default () => {
	const schema = useDpSchema();
	const dpState = useProps((state) => state);

	console.log("schema", schema);

	return (
		<View>
			{Object.keys(schema || {}).map((dpCode) => {
				const props = schema[dpCode];
				// 这里为了文章篇幅,忽略其他类型的。本地代码可复制上节类型的到这里
				if (props.type === "string") {
					return <InputCard value={dpState[dpCode]} />;
				}
				return (
					<View key={dpCode}>
						{dpCode}: {dpState[dpCode]}
					</View>
				);
			})}
		</View>
	);
};

Raw 类型 DP 一般不做渲染,如果需要可以按照 String 类型进行处理。

14.1 Value 功能点数据结构

Value 类型 DP 点的 Schema 属性配置如下:

{
	dptype: "obj";
	id: "18";
	max: 100;
	min: 0;
	scale: 0;
	step: 1;
	type: "value";
	unit: "%";
}

14.2 使用滑动条组件 Slider

首先实现 Slider 输入组件。

其中定义了数值范围和单位,使用 Slider 组件进行渲染:

import React from "react";

import { useActions, useProps } from "@ray-js/panel-sdk";
import { Slider } from "@ray-js/components";
import Strings from "@/i18n";

const ValueCard = ({ dpCode }) => {
	const actions = useActions();
	const dpValue = useProps((state) => state[dpCode]);

	return (
		<View>
			{Strings.getDpLang(dpCode)}:
			<Slider
				step={props?.step}
				max={props?.max}
				min={props?.min}
				value={dpState[dpCode]}
				onChange={(event) => {
					actions[dpCode].set();
				}}
			/>
		</View>
	);
};

对于 Value 类型的 DP 功能点,以 add_ele 用电量 DP 点的 actions 为例,actions.xxx 会有以下几个工具方法:

actions.add_ele.set(1000); // add_ele 下发 1000
actions.add_ele.inc(); // 根据当前功能点步长 step 进行递增
actions.add_ele.dec(); // 根据当前功能点步长 step 进行递减

遍历 Schema 渲染:

import { useDpSchema, useActions, useProps } from "@ray-js/panel-sdk";
import { Slider } from "@ray-js/components";

export default () => {
	const schema = useDpSchema();
	const dpState = useProps((state) => state);

	console.log("schema", schema);

	return (
		<View>
			{Object.keys(schema).map((dpCode) => {
				const props = schema[dpCode];
				// 这里为了文章篇幅,忽略其他类型的。本地代码可复制上节类型的到这里
				if (props.type === "value") {
					return <ValueCard dpCode={dpCode} />;
				}
				return (
					<View key={dpCode}>
						{dpCode}: {dpState[dpCode]}
					</View>
				);
			})}
		</View>
	);
};

Slider 组件是一个滑动条组件,可以根据数值范围进行约束,IDE 渲染如下,所有 Value 类型 DP 都渲染出了滑动条。

15.1 Bitmap 功能点数据结构

Bitmap 类型一般用作故障上报,属性配置如下:

{
	dptype: "obj";
	id: "22";
	label: ["sensor_fault", "temp_fault"];
	maxlen: 2;
	type: "bitmap";
}

15.2 使用消息提醒组件 Notification

故障型 DP 使用弹窗渲染,这里使用 @ray-js/ray-components-plus 提供的 Notification 来实现:

import { useDpSchema, useActions, useProps } from "@ray-js/panel-sdk";
import { Notification } from "@ray-js/ray-components-plus";

export default () => {
	const schema = useDpSchema();
	const dpState = useProps((state) => state);

	console.log("schema", schema);

	// 弹窗消息在 useEffect 中进行
	useEffect(() => {
		Object.keys(schema).forEach((dpCode) => {
			const props = schema[dpCode];
			if (props.type === "bitmap") {
				Notification.show({
					message: Strings.getFaultStrings(dpCode, dpState[dpCode]),
					icon: "warning",
				});
			}
		});
	}, [schema, dpState]);

	return (
		<View>
			{Object.keys(schema).map((dpCode) => {
				const props = schema[dpCode];
				// 这里为了文章篇幅,忽略其他类型的。本地代码可复制上节类型的到这里
				return (
					<View key={dpCode}>
						{dpCode}: {dpState[dpCode]}
					</View>
				);
			})}
		</View>
	);
};

Bitmap 类型通常用来做故障上报,以弹窗消息提示,所以需要在 useEffect 中遍历 Schema 找到 Bitmap 类型并弹窗提醒。

16.1 开发者平台添加自定义功能点

以上 Schema 中是家电类目自带的标准 DP 点,还可以增加自定义的 DP。在开发者平台,进入到产品的开发页面 > 功能定义 > 自定义功能 区域,单击 添加功能

16.2 自定义功能点属性配置

新建一个 Bool 型 DP:

16.3 IDE 刷新拉取自定义功能点配置

然后回到 IDE 中,点击 编译 按钮刷新面板,可以看到渲染出了新增加的一个 DP 点:

17.1 虚拟设备解决什么问题?

面板运行时需要获取 设备信息 来显示 设备的运行状态。在开发阶段,如果没有真实的 智能硬件设备,可以借助 虚拟设备 来辅助调试,可以达到和真实设备一样的效果。虚拟设备和真实设备对于面板小程序来说可以是等效的,其关系如下图所示:

17.2 授权 IDE 登录

在使用虚拟设备前,请先确认已授权登录态,单击右上角登录,使用 智能生活 App 扫描二维码授权登录。

17.3 App 扫码创建虚拟设备

登录后进入 万能面板 项目,单击调试工具 Virtual Device,使用 智能生活 App 扫码创建虚拟设备。

17.4 操作指南

虚拟设备面板中分为 3 个区域。如下图,左侧是兜底面板,用于展示当前产品的 DP 功能点;中间是虚拟设备 DP 控制列表,可以改变 DP 状态并单击 上报 按钮来上报;右侧下方是 Log 面板,用于输出 MQTT 日志。单击 可视化面板,切换到兜底面板视图,它与控制面板功能相同,更加直观的展现产品功能点。

17.5 调试代码

下面来调试刚刚编写的代码,参考下图:

18.1 获取虚拟设备 ID

在虚拟设备界面的右侧,单击 设备信息,然后在 deviceId 处复制下设备 ID。

18.2 设置真机调试参数

单击 编译参数设置,按照格式填入真机调试参数。 例如:deviceId=vdevo165398364416684

18.3 App 扫码打开调试器

设置编译参数后,单击 真机调试 按钮(真机需要前往 智能生活 App 下载)。

使用 智能生活 App 扫描二维码,打开并进入小程序面板,可以在真机上进行调试万能面板。

到此你已经熟悉了 6 种 DP 点的渲染及下发,此处附上万能面板代码开源地址:panel-universal

经过样式优化后的万能面板展示如下:

20.1 上传源码包

在 IDE 中完成调试后,单击 上传源码 按钮,输入版本号及说明,单击 上传 上传预览包。

上传完成后,在小程序开发者平台版本管理中,可以看到已经上传的版本列表。

20.2 添加预览包白名单

  1. 在上传完成源码包后,在 小程序开发者平台 > 版本管理 中,选择需要预发布的版本,设为体验版。
  2. 单击 白名单,添加你的 智能生活 App 的账号。
  3. 添加完成后,可以单击 版本管理 > 体验版二维码 查看小程序码,并使用 智能生活 App 扫码预览小程序。

20.3 审核上线

非官方主体的面板小程序,在提交审核前,需要完善开发者平台展示信息。其余审核上线注意项可参考 上线审核