|
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