Teams Tab App 代码深入浅出 - 配置页面
上一篇文章我们使用Teams Toolkit 来创建、运行 tab app。这篇文章我们深入来分析看一下tab app 的代码。
先打开代码目录,可以看到在 src 目录下有入口文件 index.tsx
,然后在 components
目录下有更多的一些 tsx 文件,tsx 是 typescript的一种扩展文件,主要用于 react 开发。
我们打开 index.tsx
,看一下代码。
import React from "react";
import ReactDOM from "react-dom";
import App from "./components/App";
import "./index.css";
ReactDOM.render(<App />, document.getElementById("root"));
可以看到代码极其简单明了,就是一个 <App>
,那我们就打开 App.tsx
看看。
import { Provider, teamsTheme } from "@fluentui/react-northstar";
import Privacy from "./Privacy";
import TermsOfUse from "./TermsOfUse";
import Tab from "./Tab";
import TabConfig from "./TabConfig";
import { useTeams } from "msteams-react-base-component";
.........
export default function App() {
const { theme } = useTeams({})[0];
return (
<Provider theme={theme || teamsTheme} styles=>
<Router>
<Route exact path="/">
<Redirect to="/tab" />
</Route>
<>
<Route exact path="/privacy" component={Privacy} />
<Route exact path="/termsofuse" component={TermsOfUse} />
<Route exact path="/tab" component={Tab} />
<Route exact path="/config" component={TabConfig} />
</>
</Router>
</Provider>
);
}
App.tsx
也算简单,有几个地方需要我们注意的,第一个就是调用了 useTeams()
方法来获取当前的 teams 的theme,teams实际上有几个不同的theme,调用 “msteams-react-base-component” 的 useTeams()
就能够拿到当前的 theme,然后把 theme 设置给了 Provider,在 Router方面则一看就明白,配置了一些路径和对应的 component。
这些路径实际上在 manifest.json 里有用到。我们打开 /build/appPackage/manifest.local.json
文件,我们可以看到:
{
...
"developer": {
"name": "Teams App, Inc.",
"websiteUrl": "https://localhost:53000",
"privacyUrl": "https://localhost:53000/index.html#/privacy",
"termsOfUseUrl": "https://localhost:53000/index.html#/termsofuse"
},
"configurableTabs": [
{
"configurationUrl": "https://localhost:53000/index.html#/config",
"canUpdateConfiguration": true,
"scopes": [
"team",
"groupchat"
]
}
],
"staticTabs": [
{
"entityId": "index",
"name": "Personal Tab",
"contentUrl": "https://localhost:53000/index.html#/tab",
"websiteUrl": "https://localhost:53000/index.html#/tab",
"scopes": [
"personal"
]
}
],
....
}
Privacy.tsx
和 TermsOfUse.tsx
非常简单,我们不在展开,我们先来看一下 TabConfig.tsx
。简化后的内容如下:
import { app, pages } from "@microsoft/teams-js";
class TabConfig extends React.Component {
render() {
app.initialize().then(() => {
pages.config.registerOnSaveHandler((saveEvent) => {
const baseUrl = `https://${window.location.hostname}:${window.location.port}`;
pages.config.setConfig({
suggestedDisplayName: "My Tab",
entityId: "Test",
contentUrl: baseUrl + "/index.html#/tab",
websiteUrl: baseUrl + "/index.html#/tab",
}).then(() => {
saveEvent.notifySuccess();
});
});
pages.config.setValidityState(true);
});
return (
<div>...</div>
);
}
}
这个基本是 tab 配置页面的标准写法,调用 app.initialize()
方法,然后注册一个 “Save” buttton 的回调函数,在这个回调函数里,调用 pages.config.setConfig()
函数来告诉 Teams,我们新建的tab的配置,新建的tab 的url是什么。
注册完后,调用了 pages.config.setValidityState(true);
来告诉 Teams,我们的 config 页面已经配置好了,可以让用户来点击 Save 按钮了。这里面有点绕,但如果各位仔细看上面的代码,也不难理解。
我们再来整理一下这个流程:
app.initialize().then(() => {
pages.config.registerOnSaveHandler((saveEvent) => { // 注册回调函数,当用户点击 Save 按钮时,这个方法会被触发
const baseUrl = `https://${window.location.hostname}:${window.location.port}`;
pages.config.setConfig({ // 告诉 Teams 新建的 tab 的具体情况,比如tab 名字和 url
suggestedDisplayName: "My Tab",
entityId: "Test",
contentUrl: baseUrl + "/index.html#/tab",
websiteUrl: baseUrl + "/index.html#/tab",
}).then(() => {
saveEvent.notifySuccess(); // 告诉 Teams,Save点击事件处理完毕
});
});
pages.config.setValidityState(true); // 告诉 Teams可以允许用户点击 Save 按钮
});
return (
<div>...</div> // 返回 config 页面的 html 内容
);
*/index.html#/tab
对应到的是 Tab component,对于 Tab 具体页面里基本都是React的一些写法,我这里就不再展开讲 React 开发了,值得一提的是,我们应该尽量使用 fluentui
和 msteams-react-base-component
库,让使用 React 开发teams tab更加方便,并且风格和teams更加一致。