主题
Skip to content
微信小游戏排行榜指南
本功能基于微信关系链数据和开放数据域实现。接入前需要同时完成微信后台权限声明、主域通信和开放数据域渲染。
发布后台配置
发布同学需要在微信 MP 后台更新《用户隐私保护指引》,声明使用了“微信朋友关系”。可参考微信社区说明。
WARNING
后台配置可能需要一小时到一天才能生效。未完成或尚未生效时,授权弹窗无法正常拉起。
示例与构建模板
核心概念
- 主域:小游戏主要代码的运行环境,也就是游戏业务逻辑所在环境。
- 开放数据域:用于读取微信关系链数据并绘制排行榜的隔离环境。它不能直接访问主域业务逻辑和资源。
- 排行榜渲染:关系链数据只能在开放数据域读取,因此排行榜需要在开放数据域中用 Canvas 渲染。推荐使用微信的 Layout 引擎。
引入构建模板
将 build-templates 放到工程根目录:

text
wechatgame
├── openDataContext
│ ├── render
│ │ ├── style.js
│ │ └── template.js
│ ├── index.js
│ └── RankManager.js
└── game.jsonopenDataContext:开放数据域代码目录。style.js:Layout 样式。template.js:Layout XML 模板。index.js、RankManager.js:排行榜逻辑。game.json:声明开放数据域目录及 Layout 插件。
json
{
"deviceOrientation": "portrait",
"openDataContext": "openDataContext",
"plugins": {
"Layout": {
"version": "1.0.14",
"provider": "wx7a727ff7d940bb3f",
"contexts": [{ "type": "openDataContext" }]
}
}
}创建排行榜节点
在场景中创建
rankView节点。在其下创建
rankContent,添加 Cocos Creator 的SubContextView组件。节点激活时即可显示开放数据域内容,组件 Size 决定显示尺寸。
可在
rankView下增加业务侧背景图。
主域通信
主域通过 wx.getOpenDataContext().postMessage() 通知开放数据域更新数据或刷新排行榜:
typescript
@ccclass("ViewManager")
export class ViewManager extends Component {
@property(Node)
private rankListView: Node = null;
refreshRank() {
this.rankListView.active = true;
this.postToOpenData({ event: "refresh", key: "rank_score" });
}
setRankData(value: number) {
this.postToOpenData({
event: "setRankData",
key: "rank_score",
value,
});
}
private postToOpenData(data: object) {
const wxApi = window["wx"];
if (wxApi) {
wxApi.getOpenDataContext().postMessage({
...data,
type: "engine",
});
}
}
}开放数据域逻辑
监听主域指令
javascript
wx.onMessage((data) => {
if (data.type !== "engine") return;
if (data.event === "viewport") {
rankView.updateViewPort(data);
} else if (data.event === "refresh") {
// 获取数据并重新渲染
} else if (data.event === "setRankData") {
setRankData(data.key, data.value);
}
});上传用户排行榜数据
每一个 key 对应一个排行榜。存在多个排行榜时,由主域传入对应 key。
javascript
function setRankData(key, value) {
wx.setUserCloudStorage({
KVDataList: [{ key, value: value.toString() }],
success: () => console.log("设置排行榜数据成功"),
fail: (err) => console.error("设置排行榜数据失败", err),
});
}使用 Layout 渲染
Layout 通过 clear、init、layout 完成绘制:
javascript
const Layout = requirePlugin("Layout").default;
import getTemplate from "./render/template";
import style from "./render/style";
function draw(rankData) {
const canvas = wx.getSharedCanvas();
const context = canvas.getContext("2d");
Layout.clear();
Layout.init(getTemplate(rankData), style);
Layout.layout(context);
}可参考 Layout 模板语法,也可使用 doT 在线编译器编译模板。

模板与样式示例
javascript
export default function getTemplate(data) {
let out = `<view id="mainView"><scrollview id="rankView" scrollY="true">`;
for (const user of data) {
out += `<view class="item">`;
out += `<image class="userImg" src="${user.avatarUrl}"></image>`;
out += `<text class="userName" value="${user.nickname}"></text>`;
out += `<text class="userScores" value="得分:${user.scores}"></text>`;
out += `</view>`;
}
return out + `</scrollview></view>`;
}javascript
export default {
mainView: {
width: 640,
height: 840,
borderRadius: 36,
},
rankView: {
width: 500,
height: 800,
marginTop: 30,
alignSelf: "center",
alignItems: "center",
},
item: {
width: 480,
height: 80,
flexDirection: "row",
marginTop: 20,
backgroundImage: "url(openDataContext/render/bg.png)",
},
userImg: { width: 80, height: 80, borderRadius: 36 },
userName: {
width: 200,
height: 80,
lineHeight: 80,
marginLeft: 30,
fontSize: 36,
textAlign: "center",
},
userScores: {
width: 170,
height: 80,
lineHeight: 80,
marginRight: 30,
fontSize: 36,
textAlign: "center",
},
};| 基础效果 | 背景配置 | 背景效果 |
|---|---|---|
![]() | ![]() | ![]() |
批量创建列表项后,需要通过 marginTop 等样式控制间距:
| 批量列表 | 调整间距后 |
|---|---|
![]() | ![]() |
滚动列表与视口
使用 <scrollview> 时必须监听引擎发送的 viewport 事件,并调用 Layout.updateViewPort:
javascript
class RankView {
constructor() {
this.context = wx.getSharedCanvas().getContext("2d");
}
updateViewPort(data) {
Layout.updateViewPort({
x: data.x,
y: data.y,
width: data.width,
height: data.height,
});
}
draw(data) {
Layout.clear();
Layout.init(getTemplate(data), style);
Layout.layout(this.context);
}
}动态传入头像、昵称和分数后的效果:
注意事项
- 开放数据域脚本不要使用
async/await、可选链、空值合并等高版本语法。 - 在微信开发者工具中勾选“将 JS 编译成 ES5”,或在构建流程中自行完成语法降级。

大型本地转码工具未纳入 Wiki 仓库,需要时请从飞书原文获取。
参考资料
点我快速对接



›
‹




