Răsfoiți Sursa

fix: add an example of markdown embedded in the form #138

vben 4 ani în urmă
părinte
comite
7db0c5c49f

+ 1 - 0
CHANGELOG.zh_CN.md

@@ -4,6 +4,7 @@
 
 - 新增 `v-ripple`水波纹指令
 - 新增左侧菜单混合模式
+- 新增 markdown 嵌入表单内示例
 
 ### 🐛 Bug Fixes
 

+ 1 - 0
src/components/Container/src/ScrollContainer.vue

@@ -4,6 +4,7 @@
     :wrapClass="`scrollbar__wrap`"
     :viewClass="`scrollbar__view`"
     class="scroll-container"
+    v-bind="$attrs"
   >
     <slot />
   </Scrollbar>

+ 53 - 11
src/components/Markdown/src/index.vue

@@ -2,14 +2,25 @@
   <div class="markdown" ref="wrapRef" />
 </template>
 <script lang="ts">
-  import { defineComponent, ref, onMounted, unref, onUnmounted, nextTick, watchEffect } from 'vue';
+  import {
+    defineComponent,
+    ref,
+    onMounted,
+    unref,
+    onUnmounted,
+    nextTick,
+    // watch,
+    computed,
+  } from 'vue';
   import Vditor from 'vditor';
   import 'vditor/dist/index.css';
 
   import { propTypes } from '/@/utils/propTypes';
+  import { useLocale } from '/@/hooks/web/useLocale';
 
+  type Lang = 'zh_CN' | 'en_US' | 'ja_JP' | 'ko_KR' | undefined;
   export default defineComponent({
-    emits: ['update:value'],
+    emits: ['change'],
     props: {
       height: propTypes.number.def(360),
       value: propTypes.string.def(''),
@@ -19,17 +30,42 @@
       const vditorRef = ref<Nullable<Vditor>>(null);
       const initedRef = ref(false);
 
+      const lang = ref<Lang>();
+
+      const { getLang } = useLocale();
+
+      const getCurrentLang = computed((): 'zh_CN' | 'en_US' | 'ja_JP' | 'ko_KR' => {
+        switch (unref(getLang)) {
+          case 'en':
+            lang.value = 'en_US';
+            break;
+          case 'ja':
+            lang.value = 'ja_JP';
+            break;
+          case 'ko':
+            lang.value = 'ko_KR';
+            break;
+          default:
+            lang.value = 'zh_CN';
+        }
+        return lang.value;
+      });
       function init() {
         const wrapEl = unref(wrapRef);
         if (!wrapEl) return;
         const bindValue = { ...attrs, ...props };
         vditorRef.value = new Vditor(wrapEl, {
+          lang: unref(getCurrentLang),
           mode: 'sv',
           preview: {
             actions: [],
           },
           input: (v) => {
-            emit('update:value', v);
+            // emit('update:value', v);
+            emit('change', v);
+          },
+          blur: () => {
+            unref(vditorRef)?.setValue(props.value);
           },
           ...bindValue,
           cache: {
@@ -39,14 +75,20 @@
         initedRef.value = true;
       }
 
-      watchEffect(() => {
-        nextTick(() => {
-          const vditor = unref(vditorRef);
-          if (unref(initedRef) && props.value && vditor) {
-            vditor.setValue(props.value);
-          }
-        });
-      });
+      // watch(
+      //   () => props.value,
+      //   () => {
+      //     nextTick(() => {
+      //       const vditor = unref(vditorRef);
+      //       if (unref(initedRef) && props.value && vditor) {
+      //         vditor.setValue(props.value);
+      //       }
+      //     });
+      //   },
+      //   {
+      //     immediate: true,
+      //   }
+      // );
 
       onMounted(() => {
         nextTick(() => {

+ 1 - 1
src/components/Scrollbar/index.ts

@@ -5,7 +5,7 @@
 import { withInstall } from '../util';
 
 import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent';
-export const Scrollbar = createAsyncComponent(() => import('./src/Scrollbar'));
+export const Scrollbar = createAsyncComponent(() => import('./src/index.vue'));
 
 withInstall(Scrollbar);
 

+ 0 - 106
src/components/Scrollbar/src/Bar.tsx

@@ -1,106 +0,0 @@
-import type { PropType } from 'vue';
-
-import { renderThumbStyle, BAR_MAP } from './util';
-import { defineComponent, computed, unref, inject, Ref, reactive, ref, onBeforeUnmount } from 'vue';
-import { on, off } from '/@/utils/domUtils';
-
-export default defineComponent({
-  name: 'Bar',
-  props: {
-    vertical: {
-      type: Boolean as PropType<boolean>,
-      default: false,
-    },
-    size: String as PropType<string>,
-    move: Number as PropType<number>,
-  },
-  setup(props) {
-    const thumbRef = ref<Nullable<HTMLDivElement>>(null);
-    const elRef = ref<Nullable<HTMLDivElement>>(null);
-    const commonState = reactive<Indexable>({});
-    const getBarRef = computed(() => {
-      return BAR_MAP[props.vertical ? 'vertical' : 'horizontal'];
-    });
-    const parentElRef = inject('scroll-bar-wrap') as Ref<Nullable<HTMLDivElement>>;
-
-    function clickThumbHandler(e: any) {
-      const { ctrlKey, button, currentTarget } = e;
-      // prevent click event of right button
-      if (ctrlKey || button === 2 || !currentTarget) {
-        return;
-      }
-      startDrag(e);
-      const bar = unref(getBarRef);
-      commonState[bar.axis] =
-        currentTarget[bar.offset] -
-        (e[bar.client as keyof typeof e] - currentTarget.getBoundingClientRect()[bar.direction]);
-    }
-
-    function clickTrackHandler(e: any) {
-      const bar = unref(getBarRef);
-      const offset = Math.abs(e.target.getBoundingClientRect()[bar.direction] - e[bar.client]);
-      const thumbEl = unref(thumbRef) as any;
-      const parentEl = unref(parentElRef) as any;
-      const el = unref(elRef) as any;
-      if (!thumbEl || !el || !parentEl) return;
-      const thumbHalf = thumbEl[bar.offset] / 2;
-      const thumbPositionPercentage = ((offset - thumbHalf) * 100) / el[bar.offset];
-      parentEl[bar.scroll] = (thumbPositionPercentage * parentEl[bar.scrollSize]) / 100;
-    }
-
-    function startDrag(e: Event) {
-      e.stopImmediatePropagation();
-      commonState.cursorDown = true;
-
-      on(document, 'mousemove', mouseMoveDocumentHandler);
-      on(document, 'mouseup', mouseUpDocumentHandler);
-      document.onselectstart = () => false;
-    }
-
-    function mouseMoveDocumentHandler(e: any) {
-      if (commonState.cursorDown === false) return;
-      const bar = unref(getBarRef);
-      const prevPage = commonState[bar.axis];
-      const el = unref(elRef) as any;
-      const parentEl = unref(parentElRef) as any;
-      const thumbEl = unref(thumbRef) as any;
-      if (!prevPage || !el || !thumbEl || !parentEl) return;
-      const rect = el.getBoundingClientRect() as any;
-      const offset = (rect[bar.direction] - e[bar.client]) * -1;
-      const thumbClickPosition = thumbEl[bar.offset] - prevPage;
-      const thumbPositionPercentage = ((offset - thumbClickPosition) * 100) / el[bar.offset];
-
-      parentEl[bar.scroll] = (thumbPositionPercentage * parentEl[bar.scrollSize]) / 100;
-    }
-
-    function mouseUpDocumentHandler() {
-      const bar = unref(getBarRef);
-      commonState.cursorDown = false;
-      commonState[bar.axis] = 0;
-      off(document, 'mousemove', mouseMoveDocumentHandler);
-      document.onselectstart = null;
-    }
-
-    onBeforeUnmount(() => {
-      off(document, 'mouseup', mouseUpDocumentHandler);
-    });
-    return () => {
-      const bar = unref(getBarRef);
-      const { size, move } = props;
-      return (
-        <div
-          class={['scrollbar__bar', 'is-' + bar.key]}
-          onMousedown={clickTrackHandler}
-          ref={elRef}
-        >
-          <div
-            ref={thumbRef}
-            class="scrollbar__thumb"
-            onMousedown={clickThumbHandler}
-            style={renderThumbStyle({ size, move, bar })}
-          />
-        </div>
-      );
-    };
-  },
-});

+ 0 - 146
src/components/Scrollbar/src/Scrollbar.tsx

@@ -1,146 +0,0 @@
-import { addResizeListener, removeResizeListener } from '/@/utils/event/resizeEvent';
-import scrollbarWidth from '/@/utils/scrollbarWidth';
-import { toObject } from './util';
-import Bar from './Bar';
-import { isString } from '/@/utils/is';
-import {
-  defineComponent,
-  PropType,
-  unref,
-  reactive,
-  ref,
-  provide,
-  onMounted,
-  nextTick,
-  onBeforeUnmount,
-} from 'vue';
-import { getSlot } from '/@/utils/helper/tsxHelper';
-import './index.less';
-import { useExpose } from '/@/hooks/core/useExpose';
-import { ScrollbarType } from './types';
-
-export default defineComponent({
-  name: 'Scrollbar',
-  props: {
-    native: Boolean as PropType<boolean>,
-    wrapStyle: {
-      type: Object as PropType<any>,
-    },
-    wrapClass: { type: String as PropType<string>, required: false },
-    viewClass: { type: String as PropType<string> },
-    viewStyle: { type: Object as PropType<any> },
-    noresize: Boolean as PropType<boolean>,
-    tag: {
-      type: String as PropType<string>,
-      default: 'div',
-    },
-  },
-  setup(props, { slots }) {
-    const resizeRef = ref<Nullable<HTMLDivElement>>(null);
-    const wrapElRef = ref<Nullable<HTMLDivElement>>(null);
-    provide('scroll-bar-wrap', wrapElRef);
-    const state = reactive({
-      sizeWidth: '0',
-      sizeHeight: '0',
-      moveX: 0,
-      moveY: 0,
-    });
-
-    function handleScroll() {
-      const warpEl = unref(wrapElRef);
-      if (!warpEl) return;
-      const { scrollTop, scrollLeft, clientHeight, clientWidth } = warpEl;
-
-      state.moveY = (scrollTop * 100) / clientHeight;
-      state.moveX = (scrollLeft * 100) / clientWidth;
-    }
-    function update() {
-      const warpEl = unref(wrapElRef);
-      if (!warpEl) return;
-      const { scrollHeight, scrollWidth, clientHeight, clientWidth } = warpEl;
-      const heightPercentage = (clientHeight * 100) / scrollHeight;
-      const widthPercentage = (clientWidth * 100) / scrollWidth;
-
-      state.sizeHeight = heightPercentage < 100 ? heightPercentage + '%' : '';
-      state.sizeWidth = widthPercentage < 100 ? widthPercentage + '%' : '';
-    }
-
-    onMounted(() => {
-      useExpose<ScrollbarType>({
-        wrap: unref(wrapElRef),
-      });
-      const { native, noresize } = props;
-      const resizeEl = unref(resizeRef);
-      const warpEl = unref(wrapElRef);
-      if (native || !resizeEl || !warpEl) return;
-      nextTick(update);
-      if (!noresize) {
-        addResizeListener(resizeEl, update);
-        addResizeListener(warpEl, update);
-      }
-    });
-    onBeforeUnmount(() => {
-      const { native, noresize } = props;
-      const resizeEl = unref(resizeRef);
-      const warpEl = unref(wrapElRef);
-      if (native || !resizeEl || !warpEl) return;
-      if (!noresize) {
-        removeResizeListener(resizeEl, update);
-        removeResizeListener(warpEl, update);
-      }
-    });
-    return () => {
-      const { native, tag, viewClass, viewStyle, wrapClass, wrapStyle } = props;
-      let style: any = wrapStyle;
-      const gutter = scrollbarWidth();
-
-      if (gutter) {
-        const gutterWith = `-${gutter}px`;
-        const gutterStyle = `margin-bottom: ${gutterWith}; margin-right: ${gutterWith};`;
-
-        if (Array.isArray(wrapStyle)) {
-          style = toObject(wrapStyle);
-          style.marginRight = style.marginBottom = gutterWith;
-        } else if (isString(wrapStyle)) {
-          style += gutterStyle;
-        } else {
-          style = gutterStyle;
-        }
-      }
-
-      const Tag = tag as any;
-      const view = (
-        <Tag class={['scrollbar__view', viewClass]} style={viewStyle} ref={resizeRef}>
-          {getSlot(slots)}
-        </Tag>
-      );
-      const wrap = (
-        <div
-          ref={wrapElRef}
-          style={style}
-          onScroll={handleScroll}
-          class={[wrapClass, 'scrollbar__wrap', gutter ? '' : 'scrollbar__wrap--hidden-default']}
-        >
-          {[view]}
-        </div>
-      );
-      let nodes: any[] = [];
-      const { moveX, sizeWidth, moveY, sizeHeight } = state;
-      if (!native) {
-        nodes = [
-          wrap,
-          /* eslint-disable */
-          <Bar move={moveX} size={sizeWidth}></Bar>,
-          <Bar vertical move={moveY} size={sizeHeight}></Bar>,
-        ];
-      } else {
-        nodes = [
-          <div ref="wrap" class={[wrapClass, 'scrollbar__wrap']} style={style}>
-            {[view]}
-          </div>,
-        ];
-      }
-      return <div class="scrollbar">{nodes}</div>;
-    };
-  },
-});

+ 109 - 0
src/components/Scrollbar/src/bar.ts

@@ -0,0 +1,109 @@
+import {
+  defineComponent,
+  h,
+  computed,
+  ref,
+  getCurrentInstance,
+  onUnmounted,
+  inject,
+  Ref,
+} from 'vue';
+import { on, off } from '/@/utils/domUtils';
+
+import { renderThumbStyle, BAR_MAP } from './util';
+
+export default defineComponent({
+  name: 'Bar',
+
+  props: {
+    vertical: Boolean,
+    size: String,
+    move: Number,
+  },
+
+  setup(props) {
+    const instance = getCurrentInstance();
+    const thumb = ref<any>(null);
+    const wrap = inject('scroll-bar-wrap', {} as Ref<Nullable<HTMLElement>>) as any;
+    const bar = computed(() => {
+      return BAR_MAP[props.vertical ? 'vertical' : 'horizontal'];
+    });
+    const barStore = ref<Indexable>({});
+    const cursorDown = ref<any>(null);
+    const clickThumbHandler = (e: any) => {
+      // prevent click event of right button
+      if (e.ctrlKey || e.button === 2) {
+        return;
+      }
+      startDrag(e);
+      barStore.value[bar.value.axis] =
+        e.currentTarget[bar.value.offset] -
+        (e[bar.value.client] - e.currentTarget.getBoundingClientRect()[bar.value.direction]);
+    };
+
+    const clickTrackHandler = (e: any) => {
+      const offset = Math.abs(
+        e.target.getBoundingClientRect()[bar.value.direction] - e[bar.value.client]
+      );
+      const thumbHalf = thumb.value[bar.value.offset] / 2;
+      const thumbPositionPercentage =
+        ((offset - thumbHalf) * 100) / instance?.vnode.el?.[bar.value.offset];
+
+      wrap.value[bar.value.scroll] =
+        (thumbPositionPercentage * wrap.value[bar.value.scrollSize]) / 100;
+    };
+    const startDrag = (e: any) => {
+      e.stopImmediatePropagation();
+      cursorDown.value = true;
+      on(document, 'mousemove', mouseMoveDocumentHandler);
+      on(document, 'mouseup', mouseUpDocumentHandler);
+      document.onselectstart = () => false;
+    };
+
+    const mouseMoveDocumentHandler = (e: any) => {
+      if (cursorDown.value === false) return;
+      const prevPage = barStore.value[bar.value.axis];
+
+      if (!prevPage) return;
+
+      const offset =
+        (instance?.vnode.el?.getBoundingClientRect()[bar.value.direction] - e[bar.value.client]) *
+        -1;
+      const thumbClickPosition = thumb.value[bar.value.offset] - prevPage;
+      const thumbPositionPercentage =
+        ((offset - thumbClickPosition) * 100) / instance?.vnode.el?.[bar.value.offset];
+      wrap.value[bar.value.scroll] =
+        (thumbPositionPercentage * wrap.value[bar.value.scrollSize]) / 100;
+    };
+
+    function mouseUpDocumentHandler() {
+      cursorDown.value = false;
+      barStore.value[bar.value.axis] = 0;
+      off(document, 'mousemove', mouseMoveDocumentHandler);
+      document.onselectstart = null;
+    }
+
+    onUnmounted(() => {
+      off(document, 'mouseup', mouseUpDocumentHandler);
+    });
+
+    return () =>
+      h(
+        'div',
+        {
+          class: ['scrollbar__bar', 'is-' + bar.value.key],
+          onMousedown: clickTrackHandler,
+        },
+        h('div', {
+          ref: thumb,
+          class: 'scrollbar__thumb',
+          onMousedown: clickThumbHandler,
+          style: renderThumbStyle({
+            size: props.size,
+            move: props.move,
+            bar: bar.value,
+          }),
+        })
+      );
+  },
+});

+ 0 - 69
src/components/Scrollbar/src/index.less

@@ -1,69 +0,0 @@
-.scrollbar {
-  position: relative;
-  overflow: hidden;
-
-  &__wrap {
-    height: 100%;
-    overflow: scroll;
-
-    &--hidden-default {
-      scrollbar-width: none;
-
-      &::-webkit-scrollbar {
-        width: 0;
-        height: 0;
-      }
-    }
-  }
-
-  &__thumb {
-    position: relative;
-    display: block;
-    width: 0;
-    height: 0;
-    cursor: pointer;
-    background-color: rgba(144, 147, 153, 0.3);
-    border-radius: inherit;
-    transition: 0.3s background-color;
-
-    &:hover {
-      background-color: rgba(144, 147, 153, 0.5);
-    }
-  }
-
-  &__bar {
-    position: absolute;
-    right: 2px;
-    bottom: 2px;
-    z-index: 1;
-    border-radius: 4px;
-    opacity: 0;
-    -webkit-transition: opacity 80ms ease;
-    transition: opacity 80ms ease;
-
-    &.is-vertical {
-      top: 2px;
-      width: 5px;
-
-      & > div {
-        width: 100%;
-      }
-    }
-
-    &.is-horizontal {
-      left: 2px;
-      height: 5px;
-
-      & > div {
-        height: 100%;
-      }
-    }
-  }
-}
-
-.scrollbar:active > .scrollbar__bar,
-.scrollbar:focus > .scrollbar__bar,
-.scrollbar:hover > .scrollbar__bar {
-  opacity: 1;
-  transition: opacity 180ms ease;
-}

+ 195 - 0
src/components/Scrollbar/src/index.vue

@@ -0,0 +1,195 @@
+<template>
+  <div class="scrollbar">
+    <div
+      ref="wrap"
+      :class="[wrapClass, 'scrollbar__wrap', native ? '' : 'scrollbar__wrap--hidden-default']"
+      :style="style"
+      @scroll="handleScroll"
+    >
+      <component :is="tag" ref="resize" :class="['scrollbar__view', viewClass]" :style="viewStyle">
+        <slot></slot>
+      </component>
+    </div>
+    <template v-if="!native">
+      <bar :move="moveX" :size="sizeWidth" />
+      <bar vertical :move="moveY" :size="sizeHeight" />
+    </template>
+  </div>
+</template>
+<script lang="ts">
+  import { addResizeListener, removeResizeListener } from '/@/utils/event/resizeEvent';
+
+  import { toObject } from './util';
+  import {
+    defineComponent,
+    ref,
+    onMounted,
+    onBeforeUnmount,
+    nextTick,
+    provide,
+    computed,
+  } from 'vue';
+  import Bar from './bar';
+
+  export default defineComponent({
+    name: 'Scrollbar',
+    components: { Bar },
+    props: {
+      native: {
+        type: Boolean,
+        default: false,
+      },
+      wrapStyle: {
+        type: [String, Array],
+        default: '',
+      },
+      wrapClass: {
+        type: [String, Array],
+        default: '',
+      },
+      viewClass: {
+        type: [String, Array],
+        default: '',
+      },
+      viewStyle: {
+        type: [String, Array],
+        default: '',
+      },
+      noresize: Boolean, // 如果 container 尺寸不会发生变化,最好设置它可以优化性能
+      tag: {
+        type: String,
+        default: 'div',
+      },
+    },
+    setup(props) {
+      const sizeWidth = ref('0');
+      const sizeHeight = ref('0');
+      const moveX = ref(0);
+      const moveY = ref(0);
+      const wrap = ref<any>(null);
+      const resize = ref<any>(null);
+
+      provide('scroll-bar-wrap', wrap);
+
+      const handleScroll = () => {
+        if (!props.native) {
+          moveY.value = (wrap.value.scrollTop * 100) / wrap.value.clientHeight;
+          moveX.value = (wrap.value.scrollLeft * 100) / wrap.value.clientWidth;
+        }
+      };
+
+      const update = () => {
+        if (!wrap.value) return;
+
+        const heightPercentage = (wrap.value.clientHeight * 100) / wrap.value.scrollHeight;
+        const widthPercentage = (wrap.value.clientWidth * 100) / wrap.value.scrollWidth;
+
+        sizeHeight.value = heightPercentage < 100 ? heightPercentage + '%' : '';
+        sizeWidth.value = widthPercentage < 100 ? widthPercentage + '%' : '';
+      };
+
+      onMounted(() => {
+        if (props.native) return;
+        nextTick(update);
+        !props.noresize && addResizeListener(resize.value, update);
+      });
+
+      onBeforeUnmount(() => {
+        if (props.native) return;
+        !props.noresize && removeResizeListener(resize.value, update);
+      });
+      const style = computed(() => {
+        let style: any = props.wrapStyle;
+        if (Array.isArray(props.wrapStyle)) {
+          style = toObject(props.wrapStyle);
+        }
+        return style;
+      });
+      return {
+        moveX,
+        moveY,
+        sizeWidth,
+        sizeHeight,
+        style,
+        wrap,
+        resize,
+        update,
+        handleScroll,
+      };
+    },
+  });
+</script>
+<style lang="less">
+  .scrollbar {
+    position: relative;
+    height: 100%;
+    overflow: hidden;
+
+    &__wrap {
+      height: 100%;
+      overflow: scroll;
+
+      &--hidden-default {
+        scrollbar-width: none;
+
+        &::-webkit-scrollbar {
+          display: none;
+          width: 0;
+          height: 0;
+          opacity: 0;
+        }
+      }
+    }
+
+    &__thumb {
+      position: relative;
+      display: block;
+      width: 0;
+      height: 0;
+      cursor: pointer;
+      background-color: rgba(144, 147, 153, 0.3);
+      border-radius: inherit;
+      transition: 0.3s background-color;
+
+      &:hover {
+        background-color: rgba(144, 147, 153, 0.5);
+      }
+    }
+
+    &__bar {
+      position: absolute;
+      right: 2px;
+      bottom: 2px;
+      z-index: 1;
+      border-radius: 4px;
+      opacity: 0;
+      -webkit-transition: opacity 80ms ease;
+      transition: opacity 80ms ease;
+
+      &.is-vertical {
+        top: 2px;
+        width: 6px;
+
+        & > div {
+          width: 100%;
+        }
+      }
+
+      &.is-horizontal {
+        left: 2px;
+        height: 6px;
+
+        & > div {
+          height: 100%;
+        }
+      }
+    }
+  }
+
+  .scrollbar:active > .scrollbar__bar,
+  .scrollbar:focus > .scrollbar__bar,
+  .scrollbar:hover > .scrollbar__bar {
+    opacity: 1;
+    transition: opacity 340ms ease-out;
+  }
+</style>

+ 2 - 0
src/components/Transition/src/ExpandTransition.vue

@@ -59,6 +59,8 @@
             if (el.scrollHeight !== 0) {
               // for safari: add class after set height, or it will jump to zero height suddenly, weired
               addClass(el, 'collapse-transition');
+              // in vue3.0.4, transitionProperty is set 'none' to avoid 'v-leave-from' issue
+              el.style.transitionProperty = 'height';
               el.style.height = 0;
               el.style.paddingTop = 0;
               el.style.paddingBottom = 0;

+ 1 - 1
src/locales/types.ts

@@ -1 +1 @@
-export type LocaleType = 'zh_CN' | 'en' | 'ru' | 'ja';
+export type LocaleType = 'zh_CN' | 'en' | 'ru' | 'ja' | 'ko';

+ 10 - 0
src/router/menus/modules/demo/comp.ts

@@ -180,6 +180,16 @@ const menu: MenuModule = {
           {
             path: 'markdown',
             name: t('routes.demo.editor.markdown'),
+            children: [
+              {
+                path: 'index',
+                name: t('routes.demo.editor.tinymceBasic'),
+              },
+              {
+                path: 'editor',
+                name: t('routes.demo.editor.tinymceForm'),
+              },
+            ],
           },
           {
             path: 'tinymce',

+ 21 - 1
src/router/routes/modules/demo/comp.ts

@@ -288,12 +288,32 @@ const comp: AppRouteModule = {
       children: [
         {
           path: 'markdown',
+          component: getParentLayout('MarkdownDemo'),
           name: 'MarkdownDemo',
-          component: () => import('/@/views/demo/editor/Markdown.vue'),
           meta: {
             title: t('routes.demo.editor.markdown'),
           },
+          redirect: '/comp/editor/markdown/index',
+          children: [
+            {
+              path: 'index',
+              name: 'MarkDownBasicDemo',
+              component: () => import('/@/views/demo/editor/markdown/index.vue'),
+              meta: {
+                title: t('routes.demo.editor.tinymceBasic'),
+              },
+            },
+            {
+              path: 'editor',
+              name: 'MarkDownFormDemo',
+              component: () => import('/@/views/demo/editor/markdown/Editor.vue'),
+              meta: {
+                title: t('routes.demo.editor.tinymceForm'),
+              },
+            },
+          ],
         },
+
         {
           path: 'tinymce',
           component: getParentLayout('TinymceDemo'),

+ 58 - 0
src/views/demo/editor/markdown/Editor.vue

@@ -0,0 +1,58 @@
+<template>
+  <div class="m-4">
+    <CollapseContainer title="MarkDown表单">
+      <BasicForm
+        :labelWidth="100"
+        :schemas="schemas"
+        :actionColOptions="{ span: 24 }"
+        @submit="handleSubmit"
+      >
+      </BasicForm>
+    </CollapseContainer>
+  </div>
+</template>
+<script lang="ts">
+  import { defineComponent, h } from 'vue';
+  import { BasicForm, FormSchema } from '/@/components/Form/index';
+  import { CollapseContainer } from '/@/components/Container/index';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  import { MarkDown } from '/@/components/Markdown';
+
+  const schemas: FormSchema[] = [
+    {
+      field: 'title',
+      component: 'Input',
+      label: 'title',
+      defaultValue: '标题',
+      rules: [{ required: true }],
+    },
+    {
+      field: 'markdown',
+      component: 'Input',
+      label: 'markdown',
+      defaultValue: 'defaultValue',
+      rules: [{ required: true, trigger: 'blur' }],
+      render: ({ model, field }) => {
+        return h(MarkDown, {
+          value: model[field],
+          onChange: (value: string) => {
+            model[field] = value;
+          },
+        });
+      },
+    },
+  ];
+  export default defineComponent({
+    components: { BasicForm, CollapseContainer },
+    setup() {
+      const { createMessage } = useMessage();
+
+      return {
+        schemas,
+        handleSubmit: (values: any) => {
+          createMessage.success('click search,values:' + JSON.stringify(values));
+        },
+      };
+    },
+  });
+</script>

+ 7 - 1
src/views/demo/editor/Markdown.vue → src/views/demo/editor/markdown/index.vue

@@ -1,7 +1,7 @@
 <template>
   <div class="p-4">
     <a-button @click="toggleTheme" class="mb-2" type="primary">黑暗主题</a-button>
-    <MarkDown v-model:value="value" ref="markDownRef" />
+    <MarkDown :value="value" @change="handleChange" ref="markDownRef" />
   </div>
 </template>
 <script lang="ts">
@@ -23,10 +23,16 @@
         const vditor = markDown.getVditor();
         vditor.setTheme('dark');
       }
+
+      function handleChange(v: string) {
+        valueRef.value = v;
+      }
+
       return {
         value: valueRef,
         toggleTheme,
         markDownRef,
+        handleChange,
       };
     },
   });

+ 4 - 18
tsconfig.json

@@ -15,16 +15,11 @@
     "noUnusedLocals": true,
     "noUnusedParameters": true,
     "experimentalDecorators": true,
-    "lib": [
-      "dom",
-      "esnext"
-    ],
+    "lib": ["dom", "esnext"],
     "incremental": true,
     "skipLibCheck": true,
     "paths": {
-      "/@/*": [
-        "src/*"
-      ]
+      "/@/*": ["src/*"]
     }
   },
   "plugins": [
@@ -32,15 +27,6 @@
       "name": "@vuedx/typescript-plugin-vue"
     }
   ],
-  "include": [
-    "src/**/*.ts",
-    "src/**/*.d.ts",
-    "src/**/*.tsx",
-    "src/**/*.vue"
-  ],
-  "exclude": [
-    "node_modules",
-    "dist",
-    "**/*.js"
-  ]
+  "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
+  "exclude": ["node_modules", "dist", "**/*.js"]
 }