Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add doc for Mask and Tagging #1335

Open
wants to merge 6 commits into
base: trailhead_guidance
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions docs/develop/guidance/feature_Mask.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Mask 伪代码

## 组件调用

```vue
<script lang="ts" setup>
const visible = ref(false); // Mask是否显示
const currentTags = ref(["mother", "son"]); // 当前步骤需要高亮显示的组件的查找路径
</script>

<template>
<Mask :visible="visible" :tags="currentTags" />
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mask 的使用方除了希望 Mask 遮住界面上几乎所有内容外,一般都还会展示一些别的内容,比如提示文案、箭头、引导用的卡通形象等,这些内容使用方应当如何渲染以确保它们不会被 Mask 遮住?一般这内容会希望相对被高亮显示的组件定位,是可以方便地做到的吗?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

好的,这确实也是需要考虑的地方。我们经过讨论决定通过Props的形式传入description字段:

  • 如果传了description,则代表当前是following步骤,除 高亮目标组件 外还需要展示卡通形象、提示文案(description)和箭头。
  • 如果没传description,则代表当前是coding步骤,不需要额外素材信息展示,仅 高亮目标组件 即可。

对于 卡通形象、提示文案(description)和箭头 展示位置的处理,这里需要考虑:

  • 蒙层中高亮元素的位置是需要通过Tagging精准高亮的。
  • 卡通形象、提示文案(description)和箭头 的展示位置需要通过高亮目标动态计算的。

对于动态计算的部分,这里可以考虑坐标系的概念,在Mask建立二维坐标系,根据 高亮目标组件的位置,分别计算 卡通形象、提示文案和箭头 的位置,同理这三者之间也有位置关系。比如:

  • 提示文案应在卡通形象上方
  • 箭头指向不可能是卡通形象,只会指向 高亮目标组件

除此外还要考虑屏幕边界问题。

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

我们经过讨论决定通过Props的形式传入description字段:

你的意思是把“卡通形象、提示文案(description)和箭头”这些内容都做到 Mask 里边?

你说的位置计算逻辑不是现在关注的重点,我们现在应该关心的是,哪些逻辑是哪个模块的职责,在我们给定的职责划分下,接口是不是易用的

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

是的,原来是想在StepPlayer里做。现在发现在Mask里会更方便一点,因为Mask本身调用了Tagging,这样可以减少调用次数。

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

把某个逻辑对应的职责从一个模块挪到另一个模块,是一个很重的动作,因为这会改变模块本身的定位,进而影响整体的模块拆分的合理性;建议当遇到问题的时候,先去想:

  1. 它是不是一个重要的问题,很多时候性能问题都不是问题
  2. 能不能通过优化接口(不改变定位)来达到目的

都不行才去考虑调整模块定位

这里如果只是多调用一次 Tagging 模块的接口,这个本身不是问题,又不是什么很重的操作;每个模块是不是关心了不该它关心的事情、干了它不该干的事情才是重要的

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

我懂了,这个操作和Mask没什么关系,还是放回StepPlayer吧

</template>
```
90 changes: 90 additions & 0 deletions docs/develop/guidance/feature_Tagging.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# Tagging 伪代码

## 全局注册(单例)

```ts
// 通过 provide 全局注册单例
const app = createApp(App);
//
app.provide("Tagging", new Tagging());
```

## 语义化标注(标注方)

### 示例组件

```vue
<!-- 示例组件1 -->
<template>
<Father data-tag="father">
<Son data-tag="son" />
<Daughter data-tag="daughter" />
</Father>
</template>

<!-- 示例组件2 -->
<template>
<Mather data-tag="mather">
<Son data-tag="son" />
<Daughter data-tag="daughter" />
</Mather>
</template>
```

### Tagging 中保存示例组件树结构信息

```ts
this.tagTree = {
father: {
e: FatherComponent,
children: {
son: {
e: SonComponent,
children: {},
},
daughter: {
e: DaughterComponent,
children: {},
},
},
},
mather: {
e: MatherComponent,
children: {
son: {
e: SonComponent,
children: {},
},
daughter: {
e: DaughterComponent,
children: {},
},
},
},
};
```

## 在 Mask 组件中使用(消费方)

```vue
<script lang="ts" setup>
// 组件内注入
const tagging = inject("Tagging");

// 传入keys参数,查找为 key = 'mother' 下的 key = 'son' 的组件,类似于CSS类选择器
const component: Component = tagging.getElementByKeys(["mother", "son"]);

const highlightComponentStyle = () => {
const lightElementStyle = {
...
...
}

component.style = highlightComponentStyle
}
</script>

<template>
<div class="mask" v-if="visible">...</div>
</template>
```
6 changes: 6 additions & 0 deletions docs/develop/guidance/module_Mask.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
```ts
type Props = {
visible: boolean; // 是否显示蒙层
tags: string[]; // 需要高亮组件的查找路径
};
```
35 changes: 35 additions & 0 deletions docs/develop/guidance/module_Tagging.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
```typescript
/** 节点 */
export interface TagNode {
e: Component;
children?: Record<string, TagNode>;
}

/** Tag 类 */
export class Tagging {
/** */
private tagTree: Record<string, TagNode>;

contrustor() {
/* 遍历组件树,收集tag,初始化tagTree */
}

/** 添加一个标注
* @param key: 添加组件的key值
* @param component: 被添加的组件
* @param keys: 添加到的目标节点,不传时添加到根节点
*/
addTag(key: string, component: Component, keys?: string[]): void;

/** 移除标注
* @param keys: 要移除的目标节点
*/
removeTag(keys: string[]): void;

/** 通过查找路径keys获取目标组件 */
getElementByKeys(keys: string[]): Component | null;

/** 清空所有标注 */
clearAllTags(): void;
}
```