|
20 | 20 | <div class="ti-rel cmp-container"> |
21 | 21 | <div class="flex-horizontal docs-content-main"> |
22 | 22 | <div class="docs-tabs-wrap"> |
23 | | - <div v-if="['interfaces', 'types', 'classes'].includes(cmpId)" id="TS" class="all-api-container"> |
24 | | - <div class="ti-f-c ti-f-wrap api-list"> |
25 | | - <div class="mt20" v-for="oneGroup in currJson.apis" :key="oneGroup.name"> |
26 | | - <div class="ti-f-r ti-f-pos-start ti-fw-bold"> |
27 | | - <div :id="`cmp-${oneGroup.name}`" class="ti-f18"> |
28 | | - {{ oneGroup.name }} |
29 | | - </div> |
30 | | - <div class="ti-ml12 ti-b-a-primary ti-c-primary ti-px8 ti-py4"> |
31 | | - {{ oneGroup.type }} |
32 | | - </div> |
33 | | - </div> |
34 | | - <div v-for="(oneApiArr, key) in oneGroup" :key="key"> |
35 | | - <template v-if="key !== 'name' && key !== 'type' && oneApiArr.length > 0"> |
36 | | - <div class="ti-f18 ti-py28" :id="`${oneGroup.name}--${key}`"> |
37 | | - {{ key }} |
38 | | - </div> |
39 | | - <div class="api-table-box"> |
40 | | - <tiny-grid class="api-table" :data="tableData[oneGroup.name][key]" :expand-config="apiExpandConf"> |
41 | | - <tiny-grid-column |
42 | | - v-if="tableData[oneGroup.name][key][0]?.type" |
43 | | - class-name="api-table-expand-col" |
44 | | - type="expand" |
45 | | - width="32" |
46 | | - > |
47 | | - <template #default="{ row }"> |
48 | | - <async-highlight v-if="row.code" :code="row.code.trim()" types="ts"></async-highlight> |
49 | | - </template> |
50 | | - </tiny-grid-column> |
51 | | - <tiny-grid-column field="name" :title="i18nByKey('name')" :width="columnWidth[key][0]"> |
52 | | - <template #default="{ row }"> |
53 | | - <span class="api-table-name"> |
54 | | - <a v-if="row.demoId" @click="jumpToDemo(row.demoId)">{{ row.name }}</a> |
55 | | - <span v-else>{{ row.name }}</span> |
56 | | - </span> |
57 | | - <version-tip |
58 | | - v-if="row.meta || row.versionTipOption" |
59 | | - :meta="row.meta" |
60 | | - v-bind="row.versionTipOption" |
61 | | - render-type="tag" |
62 | | - tip-subject="api" |
63 | | - > |
64 | | - </version-tip> |
65 | | - </template> |
66 | | - </tiny-grid-column> |
67 | | - <tiny-grid-column |
68 | | - v-if="tableData[oneGroup.name][key][0]?.type" |
69 | | - field="type" |
70 | | - :title="i18nByKey('propType')" |
71 | | - :width="columnWidth[key][1]" |
72 | | - > |
73 | | - <template #default="{ row }"> |
74 | | - <a |
75 | | - v-if="row.typeAnchorName" |
76 | | - :href="`${row.typeAnchorName.indexOf('#') === -1 ? '#' : ''}${row.typeAnchorName}`" |
77 | | - v-html="row.type" |
78 | | - ></a> |
79 | | - <span v-else v-html="row.type"></span> |
80 | | - </template> |
81 | | - </tiny-grid-column> |
82 | | - <tiny-grid-column |
83 | | - v-if="key === 'props'" |
84 | | - field="defaultValue" |
85 | | - :title="i18nByKey('defValue')" |
86 | | - :width="columnWidth[key][2]" |
87 | | - ></tiny-grid-column> |
88 | | - <tiny-grid-column field="desc" :title="i18nByKey('desc')"> |
89 | | - <template #default="data"> |
90 | | - <span v-html="data.row.desc"></span> |
91 | | - </template> |
92 | | - </tiny-grid-column> |
93 | | - </tiny-grid> |
94 | | - </div> |
95 | | - </template> |
96 | | - </div> |
97 | | - </div> |
98 | | - </div> |
99 | | - </div> |
100 | | - <tiny-tabs v-else v-model="activeTab" ref="demoTabs" class="docs-content-tabs" @click="onTabsClick"> |
| 23 | + <tiny-tabs v-model="activeTab" ref="demoTabs" class="docs-content-tabs" @click="onTabsClick"> |
101 | 24 | <tiny-tab-item :title="i18nByKey('demos')" name="demos"> |
102 | 25 | <!-- demos列表 --> |
103 | 26 | <template v-if="currJson?.demos?.length"> |
|
106 | 29 | <demo |
107 | 30 | v-for="demo in currJson.demos" |
108 | 31 | :key="demo.name" |
| 32 | + :observer="observer" |
| 33 | + :isIntersecting="demo.isIntersecting" |
109 | 34 | :demo="demo" |
110 | 35 | :curr-demo-id="currDemoId" |
111 | 36 | class="mb32" |
112 | 37 | @mounted="demoMounted" |
113 | 38 | /> |
114 | 39 | </div> |
115 | 40 | <div v-else> |
116 | | - <demo v-if="singleDemo" :key="singleDemo.name" :demo="singleDemo" /> |
| 41 | + <demo v-if="singleDemo" :isIntersecting="true" :key="singleDemo.name" :demo="singleDemo" /> |
117 | 42 | </div> |
118 | 43 | </div> |
119 | 44 | </template> |
@@ -294,11 +219,10 @@ export default defineComponent({ |
294 | 219 | webDocPath: computed(() => ''), |
295 | 220 | langKey: getWord('zh-CN', 'en-US'), |
296 | 221 | cmpId: '', |
| 222 | + observer: null, |
297 | 223 | currJson: { column: 1, demos: [], apis: [], types: {} }, |
298 | 224 | cmpTopMd: null, |
299 | 225 | cmpFAQMd: null, |
300 | | - evenDemo: computed(() => state.currJson.demos?.filter((d, i) => i % 2 === 0) || []), |
301 | | - oddDemo: computed(() => state.currJson.demos?.filter((d, i) => i % 2 === 1) || []), |
302 | 226 | currDemoId: '', |
303 | 227 | demoAnchorLinks: computed(() => { |
304 | 228 | const links = |
@@ -481,6 +405,7 @@ export default defineComponent({ |
481 | 405 | // 用户打开官网有时候会带一些特殊字符的hash,try catch一下防止js报错 |
482 | 406 | scrollTarget = document.querySelector(`#${hash}`) |
483 | 407 | } catch (err) {} |
| 408 | +
|
484 | 409 | if (scrollTarget && !isRunningTest) { |
485 | 410 | // doc-layout-scoller(滚动) > tabs > tab-content(relative), 造成 scrollTarget.offsetTop 是相对于 tab-content的距离 |
486 | 411 | // 所以滚动需要修正 tab-title的占位高度才行 |
@@ -556,6 +481,12 @@ export default defineComponent({ |
556 | 481 | // 3、加载cmpId.js 文件 |
557 | 482 | // eslint-disable-next-line no-eval |
558 | 483 | const json = jsData ? eval('(' + jsData.slice(15) + ')') : {} |
| 484 | +
|
| 485 | + // 默认设置每个实例demo都不和视图相交 |
| 486 | + json.demos?.forEach((item) => { |
| 487 | + item.isIntersecting = false |
| 488 | + }) |
| 489 | +
|
559 | 490 | state.currJson = { |
560 | 491 | ...json, |
561 | 492 | demos: $clone(json.demos || []), // 克隆一下,避免保存上次的isOpen |
@@ -635,6 +566,27 @@ export default defineComponent({ |
635 | 566 | if (docLayout) { |
636 | 567 | docLayout.addEventListener('scroll', onDocLayoutScroll) |
637 | 568 | } |
| 569 | +
|
| 570 | + const options = { |
| 571 | + root: docLayout, |
| 572 | + threshold: 0.2 |
| 573 | + } |
| 574 | +
|
| 575 | + const callback = (entries) => { |
| 576 | + entries.forEach((entry) => { |
| 577 | + if (entry.isIntersecting) { |
| 578 | + // 当demo示例与视图相交才加载对应的vue组件 |
| 579 | + const demoId = entry.target.id |
| 580 | + state.currJson.demos.forEach((item) => { |
| 581 | + if (item.demoId === demoId) { |
| 582 | + item.isIntersecting = true |
| 583 | + } |
| 584 | + }) |
| 585 | + } |
| 586 | + }) |
| 587 | + } |
| 588 | +
|
| 589 | + state.observer = new IntersectionObserver(callback, options) |
638 | 590 | }) |
639 | 591 | } |
640 | 592 |
|
@@ -736,6 +688,7 @@ export default defineComponent({ |
736 | 688 |
|
737 | 689 | onMounted(() => { |
738 | 690 | loadPage() |
| 691 | + // 加载公共尾部 |
739 | 692 | const common = new window.TDCommon(['#footer'], {}) |
740 | 693 | common.renderFooter() |
741 | 694 | setScrollListener() |
@@ -766,6 +719,7 @@ export default defineComponent({ |
766 | 719 | <style lang="less" scoped> |
767 | 720 | .docs-header { |
768 | 721 | padding: 16px 40px; |
| 722 | + min-height: 102px; |
769 | 723 | background-color: #fff; |
770 | 724 | box-shadow: 12px 0 20px 6px rgba(0, 0, 0, 0.06); |
771 | 725 |
|
|
0 commit comments