Parcourir la source

refactor(架构调整): 完成特制docs repl定制组件制作

gemercheung il y a 2 ans
Parent
commit
852ff20bce

+ 28 - 0
docs/.vitepress/config/plugins.ts

@@ -20,6 +20,7 @@ interface ContainerOpts {
 export const mdPlugin = (md: MarkdownIt) => {
     md.use(externalLinkIcon)
     md.use(tableWrapper)
+    // demo apply
     md.use(mdContainer, 'demo', {
         validate(params) {
             return !!params.trim().match(/^demo\s*(.*)$/)
@@ -46,4 +47,31 @@ export const mdPlugin = (md: MarkdownIt) => {
             }
         },
     } as ContainerOpts)
+    // repl apply
+    md.use(mdContainer, 'repl', {
+        validate(params) {
+            return !!params.trim().match(/^repl\s*(.*)$/)
+        },
+
+        render(tokens, idx) {
+            const m = tokens[idx].info.trim().match(/^repl\s*(.*)$/)
+            if (tokens[idx].nesting === 1 /* means the tag is opening */) {
+                const description = m && m.length > 1 ? m[1] : ''
+                const sourceFileToken = tokens[idx + 2]
+                let source = ''
+                const sourceFile = sourceFileToken.children?.[0].content ?? ''
+
+                if (sourceFileToken.type === 'inline') {
+                    source = fs.readFileSync(path.resolve(docRoot, 'examples', `${sourceFile}.vue`), 'utf-8')
+                }
+                if (!source) throw new Error(`Incorrect source file: ${sourceFile}`)
+
+                return `<Demo isRepl :demos="demos" source="${encodeURIComponent(highlight(source, 'vue'))}" path="${sourceFile}" raw-source="${encodeURIComponent(
+                    source
+                )}" description="${encodeURIComponent(localMd.render(description))}">`
+            } else {
+                return '</Demo>'
+            }
+        },
+    } as ContainerOpts)
 }

+ 13 - 6
docs/.vitepress/vitepress/components/demo/vp-example.vue

@@ -24,6 +24,11 @@ const props = defineProps({
         type: Object,
         required: true,
     },
+    isRepl: {
+        type: Boolean,
+        required: false,
+        default: () => false,
+    },
 })
 
 const loadSingleData = computed(() => {
@@ -68,8 +73,10 @@ store.state.mainFile = 'PlaygroundMain.vue'
 <template>
     <div class="example-showcase" antialiased>
         <ClientOnly>
-            <!-- <component :is="demo" v-if="demo" v-bind="$attrs" /> -->
-            <Repl :store="store" :sfc-options="sfcOptions" :clear-console="false" :show-compile-output="false" auto-resize />
+            <template v-if="demo">
+                <component :is="demo" v-if="!isRepl" v-bind="$attrs" />
+                <Repl v-else :store="store" :sfc-options="sfcOptions" :clear-console="false" :show-compile-output="false" auto-resize />
+            </template>
         </ClientOnly>
     </div>
 </template>
@@ -83,15 +90,15 @@ store.state.mainFile = 'PlaygroundMain.vue'
 </style>
 <style lang="scss">
 .vue-repl {
-    height: 600px;
+    height: 650px;
     .left {
         display: none;
     }
     .right {
         width: 100% !important;
     }
-    .tab-buttons {
-        display: none;
-    }
+    // .tab-buttons {
+    //     display: none;
+    // }
 }
 </style>

+ 0 - 49
docs/.vitepress/vitepress/components/demo/vp-frameRender.ts

@@ -1,49 +0,0 @@
-//@ts-nocheck
-import { createApp, defineComponent, h, onBeforeUpdate, onMounted, ref } from 'vue'
-
-// eslint-disable-next-line vue/one-component-per-file
-export default defineComponent({
-    name: 'RenderToIFrame',
-    props: {
-        css: {
-            type: String,
-            default: '',
-        },
-    },
-    setup(props, { slots }) {
-        const iframeRef = ref<HTMLElement | null>(null)
-        const iframeBody = ref<HTMLElement | null>(null)
-        const iframeHead = ref(null)
-        const iframeStyle = ref(null)
-        let iframeApp = null
-
-        onMounted(() => {
-            iframeBody.value = iframeRef.value.contentDocument.body
-            iframeHead.value = iframeRef.value.contentDocument.head
-            const el = document.createElement('div')
-            iframeRef.value?.classList.add('playground-iframe')
-            el.id = 'app'
-            iframeBody.value.appendChild(el)
-            iframeStyle.value = document.createElement('style')
-            iframeStyle.value.innerHTML = props.css
-            iframeHead.value.appendChild(iframeStyle.value)
-
-            // eslint-disable-next-line vue/one-component-per-file
-            iframeApp = createApp({
-                name: 'IframeRender',
-                setup() {
-                    return () => slots.default()
-                },
-            }).mount(el)
-        })
-        onBeforeUpdate(() => {
-            if (!iframeApp || !iframeRef.value) {
-                return
-            }
-            if (props.css) {
-                iframeStyle.value.innerHTML = props.css
-            }
-        })
-        return () => h('iframe', { ref: iframeRef })
-    },
-})

+ 2 - 2
docs/.vitepress/vitepress/components/vp-demo.vue

@@ -11,7 +11,6 @@ import demoBlockLocale from '../../i18n/component/demo-block.json'
 import Example from './demo/vp-example.vue'
 import SourceCode from './demo/vp-source-code.vue'
 import '@vue/repl/style.css'
-import '../composables/dept'
 
 const props = defineProps<{
     demos: object
@@ -19,6 +18,7 @@ const props = defineProps<{
     path: string
     rawSource: string
     description?: string
+    isRepl?: boolean
 }>()
 
 const vm = getCurrentInstance()!
@@ -71,7 +71,7 @@ const copyCode = async () => {
         <p text="sm" v-html="decodedDescription" />
 
         <div class="example">
-            <Example :file="path" :demo="formatPathDemos[path]" :raw="rawSource" />
+            <Example :file="path" :demo="formatPathDemos[path]" :raw="rawSource" :is-repl="isRepl" />
             <ElDivider class="m-0" />
 
             <div class="op-btns">

+ 0 - 32
docs/.vitepress/vitepress/composables/dept.ts

@@ -1,32 +0,0 @@
-await loadSDKDep()
-await loadSDK()
-await loadKanKanThemeChalkStyle()
-export function loadSDKDep() {
-    return new Promise((resolve, reject) => {
-        const script = document.createElement('script')
-        script.src = '//4dkk.4dage.com/v4-test/www/sdk/kankan-sdk-deps.js?v=4.6.0-alpha.10'
-        script.addEventListener('load', resolve)
-        script.addEventListener('error', reject)
-        document.body.append(script)
-    })
-}
-
-export function loadSDK() {
-    return new Promise((resolve, reject) => {
-        const script = document.createElement('script')
-        script.src = '//4dkk.4dage.com/v4-test/www/sdk/kankan-sdk.js?v=4.6.0-alpha.10'
-        script.addEventListener('load', resolve)
-        script.addEventListener('error', reject)
-        document.body.append(script)
-    })
-}
-export function loadKanKanThemeChalkStyle() {
-    return new Promise((resolve, reject) => {
-        const link = document.createElement('link')
-        link.rel = 'stylesheet'
-        link.href = 'https://4dkk.4dage.com/npm_test/kankan-components/theme-chalk/index.css'
-        link.addEventListener('load', resolve)
-        link.addEventListener('error', reject)
-        document.body.append(link)
-    })
-}

+ 1 - 0
docs/.vitepress/vitepress/index.ts

@@ -15,6 +15,7 @@ import 'uno.css'
 
 import VPApp from './components/vp-app.vue'
 import VPDemo from './components/vp-demo.vue'
+
 import IconList from './components/globals/icons.vue'
 
 import type { Component } from 'vue'

+ 2 - 0
docs/components.d.ts

@@ -63,10 +63,12 @@ declare module '@vue/runtime-core' {
         VpChangelog: typeof import('./.vitepress/vitepress/components/globals/vp-changelog.vue')['default']
         VpContent: typeof import('./.vitepress/vitepress/components/vp-content.vue')['default']
         VpDemo: typeof import('./.vitepress/vitepress/components/vp-demo.vue')['default']
+        'VpDemo copy': typeof import('./.vitepress/vitepress/components/vp-demo copy.vue')['default']
         VpDocContent: typeof import('./.vitepress/vitepress/components/vp-doc-content.vue')['default']
         VpEditLink: typeof import('./.vitepress/vitepress/components/doc-content/vp-edit-link.vue')['default']
         VpExample: typeof import('./.vitepress/vitepress/components/demo/vp-example.vue')['default']
         VpFooter: typeof import('./.vitepress/vitepress/components/globals/vp-footer.vue')['default']
+        VpGemer: typeof import('./.vitepress/vitepress/components/vp-gemer.vue')['default']
         VpHamburger: typeof import('./.vitepress/vitepress/components/navbar/vp-hamburger.vue')['default']
         VpHeroContent: typeof import('./.vitepress/vitepress/components/vp-hero-content.vue')['default']
         VpLastUpdatedAt: typeof import('./.vitepress/vitepress/components/doc-content/vp-last-updated-at.vue')['default']

+ 1 - 12
docs/examples/tag/basic.vue

@@ -38,17 +38,6 @@ const handleTagview = ({ id }) => {
             <div xui_tags_view>
                 <UITag v-for="(item, index) in tags" :key="index" :tag="item" @click="handleTagview" />
             </div>
-            <!-- <div xui_tags_view>
-        <UITag v-for="(item, index) in tags" :key="index" :tag="item">
-          <template #content="{ data, id, isClick, isShow, x, y }">
-            <div>id:{{ id }}</div>
-            <div>isClick:{{ isClick }}</div>
-            <div>isShow:{{ isShow }}</div>
-            <div>x:{{ x }}</div>
-            <div>y:{{ y }}</div>
-          </template>
-        </UITag>
-      </div> -->
         </Teleport>
     </div>
 </template>
@@ -63,7 +52,7 @@ body,
 }
 .scene {
     width: 100%;
-    height: 600px;
+    height: 100%;
     padding: 0;
     margin: 0;
 }

+ 1 - 1
docs/examples/tag/custom.vue

@@ -60,7 +60,7 @@ body,
 }
 .scene {
     width: 100%;
-    height: 600px;
+    height: 100%;
     padding: 0;
     margin: 0;
 }

+ 2 - 2
docs/zh-CN/component/tag.md

@@ -9,7 +9,7 @@ Tags 热点使用如下。
 
 ## 基本用法
 
-:::demo
+:::repl
 
 tag/basic
 
@@ -17,7 +17,7 @@ tag/basic
 
 ## 定制 Slot
 
-:::demo
+:::repl
 
 tag/custom