Ben Lin
2024-06-18 ebbd788fbb2c0b45d4473798efc57eec8ba74a25
src/components/Markdown/src/Markdown.vue
@@ -1,10 +1,10 @@
<template>
  <div ref="wrapRef"></div>
</template>
<script lang="ts">
<script lang="ts" setup>
  import './adapter.js';
  import type { Ref } from 'vue';
  import {
    defineComponent,
    ref,
    unref,
    nextTick,
@@ -12,149 +12,148 @@
    watch,
    onBeforeUnmount,
    onDeactivated,
    useAttrs,
  } from 'vue';
  import Vditor from 'vditor';
  import 'vditor/dist/index.css';
  import { useLocale } from '/@/locales/useLocale';
  import { useLocale } from '@/locales/useLocale';
  import { useModalContext } from '../../Modal';
  import { useRootSetting } from '/@/hooks/setting/useRootSetting';
  import { useRootSetting } from '@/hooks/setting/useRootSetting';
  import { onMountedOrActivated } from '@vben/hooks';
  import { getTheme } from './getTheme';
  type Lang = 'zh_CN' | 'en_US' | 'ja_JP' | 'ko_KR' | undefined;
  export default defineComponent({
    inheritAttrs: false,
    props: {
      height: { type: Number, default: 360 },
      value: { type: String, default: '' },
    },
    emits: ['change', 'get', 'update:value'],
    setup(props, { attrs, emit }) {
      const wrapRef = ref(null);
      const vditorRef = ref(null) as Ref<Vditor | null>;
      const initedRef = ref(false);
  defineOptions({ inheritAttrs: false });
      const modalFn = useModalContext();
      const { getLocale } = useLocale();
      const { getDarkMode } = useRootSetting();
      const valueRef = ref(props.value || '');
      watch(
        [() => getDarkMode.value, () => initedRef.value],
        ([val, inited]) => {
          if (!inited) {
            return;
          }
          instance
            .getVditor()
            ?.setTheme(getTheme(val) as any, getTheme(val, 'content'), getTheme(val, 'code'));
        },
        {
          immediate: true,
          flush: 'post',
        },
      );
      watch(
        () => props.value,
        (v) => {
          if (v !== valueRef.value) {
            instance.getVditor()?.setValue(v);
          }
          valueRef.value = v;
        },
      );
      const getCurrentLang = computed((): 'zh_CN' | 'en_US' | 'ja_JP' | 'ko_KR' => {
        let lang: Lang;
        switch (unref(getLocale)) {
          case 'en':
            lang = 'en_US';
            break;
          case 'ja':
            lang = 'ja_JP';
            break;
          case 'ko':
            lang = 'ko_KR';
            break;
          default:
            lang = 'zh_CN';
        }
        return lang;
      });
      function init() {
        const wrapEl = unref(wrapRef);
        if (!wrapEl) return;
        const bindValue = { ...attrs, ...props };
        const insEditor = new Vditor(wrapEl, {
          // 设置外观主题
          theme: getTheme(getDarkMode.value) as any,
          lang: unref(getCurrentLang),
          mode: 'sv',
          fullscreen: {
            index: 520,
          },
          preview: {
            theme: {
              // 设置内容主题
              current: getTheme(getDarkMode.value, 'content'),
            },
            hljs: {
              // 设置代码块主题
              style: getTheme(getDarkMode.value, 'code'),
            },
            actions: [],
          },
          input: (v) => {
            valueRef.value = v;
            emit('update:value', v);
            emit('change', v);
          },
          after: () => {
            nextTick(() => {
              modalFn?.redoModalHeight?.();
              insEditor.setValue(valueRef.value);
              vditorRef.value = insEditor;
              initedRef.value = true;
              emit('get', instance);
            });
          },
          blur: () => {
            //unref(vditorRef)?.setValue(props.value);
          },
          ...bindValue,
          cache: {
            enable: false,
          },
        });
      }
      const instance = {
        getVditor: (): Vditor => vditorRef.value!,
      };
      function destroy() {
        const vditorInstance = unref(vditorRef);
        if (!vditorInstance) return;
        try {
          vditorInstance?.destroy?.();
        } catch (error) {
          //
        }
        vditorRef.value = null;
        initedRef.value = false;
      }
      onMountedOrActivated(init);
      onBeforeUnmount(destroy);
      onDeactivated(destroy);
      return {
        wrapRef,
        ...instance,
      };
    },
  const props = defineProps({
    height: { type: Number, default: 360 },
    value: { type: String, default: '' },
  });
  const emit = defineEmits(['change', 'get', 'update:value']);
  const attrs = useAttrs();
  const wrapRef = ref(null);
  const vditorRef = ref(null) as Ref<Vditor | null>;
  const initedRef = ref(false);
  const modalFn = useModalContext();
  const { getLocale } = useLocale();
  const { getDarkMode } = useRootSetting();
  const valueRef = ref(props.value || '');
  watch(
    [() => getDarkMode.value, () => initedRef.value],
    ([val, inited]) => {
      if (!inited) {
        return;
      }
      instance
        .getVditor()
        ?.setTheme(getTheme(val) as any, getTheme(val, 'content'), getTheme(val, 'code'));
    },
    {
      immediate: true,
      flush: 'post',
    },
  );
  watch(
    () => props.value,
    (v) => {
      if (v !== valueRef.value) {
        instance.getVditor()?.setValue(v);
      }
      valueRef.value = v;
    },
  );
  const getCurrentLang = computed((): 'zh_CN' | 'en_US' | 'ja_JP' | 'ko_KR' => {
    let lang: Lang;
    switch (unref(getLocale)) {
      case 'en':
        lang = 'en_US';
        break;
      case 'ja':
        lang = 'ja_JP';
        break;
      case 'ko':
        lang = 'ko_KR';
        break;
      default:
        lang = 'zh_CN';
    }
    return lang;
  });
  function init() {
    const wrapEl = unref(wrapRef);
    if (!wrapEl) return;
    const bindValue = { ...attrs, ...props };
    const insEditor = new Vditor(wrapEl, {
      // 设置外观主题
      theme: getTheme(getDarkMode.value) as any,
      lang: unref(getCurrentLang),
      mode: 'sv',
      fullscreen: {
        index: 520,
      },
      preview: {
        theme: {
          // 设置内容主题
          current: getTheme(getDarkMode.value, 'content'),
        },
        hljs: {
          // 设置代码块主题
          style: getTheme(getDarkMode.value, 'code'),
        },
        actions: [],
      },
      input: (v) => {
        valueRef.value = v;
        emit('update:value', v);
        emit('change', v);
      },
      after: () => {
        nextTick(() => {
          modalFn?.redoModalHeight?.();
          insEditor.setValue(valueRef.value);
          vditorRef.value = insEditor;
          initedRef.value = true;
          emit('get', instance);
        });
      },
      blur: () => {
        //unref(vditorRef)?.setValue(props.value);
      },
      ...bindValue,
      cache: {
        enable: false,
      },
    });
  }
  const instance = {
    getVditor: (): Vditor => vditorRef.value!,
  };
  function destroy() {
    const vditorInstance = unref(vditorRef);
    if (!vditorInstance) return;
    try {
      vditorInstance?.destroy?.();
    } catch (error) {
      //
    }
    vditorRef.value = null;
    initedRef.value = false;
  }
  onMountedOrActivated(init);
  onBeforeUnmount(destroy);
  onDeactivated(destroy);
</script>