gis-view-webgl2 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -8
- package/dist/gis-view.css +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +309 -59
- package/dist/index.js +1 -1
- package/docs/AI/345/257/271/350/257/235/346/261/207/346/200/273.md +117 -0
- package/docs/GisView.md +2 -2
- package/docs/ai/06-/344/274/232/350/257/235/347/264/242/345/274/225/344/270/216/345/244/215/346/237/245/346/226/271/346/263/225.md +107 -0
- package/docs/api/index.html +1 -1
- package/docs/demos/ApiCoverageDemo.vue +644 -0
- package/docs/demos/ChannelDemo.vue +14 -12
- package/docs/demos/ClusterDemo.vue +251 -0
- package/docs/demos/CopyMergeDemo.vue +3 -4
- package/docs/demos/EventDemo.vue +3 -3
- package/docs/demos/GisViewDemo.vue +64 -8809
- package/docs/demos/api-index.js +48 -41
- package/docs/demos/demos.js +33 -16
- package/docs/demos/gis-view-demo/GisViewDemoCardHeader.vue +28 -0
- package/docs/demos/gis-view-demo/GisViewDemoDialogs.vue +82 -0
- package/docs/demos/gis-view-demo/GisViewDemoFooter.vue +16 -0
- package/docs/demos/gis-view-demo/GisViewDemoHeading.vue +16 -0
- package/docs/demos/gis-view-demo/GisViewDemoPanelStack.vue +71 -0
- package/docs/demos/gis-view-demo/GisViewDemoStage.vue +219 -0
- package/docs/demos/gis-view-demo/demo.css +1230 -0
- package/docs/demos/gis-view-demo/demoContext.js +12 -0
- package/docs/demos/gis-view-demo/panels/DataPanels.vue +303 -0
- package/docs/demos/gis-view-demo/panels/OpsPanels.vue +174 -0
- package/docs/demos/gis-view-demo/panels/StylePanels.vue +561 -0
- package/docs/demos/gis-view-demo/panels/ViewPanels.vue +396 -0
- package/docs/demos/gis-view-demo/useGisViewDemo.js +6188 -0
- package/docs/format/07-/344/272/213/344/273/266/350/275/275/350/215/267/344/270/216/347/244/272/344/276/213/346/225/260/346/215/256.md +3 -2
- package/docs/internals/16-03-/344/274/230/345/214/226/344/270/216/345/217/226/350/210/215-/344/270/213.md +1 -1
- package/docs/manual/02-/345/235/220/346/240/207/344/270/216/346/225/260/346/215/256.md +3 -2
- package/docs/manual/03-/351/205/215/347/275/256/351/241/271.md +87 -14
- package/docs/manual/04-/344/272/213/344/273/266/344/270/216/345/233/236/350/260/203.md +8 -8
- package/docs/manual/07-/346/214/207/351/222/210/344/270/216/350/246/201/347/264/240/347/274/226/350/276/221.md +40 -3
- package/docs/manual/08-/351/200/211/344/270/255/344/270/216/346/213/220/347/202/271.md +26 -0
- package/docs/manual/09-/351/200/232/351/201/223/344/270/216/345/244/232/345/233/236/347/272/277.md +6 -2
- package/docs/manual/10-/351/200/232/351/201/223/347/274/226/350/276/221/344/270/216/346/226/260/345/242/236.md +39 -7
- package/docs/manual/12-/346/240/207/347/255/276/344/270/216/350/243/205/351/245/260.md +13 -4
- package/docs/manual/13-/345/212/250/346/225/210/344/270/216/345/233/276/345/205/203.md +3 -0
- package/docs/manual/14-/350/247/206/345/233/276/344/270/216/347/255/233/351/200/211.md +35 -19
- package/docs/manual/15-/345/257/274/345/207/272/344/270/216/351/233/206/346/210/220.md +5 -0
- package/docs/manual/16-/345/256/236/344/276/213/346/226/271/346/263/225/346/200/273/350/241/250.md +12 -6
- package/docs/manual/17-/345/217/202/346/225/260/351/200/237/346/237/245.md +39 -22
- package/docs/manual/18-/351/200/220/346/226/271/346/263/225/347/244/272/344/276/213.md +52 -13
- package/docs/manual/20-/346/200/247/350/203/275/344/270/216/345/244/247/346/225/260/346/215/256.md +25 -1
- package/docs/manual/21-/350/257/264/346/230/216/344/270/216/345/270/270/350/247/201/351/227/256/351/242/230.md +5 -5
- package/docs/steps/README.md +17 -11
- package/docs/steps/selftest-actions.html +3 -5
- package/docs/steps/selftest-demo.html +27 -18
- package/docs/steps/selftest-demos.html +387 -27
- package/docs/steps/selftest-docs.html +4 -4
- package/docs/steps/selftest-effects.html +200 -0
- package/docs/steps/selftest-features.html +512 -11
- package/docs/steps/selftest-labels.html +74 -0
- package/docs/steps/selftest-perf.html +293 -20
- package/docs/steps/selftest-scale.html +52 -29
- package/docs/steps/step-10-full.js +1 -1
- package/docs/steps/step-12-events.js +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { inject } from 'vue'
|
|
2
|
+
|
|
3
|
+
export const DEMO_CONTEXT = Symbol('gis-view-demo')
|
|
4
|
+
|
|
5
|
+
/** 子组件统一从这里取演示上下文;入口组件负责 provide。 */
|
|
6
|
+
export const useGisViewDemoContext = () => {
|
|
7
|
+
const context = inject(DEMO_CONTEXT)
|
|
8
|
+
if (!context) {
|
|
9
|
+
throw new Error('GisViewDemo 子组件必须在 GisViewDemo 内使用')
|
|
10
|
+
}
|
|
11
|
+
return context
|
|
12
|
+
}
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { useGisViewDemoContext } from '../demoContext.js'
|
|
3
|
+
const {
|
|
4
|
+
STATION_TYPES, VOLTAGE_FILTERS, CASCADE_MODES, viewRef, selectedLabel, channelLabel, activePanel, dataShape,
|
|
5
|
+
dataShapeReadout, channelMode, channelOffset, channelWidth, channelInset, channelNodeWidth,
|
|
6
|
+
channelTangentInset, channelTangentInsetText, hideChannelNodes, searchKeyword, searchScope, searchFocus,
|
|
7
|
+
searchReadout, filterVoltage, filterType, filterKeyword, filterLines, filterCascade, filterReadout,
|
|
8
|
+
parallelGroups, parallelGroupsText, parallelGroupsJson, runSearch, exportDataFormat, exportDataAll,
|
|
9
|
+
exportParts, EXPORT_PART_CHOICES, toggleExportPart, exportPart, EXPORT_PARTS, exportDataReadout,
|
|
10
|
+
exportDataSample, exportDataToFile, exportSelectionPartsToFile, exportPartToFile, refreshExportSample,
|
|
11
|
+
refreshDataShape, printDataShape, copyParallelGroupRecords, clearFilterControls, selectFirstLine,
|
|
12
|
+
selectChannelLine, selectSeveralNodes, selectQuarterBox, addWaypointToFirstLine, addWaypointToChannel,
|
|
13
|
+
channelGroupOptions, channelGroupTarget, channelGroupSplitSize, channelGroupReadout, splitSelectedChannel,
|
|
14
|
+
mergeSelectedChannel, channelRenameText, renameSelectedChannel, addLineToSelectedChannel,
|
|
15
|
+
removeLineFromSelectedChannel, removeLastChannelGroup, separateSelectedChannelGroups,
|
|
16
|
+
clearSeparatedChannelGroups, addChannelAutoCommit, addChannelContinuous, addChannelChain, addChannelCircuits,
|
|
17
|
+
addChannelHandoff, addChannelMembers, fillChannelMemberColors, resetChannelMembers, addChannelMemberSummary,
|
|
18
|
+
channelDraft, draftClickText, lastAddedChannel, channelReadyPayload, channelDraftOptions, channelDraftReadout,
|
|
19
|
+
channelOptionLabel, beginAddChannel, continueAddChannel, removeLastAdded, cancelAddChannel,
|
|
20
|
+
endChannelDraftDemo, commitChannelDraft, addChannelProgrammatic, addLineProgrammatic, targetedType,
|
|
21
|
+
updateTargeted, clearSelection, deselectFirstSelected, createChannels,
|
|
22
|
+
} = useGisViewDemoContext()
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
<template>
|
|
26
|
+
<div v-show="activePanel === 'data-shape'" class="demo-panel-body">
|
|
27
|
+
<div class="demo-controls">
|
|
28
|
+
<span class="demo-control-hint">声明数据只有三份:points / lines / channels(写进 options 或 updateData / updateOptions);通道、分组、拐点的运行时结构由实例接口给出来</span>
|
|
29
|
+
<button type="button" @click="refreshDataShape()">刷新读数</button>
|
|
30
|
+
<button type="button" @click="printDataShape()">打印完整结构到控制台</button>
|
|
31
|
+
<span class="demo-control-hint">{{ dataShapeReadout }}</span>
|
|
32
|
+
</div>
|
|
33
|
+
<div class="demo-controls demo-controls--shape">
|
|
34
|
+
<div v-for="block in (dataShape ?? [])" :key="block.key" class="demo-shape">
|
|
35
|
+
<p class="demo-shape-title">{{ block.title }}</p>
|
|
36
|
+
<span class="demo-shape-fields">{{ block.fields }}</span>
|
|
37
|
+
<span class="demo-shape-note">{{ block.note }}</span>
|
|
38
|
+
<pre class="demo-groups">{{ block.sample }}</pre>
|
|
39
|
+
</div>
|
|
40
|
+
<p v-if="!dataShape" class="demo-shape-fields">点「刷新读数」看当前这一份数据的真实结构</p>
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
|
|
44
|
+
<div v-show="activePanel === 'data-export'" class="demo-panel-body">
|
|
45
|
+
<div class="demo-controls">
|
|
46
|
+
<label class="demo-slider">
|
|
47
|
+
口径
|
|
48
|
+
<select v-model="exportDataFormat" title="view = 四份分开(points / lines / channels / parallelGroups);new = new.json 的列名(station_data + channel_data + 四至范围);test = test.json 的列名(point_data + line_data + parallel_groups)" @change="refreshExportSample()">
|
|
49
|
+
<option value="view">四份分开(view)</option>
|
|
50
|
+
<option value="new">new.json(station_data + channel_data)</option>
|
|
51
|
+
<option value="test">test.json(point_data + line_data + parallel_groups)</option>
|
|
52
|
+
</select>
|
|
53
|
+
</label>
|
|
54
|
+
<label><input v-model="exportDataAll" type="checkbox" @change="refreshExportSample()" /> 拐点连没编辑过的分组一起列(all)</label>
|
|
55
|
+
<button type="button" @click="exportDataToFile()">导出整份(下载 JSON)</button>
|
|
56
|
+
<span class="demo-control-hint">{{ exportDataReadout }}</span>
|
|
57
|
+
</div>
|
|
58
|
+
<div class="demo-controls">
|
|
59
|
+
<label class="demo-slider">
|
|
60
|
+
分项(多选)
|
|
61
|
+
</label>
|
|
62
|
+
<label v-for="item in EXPORT_PART_CHOICES" :key="item.value" :title="item.label">
|
|
63
|
+
<input type="checkbox" :checked="exportParts.includes(item.value)" @change="toggleExportPart(item.value, $event.target.checked)" /> {{ item.label }}
|
|
64
|
+
</label>
|
|
65
|
+
<button type="button" @click="exportSelectionPartsToFile()">导出选中数据的这几份</button>
|
|
66
|
+
<button type="button" @click="refreshExportSample()">刷新样例</button>
|
|
67
|
+
</div>
|
|
68
|
+
<div class="demo-controls demo-controls--shape">
|
|
69
|
+
<label class="demo-slider">
|
|
70
|
+
单份
|
|
71
|
+
<select v-model="exportPart" title="一次只取一份:节点 / 线路 / 通道 / 拐点各是各的口径,互不混在一起" @change="refreshExportSample()">
|
|
72
|
+
<option v-for="item in EXPORT_PARTS" :key="item.value" :value="item.value">{{ item.label }}</option>
|
|
73
|
+
</select>
|
|
74
|
+
</label>
|
|
75
|
+
<button type="button" @click="exportPartToFile()">导出这一份(下载 JSON)</button>
|
|
76
|
+
</div>
|
|
77
|
+
<div class="demo-controls demo-controls--shape">
|
|
78
|
+
<span class="demo-control-hint">分项多选:选什么就导什么,默认场站 + 通道;勾了通道或线路会自动带上拐点(通道的路由与线路的折线都靠拐点说话),一个都不勾就是四份全要。节点与通道走 new.json 那套列名(station_data / channel_data:通道的 line_data 里是回线、coords 是整条通道的路由),线路与拐点走 test.json 那套(line_data / parallel_groups:拐点只记在集合里,不散进每条回线);业务列(max_loading_rate 这类)原样透传,warnings 会说哪个 id 没找到。「导出选中数据的这几份」统一走 exportData({ scope: 'selection' }) —— 选中口径与「导出选中为数据」一样(框选 / 多选出来的那批节点,线路取两端都在里面的),出的却是分项业务表。下面这一段是「只取头两个节点 / 两条线 / 一条通道」的样例</span>
|
|
79
|
+
<pre class="demo-groups">{{ exportDataSample || '点「刷新样例」看当前口径下的导出结构' }}</pre>
|
|
80
|
+
</div>
|
|
81
|
+
</div>
|
|
82
|
+
|
|
83
|
+
<div v-show="activePanel === 'data-channel'" class="demo-panel-body">
|
|
84
|
+
<div class="demo-controls">
|
|
85
|
+
<label><input v-model="channelMode" type="checkbox" /> 通道多回线</label>
|
|
86
|
+
<label><input v-model="hideChannelNodes" type="checkbox" /> 隐藏通道端点节点</label>
|
|
87
|
+
<label class="demo-slider">
|
|
88
|
+
偏移方式
|
|
89
|
+
<select v-model="channelOffset">
|
|
90
|
+
<option value="tangent">切点均分</option>
|
|
91
|
+
<option value="inset">切点内收</option>
|
|
92
|
+
</select>
|
|
93
|
+
</label>
|
|
94
|
+
<label class="demo-slider">
|
|
95
|
+
节点宽度倍数
|
|
96
|
+
<input v-model.lazy.number="channelNodeWidth" type="range" min="0" max="2" step="0.05" />
|
|
97
|
+
<span>{{ channelNodeWidth.toFixed(2) }}</span>
|
|
98
|
+
</label>
|
|
99
|
+
<label class="demo-slider">
|
|
100
|
+
通道宽度
|
|
101
|
+
<input v-model.lazy.number="channelWidth" type="range" min="0.04" max="0.4" step="0.01" :disabled="channelNodeWidth > 0" />
|
|
102
|
+
<span>{{ channelWidth.toFixed(2) }}</span>
|
|
103
|
+
</label>
|
|
104
|
+
<label class="demo-slider">
|
|
105
|
+
内收比例
|
|
106
|
+
<input v-model.lazy.number="channelInset" type="range" min="0" max="0.42" step="0.02" :disabled="channelOffset !== 'inset'" />
|
|
107
|
+
<span>{{ channelInset.toFixed(2) }}</span>
|
|
108
|
+
</label>
|
|
109
|
+
<label class="demo-slider">
|
|
110
|
+
切点内收
|
|
111
|
+
<input v-model.lazy.number="channelTangentInset" type="range" min="-1" max="8" step="0.5" :disabled="channelNodeWidth <= 0" />
|
|
112
|
+
<span>{{ channelTangentInsetText }}</span>
|
|
113
|
+
</label>
|
|
114
|
+
<span class="demo-control-hint">通道:{{ channelLabel }}</span>
|
|
115
|
+
</div>
|
|
116
|
+
|
|
117
|
+
<div class="demo-controls">
|
|
118
|
+
<label class="demo-slider">
|
|
119
|
+
通道分组
|
|
120
|
+
<select v-model="channelGroupTarget" :disabled="!channelGroupOptions.length" title="回线最多的前几条通道">
|
|
121
|
+
<option v-for="option in channelGroupOptions" :key="String(option.id)" :value="String(option.id)">{{ option.id }}({{ option.lines }} 回)</option>
|
|
122
|
+
</select>
|
|
123
|
+
</label>
|
|
124
|
+
<label class="demo-slider">
|
|
125
|
+
每组回线
|
|
126
|
+
<select v-model.number="channelGroupSplitSize" title="拆分时每组放几条回线(最少一条)">
|
|
127
|
+
<option :value="1">1 回</option>
|
|
128
|
+
<option :value="2">2 回</option>
|
|
129
|
+
<option :value="3">3 回</option>
|
|
130
|
+
</select>
|
|
131
|
+
</label>
|
|
132
|
+
<button type="button" @click="splitSelectedChannel">拆分分组</button>
|
|
133
|
+
<button type="button" @click="mergeSelectedChannel">合并分组</button>
|
|
134
|
+
<button type="button" @click="separateSelectedChannelGroups">加拐点分开分组</button>
|
|
135
|
+
<button type="button" @click="clearSeparatedChannelGroups">去掉分开的拐点</button>
|
|
136
|
+
<input v-model="channelRenameText" type="text" placeholder="通道名称(留空 = 摘掉)" title="updateChannel({ name }):悬停提示的 {name}、标签模板与搜索都取它" />
|
|
137
|
+
<button type="button" @click="renameSelectedChannel">改名</button>
|
|
138
|
+
<button type="button" @click="addLineToSelectedChannel">加一条回线</button>
|
|
139
|
+
<button type="button" @click="removeLineFromSelectedChannel">摘一条回线</button>
|
|
140
|
+
<button type="button" @click="removeLastChannelGroup">删除一个分组</button>
|
|
141
|
+
<span class="demo-control-hint">{{ channelGroupReadout }}</span>
|
|
142
|
+
<details class="demo-hint-more"><summary>说明</summary><span class="demo-control-hint">拆分:第一组沿用当前拐点、新分组的线路不带拐点;合并:被并入的线路跟随目标分组的拐点(目标没有拐点就一条都不带);加点 / 拖点只作用于同一分组的线路;拆分 / 合并只换骨架:偏移按整条通道排(每条回线各占一条车道),两回线拆成两组各一条时两根线一左一右、四回线拆成两组时四条线还在原来的位置上,都不会重合;想把某一组拐到别的走廊上就用「加拐点分开分组」给第 2…n 组各加一个拐点(每组按序号沿法线往外让一档,第 1 组不动),「去掉分开的拐点」回到原来的车道</span></details>
|
|
143
|
+
</div>
|
|
144
|
+
<div class="demo-controls">
|
|
145
|
+
<div class="demo-members">
|
|
146
|
+
<span class="demo-control-hint">逐条回线属性(linePropsByMember):第 i 行只管第 i 回,盖在统一的 lineProps 之上;留空的项跟着统一配置 / 自动名称走({{ addChannelMemberSummary }})</span>
|
|
147
|
+
<div v-for="(member, index) in addChannelMembers" :key="index" class="demo-member-row">
|
|
148
|
+
<span class="demo-member-title">第 {{ index + 1 }} 回</span>
|
|
149
|
+
<input v-model="member.name" type="text" placeholder="名称(留空自动)" />
|
|
150
|
+
<label>颜色 <input v-model="member.color" type="color" /></label>
|
|
151
|
+
<button type="button" title="清空颜色(回到自动配色)" @click="member.color = ''">自动色</button>
|
|
152
|
+
<input v-model="member.width" type="number" min="0.5" step="0.5" placeholder="线宽" />
|
|
153
|
+
<input v-model="member.opacity" type="number" min="0" max="1" step="0.05" placeholder="不透明度" />
|
|
154
|
+
<input v-model="member.value" type="number" step="0.1" placeholder="max_loading_rate" />
|
|
155
|
+
</div>
|
|
156
|
+
<div class="demo-member-row">
|
|
157
|
+
<button type="button" @click="fillChannelMemberColors">逐回错开颜色</button>
|
|
158
|
+
<button type="button" @click="resetChannelMembers">清空逐条属性</button>
|
|
159
|
+
<span class="demo-control-hint">逐条属性与 createChannels 的 linePropsByMember 同名同义:草稿一路带到落地,程序化新增也认</span>
|
|
160
|
+
</div>
|
|
161
|
+
</div>
|
|
162
|
+
<label><input v-model="addChannelAutoCommit" type="checkbox" /> 选完两个节点直接落地</label>
|
|
163
|
+
<label><input v-model="addChannelHandoff" type="checkbox" /> 交接模式(选完两个节点自己调 addChannel 落地)</label>
|
|
164
|
+
<label><input v-model="addChannelContinuous" type="checkbox" /> 连续新增(落地后草稿重开,接着点下一对节点)</label>
|
|
165
|
+
<label><input v-model="addChannelChain" type="checkbox" /> 接着上一段的终点画</label>
|
|
166
|
+
<label class="demo-slider">
|
|
167
|
+
一次加几回
|
|
168
|
+
<select v-model.number="addChannelCircuits" title="新建通道时一次往这条通道里加几条回线;新建线路时是一次加几条独立线路">
|
|
169
|
+
<option v-for="count in 8" :key="count" :value="count">{{ count }} 回</option>
|
|
170
|
+
</select>
|
|
171
|
+
</label>
|
|
172
|
+
<button type="button" @click="beginAddChannel('channel')">新建通道(点两个节点)</button>
|
|
173
|
+
<button type="button" @click="beginAddChannel('line')">新建线路(独立、不挂通道)</button>
|
|
174
|
+
<button type="button" @click="continueAddChannel()">继续新增(开下一段)</button>
|
|
175
|
+
<button type="button" :disabled="!channelDraft" @click="cancelAddChannel">取消新增</button>
|
|
176
|
+
<button type="button" :disabled="!lastAddedChannel" @click="removeLastAdded">移除上一条新增</button>
|
|
177
|
+
<button type="button" @click="addChannelProgrammatic">程序化新增通道</button>
|
|
178
|
+
<button type="button" @click="addLineProgrammatic">程序化新增线路</button>
|
|
179
|
+
<span class="demo-control-hint">{{ channelDraftReadout }}</span>
|
|
180
|
+
</div>
|
|
181
|
+
<div class="demo-controls">
|
|
182
|
+
<details class="demo-hint-more"><summary>说明</summary><span class="demo-control-hint">新建通道(kind: 'channel'):两个节点之间没有通道就建一条,已有通道就变成新分组 / 并入某一组;「一次加几回」决定这一次往通道里加几条回线 —— 新通道 / 新分组 / 并入分组的余量都按它算,加不下的方案置灰(上限是 options.channelMaxGroups / channelGroupMaxLines)。新建线路(kind: 'line'):只加线路、不挂任何通道,两个节点相同才不允许。两者的草稿交互是同一套,onChannelDraft 载荷里的 kind 与 circuits 说明这一段在加什么,「继续新增」时还能换(continueAddChannel({ kind, circuits }))。勾上「交接模式」之后两个节点选完就先收起草稿(假通道消失),由 demo 自己在 onChannelDraft 的 ready 回调里调 addChannel 落地(面板的逐条属性走第二段 lineItems;与「选完两个节点直接落地」同时勾时后者先落地)。选完两个节点后,结束事件(ready)的读数(hasChannel / hasGroup / groupCount / groups / group / channel / existingChannelId)摆到下面「结束事件」那一行;旁边的「收掉假通道不新建」演示 endAddChannel:静默收掉示例假通道、数据不动、不补 cancel 事件</span></details>
|
|
183
|
+
</div>
|
|
184
|
+
<div class="demo-controls">
|
|
185
|
+
<span class="demo-control-hint">onChannelDraftClick(草稿里每点一次都发):{{ draftClickText }}</span>
|
|
186
|
+
<button type="button" :disabled="!channelDraft || channelDraft.phase !== 'ready'" @click="commitChannelDraft()">落地这一段(不挑方案)</button>
|
|
187
|
+
</div>
|
|
188
|
+
<div class="demo-controls">
|
|
189
|
+
<details class="demo-hint-more"><summary>说明</summary><span class="demo-control-hint">第一次点击拿到起点、第二次拿到终点(step 1 / 2),第二次之后线路结束:点下面的方案按钮落地(独立线路没有方案表,用上面的「落地这一段」),也可以提前「取消新增」退出草稿;「移除上一条新增」把刚落地的回线从数据里摘掉(一次加多回就是一批一起摘);连续新增落地时草稿原地重开(chain 时新起点就是上一段的终点),不用重新点「新建通道」</span></details>
|
|
190
|
+
</div>
|
|
191
|
+
<div class="demo-controls">
|
|
192
|
+
<span class="demo-control-hint">结束事件(beginAddChannel 的 onChannelDraft phase 'ready'):{{ channelReadyPayload ? `起点 ${String(channelReadyPayload.from.id)} → 终点 ${String(channelReadyPayload.to.id)}` : '还没走完一段(点两个节点之后这里摆出读数)' }}</span>
|
|
193
|
+
<span v-if="channelReadyPayload" class="demo-control-hint" data-demo="channel-ready">
|
|
194
|
+
hasChannel {{ channelReadyPayload.hasChannel }} · hasGroup {{ channelReadyPayload.hasGroup }} · {{ channelReadyPayload.groupCount }} 组
|
|
195
|
+
· 分组明细 {{ channelReadyPayload.groups.length ? channelReadyPayload.groups.map(group => `${String(group.id)}(${group.lineCount} 回)`).join(',') : '—' }}
|
|
196
|
+
· 当前分组 {{ channelReadyPayload.group ? String(channelReadyPayload.group.id) : '—' }}
|
|
197
|
+
· 通道 {{ channelReadyPayload.channel ? `${String(channelReadyPayload.channel.id)}(${channelReadyPayload.channel.lineIds.length} 回线)` : '—' }}
|
|
198
|
+
· existingChannelId {{ channelReadyPayload.existingChannelId ?? '—' }} / existingChannelIndex {{ channelReadyPayload.existingChannelIndex }}
|
|
199
|
+
</span>
|
|
200
|
+
<button type="button" data-demo="channel-ready-end" :disabled="!channelDraft || channelDraft.phase !== 'ready'" title="endAddChannel:静默收掉视图上的示例假通道 / 线路,数据不动、不补 cancel 事件" @click="endChannelDraftDemo">收掉假通道不新建(endAddChannel)</button>
|
|
201
|
+
</div>
|
|
202
|
+
<div v-if="channelDraftOptions.length" class="demo-controls">
|
|
203
|
+
<span class="demo-control-hint">点方案落地({{ channelDraft?.preferred ? `推荐 ${channelDraft.preferred}` : '没有推荐方案' }})· 两个节点之间的通道已有分组时:变成新分组 / 并入某一组,到上限的方案置灰</span>
|
|
204
|
+
<button v-for="option in channelDraftOptions" :key="option.type + '-' + String(option.groupId ?? option.channelId ?? '')" type="button" :disabled="!option.enabled" :title="option.reason ?? ''" @click="commitChannelDraft(option)">
|
|
205
|
+
{{ channelOptionLabel(option) }}{{ option.enabled ? '' : '(不可用)' }}
|
|
206
|
+
</button>
|
|
207
|
+
</div>
|
|
208
|
+
<div class="demo-controls">
|
|
209
|
+
<span class="demo-control-hint">通道右键交互框:在画布上右键任意一条通道回线,框里就是这条通道的组数 / 当前分组 / 分组列表与可用交互(统一的 onContextMenu 载荷里,通道上下文在 payload.channelContext);点空白处收框</span>
|
|
210
|
+
</div>
|
|
211
|
+
|
|
212
|
+
</div>
|
|
213
|
+
|
|
214
|
+
<div v-show="activePanel === 'data-filter'" class="demo-panel-body">
|
|
215
|
+
<div class="demo-controls">
|
|
216
|
+
<label class="demo-slider">
|
|
217
|
+
电压筛选
|
|
218
|
+
<select v-model="filterVoltage">
|
|
219
|
+
<option v-for="item in VOLTAGE_FILTERS" :key="item.value" :value="item.value">{{ item.label }}</option>
|
|
220
|
+
</select>
|
|
221
|
+
</label>
|
|
222
|
+
<label class="demo-slider">
|
|
223
|
+
站点类型
|
|
224
|
+
<select v-model="filterType">
|
|
225
|
+
<option value="all">全部类型</option>
|
|
226
|
+
<option v-for="type in STATION_TYPES" :key="type" :value="type">{{ type }}</option>
|
|
227
|
+
</select>
|
|
228
|
+
</label>
|
|
229
|
+
<label>名称包含 <input v-model="filterKeyword" type="text" placeholder="节点 / 站点名" /></label>
|
|
230
|
+
<label class="demo-slider">
|
|
231
|
+
节点被过滤
|
|
232
|
+
<select v-model="filterCascade">
|
|
233
|
+
<option v-for="item in CASCADE_MODES" :key="String(item.value)" :value="item.value">{{ item.label }}</option>
|
|
234
|
+
</select>
|
|
235
|
+
</label>
|
|
236
|
+
<label><input v-model="filterLines" type="checkbox" /> 线路也按电压过滤</label>
|
|
237
|
+
<button type="button" @click="clearFilterControls">清除筛选</button>
|
|
238
|
+
<span class="demo-control-hint">{{ filterReadout }}</span>
|
|
239
|
+
</div>
|
|
240
|
+
|
|
241
|
+
<div class="demo-controls">
|
|
242
|
+
<label class="demo-slider">
|
|
243
|
+
搜索
|
|
244
|
+
<input v-model="searchKeyword" type="text" placeholder="节点名 / 线路名 / 属性值" @keyup.enter="runSearch" />
|
|
245
|
+
</label>
|
|
246
|
+
<label class="demo-slider">
|
|
247
|
+
搜索范围
|
|
248
|
+
<select v-model="searchScope">
|
|
249
|
+
<option value="all">节点 + 线路 + 通道</option>
|
|
250
|
+
<option value="points">只看节点</option>
|
|
251
|
+
<option value="lines">只看线路</option>
|
|
252
|
+
<option value="channels">只看通道(含回线)</option>
|
|
253
|
+
</select>
|
|
254
|
+
</label>
|
|
255
|
+
<label class="demo-slider">
|
|
256
|
+
搜到就聚焦 + 选中
|
|
257
|
+
<input v-model="searchFocus" type="checkbox" />
|
|
258
|
+
</label>
|
|
259
|
+
<button type="button" @click="runSearch">搜索</button>
|
|
260
|
+
<button type="button" @click="searchKeyword = ''; searchReadout = ''">清空搜索</button>
|
|
261
|
+
<span class="demo-control-hint">{{ searchReadout || '搜索只返回结果、不动视角:聚焦与选中由这一页决定(右边的勾选框),要隐藏请用上面的筛选' }}</span>
|
|
262
|
+
</div>
|
|
263
|
+
|
|
264
|
+
</div>
|
|
265
|
+
|
|
266
|
+
<div v-show="activePanel === 'data-tools'" class="demo-panel-body">
|
|
267
|
+
<div class="demo-controls">
|
|
268
|
+
<button type="button" @click="viewRef?.fitView()">适应视图</button>
|
|
269
|
+
<button type="button" @click="viewRef?.zoomIn()">放大</button>
|
|
270
|
+
<button type="button" @click="viewRef?.zoomOut()">缩小</button>
|
|
271
|
+
<button type="button" @click="viewRef?.resetView()">重置</button>
|
|
272
|
+
<button type="button" @click="selectFirstLine">选中线路</button>
|
|
273
|
+
<button type="button" @click="selectChannelLine">选中 5 回线通道</button>
|
|
274
|
+
<button type="button" @click="selectSeveralNodes">多选 4 个节点</button>
|
|
275
|
+
<button type="button" @click="selectQuarterBox">选中左上 1/4</button>
|
|
276
|
+
<button type="button" @click="addWaypointToFirstLine">给首条线路加点</button>
|
|
277
|
+
<button type="button" @click="addWaypointToChannel">给通道加点</button>
|
|
278
|
+
<button type="button" @click="copyParallelGroupRecords">复制拐点集合</button>
|
|
279
|
+
<button type="button" @click="deselectFirstSelected">取消选中一个(deselect)</button>
|
|
280
|
+
<button type="button" @click="clearSelection">清空选中(deselect)</button>
|
|
281
|
+
<span class="demo-control-hint">{{ selectedLabel }}</span>
|
|
282
|
+
</div>
|
|
283
|
+
|
|
284
|
+
<div class="demo-controls">
|
|
285
|
+
<label class="demo-slider">
|
|
286
|
+
定向更新
|
|
287
|
+
<select v-model="targetedType" title="改一个节点 / 线路 / 通道并重渲染相关的视图">
|
|
288
|
+
<option value="point">节点(updatePoint)</option>
|
|
289
|
+
<option value="line">线路(updateLine)</option>
|
|
290
|
+
<option value="channel">通道(updateChannel)</option>
|
|
291
|
+
</select>
|
|
292
|
+
</label>
|
|
293
|
+
<button type="button" @click="updateTargeted">改一下并重渲染</button>
|
|
294
|
+
<span class="demo-control-hint">有选中就改选中的,没选中就改第一条;只重排受影响的那一小片(节点带着绑在它身上的线与锚定它的通道、线路只重排自己、通道按成员表比对),其余要素与缓存不动,鹰眼图与标签跟着重画</span>
|
|
295
|
+
</div>
|
|
296
|
+
|
|
297
|
+
<div class="demo-controls">
|
|
298
|
+
<span class="demo-control-hint">{{ parallelGroupsText }}</span>
|
|
299
|
+
<pre v-if="parallelGroupsJson" class="demo-groups">{{ parallelGroupsJson }}</pre>
|
|
300
|
+
</div>
|
|
301
|
+
|
|
302
|
+
</div>
|
|
303
|
+
</template>
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { useGisViewDemoContext } from '../demoContext.js'
|
|
3
|
+
const {
|
|
4
|
+
FEATURE_PRESET_OPTIONS, FEATURE_LABELS, featurePreset, featureState, featureText, applyFeaturePreset,
|
|
5
|
+
toggleFeature, historyEnabled, historyLimit, historyText, historyEventLabel, historySteps, applyHistoryOptions,
|
|
6
|
+
undoStep, redoStep, clearHistorySteps, QUALITY_OPTIONS, qualityMode, qualityText, warningText, movePointBatch,
|
|
7
|
+
perfText, perfStatsText, refreshPerfStats, runPerfBench, triggerWarning, eventLog, eventCountText, activePanel,
|
|
8
|
+
apiReadout, apiHint, probeApi, apiQuery, apiSection, apiPicked, apiEval, apiEvalResult, apiSectionTitles,
|
|
9
|
+
apiMemberCount, apiFiltered, apiVisibleCount, apiOptionsFiltered, pickApi, pickApiOption, apiEvalSample,
|
|
10
|
+
runApiEval, pluginReadout, mountRuntimePlugin, unmountRuntimePlugin, FEATURE_NAMES, API_SUMMARY,
|
|
11
|
+
} = useGisViewDemoContext()
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
<template>
|
|
15
|
+
<div v-show="activePanel === 'ops-quality'" class="demo-panel-body">
|
|
16
|
+
<div class="demo-controls">
|
|
17
|
+
<label class="demo-slider">
|
|
18
|
+
画质
|
|
19
|
+
<select v-model="qualityMode" title="画质档位:只改「画哪些批次 + 多大分辨率」,不重排场景;自动档按每帧渲染耗时升降(掉档快、升档慢)">
|
|
20
|
+
<option v-for="item in QUALITY_OPTIONS" :key="item.value" :value="item.value">{{ item.label }}</option>
|
|
21
|
+
</select>
|
|
22
|
+
</label>
|
|
23
|
+
<button type="button" @click="movePointBatch">批量移动 200 个节点(batch)</button>
|
|
24
|
+
<button type="button" @click="runPerfBench">跑一次性能压测</button>
|
|
25
|
+
<button type="button" @click="refreshPerfStats">刷新交互读数</button>
|
|
26
|
+
<button type="button" @click="triggerWarning">故意写错一个配置键(onWarning)</button>
|
|
27
|
+
</div>
|
|
28
|
+
<div class="demo-controls">
|
|
29
|
+
<span class="demo-control-hint">性能压测:{{ perfText }}</span>
|
|
30
|
+
</div>
|
|
31
|
+
<div class="demo-controls">
|
|
32
|
+
<span class="demo-control-hint">交互读数(getStats):{{ perfStatsText }}</span>
|
|
33
|
+
</div>
|
|
34
|
+
<div class="demo-controls">
|
|
35
|
+
<details class="demo-hint-more"><summary>说明</summary><span class="demo-control-hint">压测把几条路径当场量一遍:同样 500 次 <code>updatePoint</code>「逐条」与「放进 <code>batch()</code>」、500 次 <code>pick</code>、5 次默认全字段 <code>search</code>。用 <code>Date.now()</code> 量的是脚本占掉的墙钟时间,和 fps / frameMs 那种帧内耗时不是一回事;跑完数据回到原处(先往下挪 20、再挪回来)。切到 10 万节点档再按一次差距更明显:逐条那条路上每次改动都要重算一遍筛选、重排整屏标签,<code>batch()</code> 只在收尾落一次,筛选投影也按改动的那几条增量补写。</span></details>
|
|
36
|
+
</div>
|
|
37
|
+
<div class="demo-controls">
|
|
38
|
+
<span class="demo-control-hint">画质:{{ qualityText }}</span>
|
|
39
|
+
</div>
|
|
40
|
+
<div class="demo-controls">
|
|
41
|
+
<span class="demo-control-hint">提醒(onWarning):{{ warningText }}</span>
|
|
42
|
+
</div>
|
|
43
|
+
<div class="demo-controls">
|
|
44
|
+
<details class="demo-hint-more"><summary>说明</summary><span class="demo-control-hint">画质只决定「画哪些批次 + 用多大分辨率」:高(全开)→ 中(关光晕)→ 省(连阴影 / 高亮环一起关)→ 最快(再降到 0.75 倍分辨率),自动档量着每帧的渲染耗时在这几档之间移动 —— 掉档快(一格窗口超标就掉)、升档慢(连着两轮低于预算才升),免得在阈值上反复横跳;换档不重排场景、也不动数据,拖动时渲染吃紧也能保住跟手。批量更新(view.batch)把 N 次改动并成一条 onDataChange(type 为 batch,changes 按顺序列出每一步)与一步历史:渲染本来就按帧合并,省下的是回调与记录 —— 十万级数据下逐个调用,最贵的就是这两样。配置项的键写错、功能预设 / 档位拼错、订阅了不存在的事件名会走 onWarning(同一个错只提醒一次),直接点名怎么写才会生效,不进 onError、也不打断流程。</span></details>
|
|
45
|
+
</div>
|
|
46
|
+
<div class="demo-controls">
|
|
47
|
+
<label class="demo-slider">
|
|
48
|
+
功能开关
|
|
49
|
+
<select v-model="featurePreset" @change="applyFeaturePreset(featurePreset)">
|
|
50
|
+
<option v-for="item in FEATURE_PRESET_OPTIONS" :key="item.value" :value="item.value">{{ item.label }}</option>
|
|
51
|
+
</select>
|
|
52
|
+
</label>
|
|
53
|
+
<button type="button" @click="applyFeaturePreset('edit'); featurePreset = 'edit'">恢复全功能</button>
|
|
54
|
+
<span class="demo-control-hint">{{ featureText }}</span>
|
|
55
|
+
</div>
|
|
56
|
+
<div class="demo-controls demo-features">
|
|
57
|
+
<label v-for="name in FEATURE_NAMES" :key="name" class="demo-feature-toggle" :title="`features.${name}`">
|
|
58
|
+
<input type="checkbox" :checked="featureState[name]" @change="toggleFeature(name)" />
|
|
59
|
+
{{ FEATURE_LABELS[name] }}
|
|
60
|
+
</label>
|
|
61
|
+
</div>
|
|
62
|
+
<div class="demo-controls">
|
|
63
|
+
<label class="demo-slider">
|
|
64
|
+
<input v-model="historyEnabled" type="checkbox" @change="applyHistoryOptions" />
|
|
65
|
+
历史
|
|
66
|
+
</label>
|
|
67
|
+
<label class="demo-slider">
|
|
68
|
+
上限
|
|
69
|
+
<input v-model.number="historyLimit" type="number" min="0" max="500" step="10" :disabled="!historyEnabled" @change="applyHistoryOptions" />
|
|
70
|
+
条(0 = 不限)
|
|
71
|
+
</label>
|
|
72
|
+
<button type="button" :disabled="!historyEnabled" @click="undoStep">撤销一步</button>
|
|
73
|
+
<button type="button" :disabled="!historyEnabled" @click="redoStep">重做一步</button>
|
|
74
|
+
<button type="button" @click="clearHistorySteps">清空历史</button>
|
|
75
|
+
</div>
|
|
76
|
+
<div class="demo-controls">
|
|
77
|
+
<span class="demo-control-hint">{{ historyText }}</span>
|
|
78
|
+
</div>
|
|
79
|
+
<div class="demo-controls">
|
|
80
|
+
<span class="demo-control-hint">{{ historyEventLabel }}</span>
|
|
81
|
+
</div>
|
|
82
|
+
<ol v-if="historySteps.length" class="demo-step-list">
|
|
83
|
+
<li v-for="entry in historySteps" :key="`${entry.time}-${entry.type}-${entry.label}`">
|
|
84
|
+
<b>{{ entry.label ?? entry.type }}</b>
|
|
85
|
+
<span>{{ entry.type }}</span>
|
|
86
|
+
</li>
|
|
87
|
+
</ol>
|
|
88
|
+
<div class="demo-controls">
|
|
89
|
+
<span class="demo-control-hint">view.on('*') 订阅全部事件:{{ eventCountText }}</span>
|
|
90
|
+
</div>
|
|
91
|
+
<ul v-if="eventLog.length" class="demo-step-list demo-step-list--events">
|
|
92
|
+
<li v-for="item in eventLog" :key="item.id">
|
|
93
|
+
<b>{{ item.name }}</b>
|
|
94
|
+
<span>{{ item.text }}</span>
|
|
95
|
+
</li>
|
|
96
|
+
</ul>
|
|
97
|
+
<div class="demo-controls">
|
|
98
|
+
<details class="demo-hint-more"><summary>说明</summary><span class="demo-control-hint">开关只决定「组件做不做某个交互」,不改数据:切到「只读浏览」之后还能悬停、还能选中,只是拖不动;切到「静态图」指针与键盘都不响应,只留画布与标签 / 鹰眼图。历史记的是改动本身(哪几个下标、改前 / 改后),拖一次节点只占一条记录、撤掉也只回写那几个下标,十万级数据下仍然按实际改动量付费;上面的事件计数里 pointer / hover 涨得最快,正是「高频事件没人订阅就不分配载荷」的那几条。</span></details>
|
|
99
|
+
</div>
|
|
100
|
+
</div>
|
|
101
|
+
<div v-show="activePanel === 'ops-api'" class="demo-panel-body">
|
|
102
|
+
<div class="demo-controls">
|
|
103
|
+
<span class="demo-control-hint">这一版把「常用读数与定位」做成了实例方法:不用自己遍历数据,也不用手写投影换算。点一下就在当前数据上调一次,返回值写在下面(画布上右键空白处也能弹出画布菜单)。</span>
|
|
104
|
+
</div>
|
|
105
|
+
<div class="demo-controls demo-api-actions">
|
|
106
|
+
<button type="button" @click="probeApi('point')">getPoint(节点)</button>
|
|
107
|
+
<button type="button" @click="probeApi('line')">getLine(线路)</button>
|
|
108
|
+
<button type="button" @click="probeApi('channel')">getChannel(通道)</button>
|
|
109
|
+
<button type="button" @click="probeApi('listPoints')">listPoints({ limit: 5 })</button>
|
|
110
|
+
<button type="button" @click="probeApi('listLines')">listLines({ inView: true })</button>
|
|
111
|
+
<button type="button" @click="probeApi('bounds')">getElementBounds(选中)</button>
|
|
112
|
+
<button type="button" @click="probeApi('locate')">focusOn(选中, { maxZoom: 8 })</button>
|
|
113
|
+
<button type="button" @click="probeApi('contextAt')">getContextAt(光标处)</button>
|
|
114
|
+
<button type="button" @click="probeApi('viewState')">getViewState()</button>
|
|
115
|
+
</div>
|
|
116
|
+
<div class="demo-controls">
|
|
117
|
+
<span class="demo-control-hint">{{ apiHint }}</span>
|
|
118
|
+
<pre v-if="apiReadout" class="demo-groups">{{ apiReadout }}</pre>
|
|
119
|
+
</div>
|
|
120
|
+
<div class="demo-controls">
|
|
121
|
+
<span class="demo-control-hint">整份实例 API({{ API_SUMMARY.members }} 个成员:{{ API_SUMMARY.methods }} 个方法 + {{ API_SUMMARY.properties }} 个属性;另有 {{ API_SUMMARY.options }} 个 options 键)按文档的 12 个分组列全 —— 清单由 <code>node docs/steps/gen-api-index.mjs</code> 从 <code>src/gis-view/create.js</code> 与 <code>docs/GisView.md</code> 的两张表生成,<code>check-doc-coverage.mjs</code> 会对账,因此搜索框里的每一条都能在文档里查到逐个方法的参数与返回。搜不到想要的名字,多半是它还没写进文档。</span>
|
|
122
|
+
</div>
|
|
123
|
+
<div class="demo-controls demo-api-search">
|
|
124
|
+
<input v-model="apiQuery" type="search" placeholder="搜成员名 / 参数 / 返回 / 说明(例如 focusOn、通道、Promise、历史)" />
|
|
125
|
+
<select v-model="apiSection">
|
|
126
|
+
<option v-for="title in apiSectionTitles" :key="title" :value="title">{{ title }}</option>
|
|
127
|
+
</select>
|
|
128
|
+
<span class="demo-control-hint">{{ apiVisibleCount }} / {{ apiMemberCount }}</span>
|
|
129
|
+
</div>
|
|
130
|
+
<div class="demo-api-list">
|
|
131
|
+
<div v-for="section in apiFiltered" :key="section.title" class="demo-api-group">
|
|
132
|
+
<p class="demo-api-group-title">{{ section.title }}({{ section.items.length }})</p>
|
|
133
|
+
<button v-for="item in section.items" :key="item.name" type="button" class="demo-api-item" :class="{ 'is-picked': apiPicked && apiPicked.name === item.name }" @click="pickApi(item)">
|
|
134
|
+
<b>{{ item.name }}</b>
|
|
135
|
+
<span>{{ item.returns }}</span>
|
|
136
|
+
</button>
|
|
137
|
+
</div>
|
|
138
|
+
<p v-if="!apiVisibleCount" class="demo-control-hint">这个关键词没有命中任何成员(成员名要写英文,说明文字可以写中文)</p>
|
|
139
|
+
</div>
|
|
140
|
+
<details class="demo-hint-more demo-api-options">
|
|
141
|
+
<summary>options 速查({{ apiOptionsFiltered.length }} / {{ API_SUMMARY.options }} 个键,关键词与上面共用)</summary>
|
|
142
|
+
<div class="demo-api-list demo-api-list--options">
|
|
143
|
+
<button v-for="option in apiOptionsFiltered" :key="option.name" type="button" class="demo-api-item" :class="{ 'is-picked': apiPicked && apiPicked.name === option.name }" @click="pickApiOption(option)">
|
|
144
|
+
<b>{{ option.name }}</b>
|
|
145
|
+
<span>{{ option.defaultValue }}</span>
|
|
146
|
+
</button>
|
|
147
|
+
</div>
|
|
148
|
+
</details>
|
|
149
|
+
<div v-if="apiPicked" class="demo-controls demo-api-detail">
|
|
150
|
+
<span class="demo-control-hint"><strong>{{ apiPicked.name }}</strong>({{ apiPicked.kind === 'property' ? '属性' : apiPicked.kind === 'option' ? 'options 键' : '方法' }})· 返回 {{ apiPicked.returns }}</span>
|
|
151
|
+
<span class="demo-control-hint">参数:{{ apiPicked.params || '无' }}</span>
|
|
152
|
+
<span class="demo-control-hint">{{ apiPicked.doc }}</span>
|
|
153
|
+
</div>
|
|
154
|
+
<div class="demo-controls demo-api-eval">
|
|
155
|
+
<input v-model="apiEval" type="text" spellcheck="false" placeholder="在当前实例上求值:view.getStats()" @keydown.enter="runApiEval" />
|
|
156
|
+
<button type="button" @click="runApiEval">求值</button>
|
|
157
|
+
<button type="button" @click="apiEvalSample">示例</button>
|
|
158
|
+
</div>
|
|
159
|
+
<div class="demo-controls">
|
|
160
|
+
<span class="demo-control-hint">求值就是 <code>new Function('view', 'return (表达式)')(view)</code>:点上面的成员会把 <code>view.名字</code> 填进来,接着补参数即可(改了数据的调用会照常发事件、记历史 —— 想试就用读数类的方法)。</span>
|
|
161
|
+
<pre v-if="apiEvalResult" class="demo-groups">{{ apiEvalResult }}</pre>
|
|
162
|
+
</div>
|
|
163
|
+
<div class="demo-controls">
|
|
164
|
+
<span class="demo-control-hint">运行时插件:view.use(plugin) 与 options.plugins 同一套写法,调用即执行、返回卸载函数;插件自己的 destroy 在「卸载」或 view.destroy() 时回调。这个示例插件只订阅 selectChange 记账。</span>
|
|
165
|
+
</div>
|
|
166
|
+
<div class="demo-controls demo-api-actions">
|
|
167
|
+
<button type="button" @click="mountRuntimePlugin">use(插件)</button>
|
|
168
|
+
<button type="button" @click="unmountRuntimePlugin">卸载插件</button>
|
|
169
|
+
</div>
|
|
170
|
+
<div class="demo-controls">
|
|
171
|
+
<span class="demo-control-hint">{{ pluginReadout }}</span>
|
|
172
|
+
</div>
|
|
173
|
+
</div>
|
|
174
|
+
</template>
|