|
1 | 1 | <template> |
2 | | - <FDrawer v-model:show="isShow" title="Playground" displayDirective="show" width="90%" @ok="isShow = false"> |
3 | | - <Repl :store="store" :showImportMap="true" :showCompileOutput="false" :clearConsole="false" /> |
4 | | - </FDrawer> |
| 2 | + <FDrawer v-model:show="isShow" title="Playground" displayDirective="show" width="90%" @ok="isShow = false" |
| 3 | + > |
| 4 | + <Repl |
| 5 | + v-if="props.codeName" |
| 6 | + :editor="CodeMirror" |
| 7 | + :store="store" |
| 8 | + :show-ts-config="false" |
| 9 | + :show-import-map="true" |
| 10 | + :show-compile-output="false" |
| 11 | + :clear-console="false" |
| 12 | + /> |
| 13 | + </FDrawer> |
5 | 14 | </template> |
6 | | -<script setup lang="ts"> |
7 | | -import { |
8 | | - version, |
9 | | - watch, |
10 | | - ref |
11 | | -} from 'vue'; |
| 15 | + |
| 16 | +<script setup> |
| 17 | +import { ref, version, watch } from 'vue'; |
| 18 | +
|
| 19 | +import CodeMirror from '@vue/repl/codemirror-editor'; |
| 20 | +import { Repl, ReplStore } from '@vue/repl'; |
12 | 21 |
|
13 | 22 | import { FDrawer } from '@fesjs/fes-design'; |
14 | | -import { |
15 | | - Repl, |
16 | | - ReplStore |
17 | | -} from '@vue/repl'; |
18 | | -import data from './demoCode.json'; |
19 | | -import '@vue/repl/style.css'; |
| 23 | +import { DEMO_ENTRY_FILE, FES_DESIGN_SETUP } from './constants'; |
20 | 24 |
|
21 | 25 | const props = defineProps({ |
22 | | - codeName: String |
| 26 | + codeName: String, |
| 27 | + codeSrc: String, |
23 | 28 | }); |
24 | | -
|
25 | | -const mainFile = 'App.vue'; |
26 | | -const demoFile = 'demo.vue'; |
| 29 | +const mainFile = 'src/App.vue'; |
| 30 | +const demoFile = 'src/demo.vue'; |
27 | 31 |
|
28 | 32 | const store = new ReplStore({ |
29 | | - defaultVueRuntimeURL: `https://npm.elemecdn.com/vue@${version}/dist/vue.esm-browser.js` |
| 33 | + defaultVueRuntimeURL: `https://registry.npmmirror.com/vue/${version}/files/dist/vue.esm-browser.js`, |
30 | 34 | }); |
31 | 35 |
|
32 | | -const fesDesignSetup = ` |
33 | | - // 不要修改此文件!!! |
34 | | - import { getCurrentInstance } from 'vue'; |
35 | | - import Space from './space.vue'; |
36 | | - import FesDesign from '@fesjs/fes-design'; |
37 | | - import * as Icons from '@fesjs/fes-design/icon'; |
38 | | - export function loadStyle() { |
39 | | - const hasLinks = document.querySelectorAll('link'); |
40 | | - for(let l of hasLinks) { |
41 | | - if (/fes-design.min.css/.test(l.href)) return; |
42 | | - } |
43 | | - |
44 | | - const link = document.createElement('link') |
45 | | - link.rel = 'stylesheet' |
46 | | - link.href = 'https://npm.elemecdn.com/@fesjs/fes-design@latest/dist/fes-design.min.css'; |
47 | | - document.head.appendChild(link) |
48 | | - const twcsslink = document.createElement('link') |
49 | | - twcsslink.rel = 'stylesheet' |
50 | | - twcsslink.href = 'https://cdn.jsdelivr.net/npm/@fesjs/traction-widget/dist/traction-widget.min.css'; |
51 | | - document.head.appendChild(twcsslink) |
52 | | - } |
53 | | - |
54 | | - export function setupFesDesign() { |
55 | | - loadStyle(); |
56 | | - const instance = getCurrentInstance() |
57 | | - instance.appContext.app.use(FesDesign); |
58 | | - Object.keys(Icons).forEach((iconName) => { |
59 | | - instance.appContext.app.component(iconName, Icons[iconName]); |
60 | | - }); |
61 | | - instance.appContext.app.component('Space', Space) |
62 | | - } |
63 | | - `; |
64 | | -
|
65 | | -function resolveSFCExample (demo) { |
66 | | - |
67 | | - const files = { |
68 | | - [mainFile]: data.app, |
69 | | - 'space.vue': data.space, |
70 | | - [demoFile]: data[demo], |
71 | | - 'fes-design.js': fesDesignSetup, |
72 | | - 'import-map.json': JSON.stringify({ |
73 | | - imports: { |
74 | | - '@fesjs/fes-design': 'https://npm.elemecdn.com/@fesjs/fes-design@latest/dist/fes-design.esm-browser.js', |
75 | | - '@fesjs/fes-design/icon': 'https://npm.elemecdn.com/@fesjs/fes-design@latest/dist/fes-design.icon-browser.js', |
76 | | - '@fesjs/traction-widget': 'https://cdn.jsdelivr.net/npm/@fesjs/traction-widget/dist/traction-widget.esm-browser.js' |
77 | | - } |
78 | | - }) |
79 | | - }; |
80 | | - return files; |
| 36 | +const defaultFiles = { |
| 37 | + [mainFile]: DEMO_ENTRY_FILE, |
| 38 | + 'src/fes-design.js': FES_DESIGN_SETUP, |
| 39 | + 'import-map.json': JSON.stringify({ |
| 40 | + imports: { |
| 41 | + '@fesjs/fes-design': |
| 42 | + 'https://registry.npmmirror.com/@fesjs/fes-design/latest/files/dist/fes-design.esm-browser.js', |
| 43 | + '@fesjs/fes-design/icon': |
| 44 | + 'https://registry.npmmirror.com/@fesjs/fes-design/latest/files/dist/fes-design.icon-browser.js', |
| 45 | + '@fesjs/traction-widget': |
| 46 | + 'https://cdn.jsdelivr.net/npm/@fesjs/traction-widget/dist/traction-widget.esm-browser.js' |
| 47 | + }, |
| 48 | + }), |
| 49 | +}; |
| 50 | +store.setFiles(defaultFiles); |
| 51 | +store.setActive(mainFile); |
| 52 | +function resolveSFCExample(codeSrc) { |
| 53 | + defaultFiles[demoFile] = codeSrc; |
| 54 | + return defaultFiles; |
81 | 55 | } |
82 | 56 |
|
83 | | -function updateExample (fileName) { |
84 | | - store.setFiles(resolveSFCExample(fileName), mainFile).then(() => { |
| 57 | +function updateExample(codeSrc) { |
| 58 | + store.setFiles(resolveSFCExample(codeSrc), mainFile).then(() => { |
85 | 59 | store.setActive(demoFile); |
86 | 60 | }); |
87 | 61 | } |
88 | 62 |
|
| 63 | +watch( |
| 64 | + () => props.codeSrc, |
| 65 | + () => { |
| 66 | + updateExample(decodeURIComponent(props.codeSrc)); |
| 67 | + }, |
| 68 | + { |
| 69 | + immediate: true, |
| 70 | + }, |
| 71 | +); |
| 72 | +
|
89 | 73 | const isShow = ref(true); |
90 | | -const handleShow = (val) => { |
| 74 | +function handleShow(val) { |
91 | 75 | isShow.value = val; |
92 | | -}; |
93 | | -
|
| 76 | +} |
94 | 77 | defineExpose({ |
95 | 78 | isShow, |
96 | | - handleShow |
97 | | -}); |
98 | | -
|
99 | | -watch(() => props.codeName, () => { |
100 | | - updateExample(props.codeName); |
101 | | -}, { |
102 | | - immediate: true |
| 79 | + handleShow, |
103 | 80 | }); |
104 | 81 | </script> |
105 | | -<style lang="less" scoped> |
| 82 | + |
| 83 | +<style lang="less"> |
106 | 84 | .vue-repl { |
107 | | - border-right: 1px solid var(--vt-c-divider-light); |
108 | | - height: calc(100vh - 88px); |
| 85 | + border-right: 1px solid var(--vt-c-divider-light); |
| 86 | + height: calc(100vh - 55px); // 55px 是 drawer header 的宽度 |
| 87 | +} |
| 88 | +
|
| 89 | +.fes-repl-drawer-content { |
| 90 | + .fes-drawer-body-container { |
| 91 | + padding-top: 0; |
| 92 | + padding-right: 0; |
| 93 | + padding-bottom: 0; |
| 94 | + } |
109 | 95 | } |
110 | 96 | </style> |
0 commit comments