国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

vue3中使用cherry-markDown步驟

這篇具有很好參考價值的文章主要介紹了vue3中使用cherry-markDown步驟。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

附cherry-markDown官網(wǎng)及api使用示例

官網(wǎng):GitHub - Tencent/cherry-markdown: ? A Markdown Editor

api:Cherry Markdown API

考慮到復(fù)用性,我在插件的基礎(chǔ)上做了二次封裝,步驟如下:

1.下載??npm install cherry-markdown --save

2..先在html中定義一個markDown容器,設(shè)置id及樣式

<template>
  <div v-loading="loading" element-loading-text="文件上傳中...">
    <div @click.prevent.stop>
      <div :id="mdId" :style="{ height: height + 'px' }"></div>
    </div>
  </div>
</template>

3.在js中引入markDown

import Cherry from "cherry-markdown";
import "cherry-markdown/dist/cherry-markdown.min.css";

4.定義需要使用的變量并初始化markDown

(一部分是從父組件傳過來的,loading是在上傳圖片/視頻/附件的時候使用)

const props = defineProps({
  height: {
    type: Number,
    default: 600,
  },
  modelValue: {
    type: String,
    default: "",
  },
  knwlgId: {
    type: String,
    default: "",
  },
  mdId: {
    type: String,
    default: "markdown-container",
  },
});
const emits = defineEmits(["update:modelValue", "setHtml"]);
const cherrInstance = ref(null);
const loading = ref(false);

onMounted(() => {
  //初始化markDown
  initCherryMD();
});

5.初始化markDown

toolbars.toolbar內(nèi)的togglePreview就是預(yù)覽按鈕

設(shè)置默認(rèn)模式:editor.defaultModel

// defaultModel 編輯器初始化后的默認(rèn)模式,一共有三種模式:1、雙欄編輯預(yù)覽模式;2、純編輯模式;3、預(yù)覽模式

// edit&preview: 雙欄編輯預(yù)覽模式

// editOnly: 純編輯模式(沒有預(yù)覽,可通過toolbar切換成雙欄或預(yù)覽模式)

// previewOnly: 預(yù)覽模式(沒有編輯框,toolbar只顯示“返回編輯”按鈕,可通過toolbar切換成編輯模式)

// defaultModel: 'edit&preview',

const initCherryMD = (value, config) => {
  cherrInstance.value = new Cherry({
    id: props.mdId,
    value: props.modelValue,
    fileUpload: fileUpload,
    emoji: {
      useUnicode: true,
    },
    header: {
      anchorStyle: "autonumber",
    },
    editor: {
      defaultModel: "editOnly",
    },
    toolbars: {
      theme: "light",
      toolbar: [
        "bold",
        "italic",
        "underline",
        "strikethrough",
        "|",
        "color",
        "header",
        "|",
        "list",
        "image",
        {
          insert: [
            "audio",
            "video",
            "link",
            "hr",
            "br",
            "code",
            "formula",
            "toc",
            "table",
            "line-table",
            "bar-table",
            "pdf",
            "word",
          ],
        },
        "graph",
        "settings",
        // "switchModel",
        "togglePreview",
      ],
      bubble: [
        "bold",
        "italic",
        "underline",
        "strikethrough",
        "sub",
        "sup",
        "|",
        "size",
        "color",
      ],
      float: [
        "h1",
        "h2",
        "h3",
        "|",
        "checklist",
        "quote",
        "quickTable",
        "code",
      ],
      customMenu: [],
    },
    callback: {
      afterChange: afterChange,
      beforeImageMounted: beforeImageMounted,
    },
  });
};

6.定義上傳圖片、獲取數(shù)據(jù)的方法(這里可以實際需求做判斷)

// 上傳通用接口未實現(xiàn)audioVideo
const fileUpload = (file, callback) => {
  if (file.size / 1024 / 1024 > 200) {
    return proxy.$modal.msgError("請上傳200M以內(nèi)的圖片!");
  }
  if (!file.type.includes("image")) {
    return proxy.$modal.msgError("僅支持上傳圖片!");
  }
  const formData = new FormData();
  formData.append("file", file);
  console.log(file, "file");
  loading.value = true;
  uploadImg(props.knwlgId, formData)
    .then((res) => {
      loading.value = false;
      callback(
        import.meta.env.VITE_APP_BASE_API +
          "/ekms/images/v1/preview/" +
          res.data.imgId
      );
    })
    .catch(() => {
      loading.value = false;
    });
};

// 變更事件回調(diào)
const afterChange = (e) => {
  emits("setHtml", getCherryContent(), getCherryHtml());
};

// 獲取渲染后html內(nèi)容
const getCherryHtml = () => {
  const result = cherrInstance.value.getHtml();
  // console.log(result, "get");
  return result;
};

// 獲取markdown內(nèi)容
const getCherryContent = () => {
  const result = cherrInstance.value.getMarkdown();
  return result;
};

// 設(shè)置markdown內(nèi)容
const setCherryContent = (val) => {
  cherrInstance.value.setMarkdown(val, 1);
};

// 圖片加載回調(diào)
const beforeImageMounted = (e, src) => {
  return { [e]: src };
};
defineExpose({
  getCherryHtml,
  setCherryContent,
});

使用該組件:

 <CherryMD
   ref="MDRef"
   v-model="mdContent"
   :knwlgId="artDetails.pkId"
   @setHtml="getContent"
 />

 const mdContent = ref("");
 //設(shè)置默認(rèn)值
 mdContent.value = res.data.content;
 nextTick(() => {
   proxy.$refs.MDRef.setCherryContent(res.data.content || "");
 });

// 獲取文章結(jié)構(gòu)信息
const getContent = (content, html) => {
  mdHtml.value = html;
  mdContent.value = content;
  changeArticle();
};

完整代碼:文章來源地址http://www.zghlxwxcb.cn/news/detail-654208.html

<template>
  <div>
    <div
      id="vditor"
      class="vditor"
      :class="{ 'vditor-hidden': showPreview }"
    ></div>
  </div>
</template>

<script setup>
import Vditor from "vditor";
import "vditor/dist/index.css";
import { getToken } from "@/utils/auth";
const { proxy } = getCurrentInstance();
const props = defineProps({
  height: {
    type: [Number, String],
    default: "inherit",
  },
  modelValue: {
    type: String,
    default: "",
  },
  knwlgId: {
    type: String,
    default: "",
  },
  showPreview: {
    type: Boolean,
    default: false,
  },
});

watch(
  () => props.showPreview,
  (newValue, oldValue) => {
    let previewDom =
      contentEditor.value.vditor.toolbar.elements.preview.firstChild;
    let isPreview = previewDom.className.indexOf("vditor-menu--current") > -1;
    emits("update:showPreview", isPreview ? false : true);
    previewDom.click();
  }
);

const emits = defineEmits([
  "update:modelValue",
  "update:showPreview",
  "setHtml",
]);
const contentEditor = ref(null);

onMounted(() => {
  contentEditor.value = new Vditor("vditor", {
    height: props.height,
    mode: "wysiwyg", //所見即所得(wysiwyg)、即時渲染(ir)、分屏預(yù)覽(sv)
    value: props.modelValue,
    cdn: import.meta.env.VITE_APP_VDITOR_API,
    toolbarConfig: {
      pin: true,
      // hide: true,
    },
    // outline: {
    //   enable: true, //展示大綱,position默認(rèn)left
    // },
    cache: {
      enable: false, // 是否使用 localStorage 進(jìn)行緩存
    },
    preview: {
      mode: "both", //顯示模式
      delay: 10,
      actions: [],
      theme: {
        path: `${import.meta.env.VITE_APP_VDITOR_API}/dist/css/content-theme`,
      },
    },
    toolbar: [
      "emoji",
      "headings",
      "bold",
      "italic",
      "strike",
      "link",
      "|",
      "list",
      "ordered-list",
      "check",
      "outdent",
      "indent",
      "|",
      "quote",
      "line",
      "code",
      "inline-code",
      "insert-before",
      "insert-after",
      "|",
      {
        //自定義上傳
        hotkey: "",
        name: "upload",
        tip: "上傳圖片",
        className: "right",
      },

      "table",
      "|",
      "undo",
      "redo",
      "|",
      "code-theme",
      "content-theme",
      "preview",
      {
        hotkey: "??S",
        name: "clearAll",
        tipPosition: "n",
        tip: "清空內(nèi)容",
        className: "right",
        icon: '<svg t="1696926237451" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2371" width="180" height="180"><path d="M512 838.858c10.89 0 19.732-9.158 19.732-20.43v-490.275c0-11.273-8.842-20.43-19.732-20.43s-19.755 9.157-19.755 20.43v490.275c0 11.272 8.842 20.43 19.755 20.43M629.877 838.813c10.935 0.428 20.138-8.37 20.475-19.688l28.665-489.69c0.427-11.272-8.077-20.745-18.99-21.195-10.935-0.405-20.137 8.415-20.475 19.688l-28.665 489.713c-0.405 11.317 8.1 20.767 18.99 21.172M848.038 185.142h-197.708v-81.653c0-22.545-17.685-40.882-39.51-40.882h-197.64c-21.87 0-39.532 18.338-39.532 40.882v81.653h-197.685c-10.913 0-19.755 9.158-19.755 20.475 0 11.272 8.843 20.407 19.755 20.407h39.577l39.488 653.67c6.367 44.73 35.415 81.72 79.065 81.72h355.793c43.65 0 71.573-37.44 79.088-81.72l39.488-653.67h39.578c10.867 0 19.755-9.135 19.755-20.408 0-11.317-8.888-20.475-19.755-20.475M413.157 103.49h197.64v81.653h-197.64v-81.653zM729.418 879.695c-2.655 21.555-17.73 40.86-39.533 40.86h-355.793c-21.87 0-36.54-19.057-39.532-40.86l-39.532-653.67h513.945l-39.555 653.67zM394.145 838.858c10.89-0.473 19.373-9.9 18.99-21.195l-29.070-489.712c-0.427-11.273-9.585-20.070-20.475-19.665-10.913 0.428-19.463 9.9-19.013 21.173l29.093 489.712c0.36 11.295 9.54 20.070 20.475 19.688z" p-id="2372"></path></svg>',
        click() {
          contentEditor.value.setValue("");
        },
      },
    ],
    after: () => {
      emits("setHtml", getValue(), getHTML());
      contentEditor.value.vditor.toolbar.elements.preview.firstChild.style.display =
        "none";
    },
    input: () => {
      // 變更事件回調(diào)
      emits("setHtml", getValue(), getHTML());
    },
    // 上傳圖片
    upload: {
      accept: "image/*",
      fieldName: "file",
      url:
        import.meta.env.VITE_APP_BASE_API +
        `/ekms/images/v1/upload?knwlgId=${props.knwlgId}`,
      headers: {
        Authorization: "Bearer " + getToken(),
      },
      filename(name) {
        return name
          .replace(/[^(a-zA-Z0-9\u4e00-\u9fa5\.)]/g, "")
          .replace(/[\?\\/:|<>\*\[\]\(\)\$%\{\}@~]/g, "")
          .replace("/\\s/g", "");
      },
      linkToImgUrl:
        import.meta.env.VITE_APP_BASE_API +
        `/ekms/images/v1/upload?knwlgId=${props.knwlgId}`,
      max: 20 * 1024 * 1024,
      multiple: false,
      withCredentials: false,
      validate(files) {
        const isLt2M = files[0].size / 1024 / 1024 < 20;
        if (!isLt2M) {
          proxy.$modal.msgError("上傳圖片大小不能超過 20MB!");
        }
        if (!files[0].type.includes("image")) {
          return proxy.$modal.msgError("僅支持上傳圖片!");
        }
      },
      //粘貼圖片回顯處理,如果有圖片加了防盜鏈,則讓后臺代理替換成自己的圖片
      linkToImgFormat(responseText) {
        let res = JSON.parse(responseText);
        let end = JSON.stringify({
          msg: "",
          code: 0,
          data: {
            originalURL:
              import.meta.env.VITE_APP_BASE_API +
              "/ekms/images/v1/preview/" +
              res.data.imgId, //圖片原始地址記錄到本地文件中,可以防止跨站點調(diào)用。
            url:
              import.meta.env.VITE_APP_BASE_API +
              "/ekms/images/v1/preview/" +
              res.data.imgId, //圖片鏈接記錄到本地文件中,可以防止跨站點調(diào)用。
          },
        });
        return end;
      },
      format(files, responseText) {
        var res = JSON.parse(responseText);
        //圖片回顯
        nextTick(() => {
          emits("setHtml", getValue(), getHTML());
        });
        return JSON.stringify({
          msg: "",
          code: 0,
          data: {
            errFiles: [],
            succMap: {
              [res.data.imgPath]:
                import.meta.env.VITE_APP_BASE_API +
                "/ekms/images/v1/preview/" +
                res.data.imgId,
            },
          },
        });
      },
    },
  });
});

function getValue() {
  return contentEditor.value.getValue(); //獲取 Markdown 內(nèi)容
}
function getHTML() {
  let dom = document.querySelector(
    ".vditor-content .vditor-wysiwyg .vditor-reset"
  )?.innerHTML;
  return dom;
}
function setValue(value) {
  return contentEditor.value.setValue(value); //設(shè)置 Markdown 內(nèi)容
}

defineExpose({
  getHTML,
  setValue,
});
</script>

<style lang="scss" scoped>
// :deep(.vditor) {
//   padding-top: 36px;
// }
:deep(.vditor-toolbar--pin) {
  // position: fixed;
  // top: 236px;
  padding-left: calc(50% - 340px);
}
:deep(.vditor-wysiwyg) {
  a {
    color: #4285f4;
    outline: 0;
    text-decoration: none;
  }
}
:deep(.vditor-hidden) {
  height: inherit !important;
  border: none !important;
  .vditor-toolbar,
  .vditor-wysiwyg {
    display: none !important;
  }
  .vditor-preview {
    display: block !important;
    overflow-x: hidden !important;
    background: #fff;
    border: none !important;
  }
  .vditor-reset {
    padding: 20px;
    margin: 0 !important;
    max-width: fit-content !important;
    background: #fff;
    a {
      color: #006eff;
    }
  }
}
:deep(.vditor-wysiwyg .vditor-reset) {
  padding: 10px 35px !important;
}
</style>

到了這里,關(guān)于vue3中使用cherry-markDown步驟的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • vue3 ts element plus form表單二次封裝詳細(xì)步驟 (附參數(shù)、類型詳細(xì)介紹及簡單使用示例)

    vue3 ts element plus form表單二次封裝詳細(xì)步驟 (附參數(shù)、類型詳細(xì)介紹及簡單使用示例)

    上篇table 表格封裝 講到項目中經(jīng)常會用到 table 表格,所以做了封裝。當(dāng)然,form 表單使用的頻率依然很高,所以和封裝 table 表格的思路相似,對 form 表單也做了一個二次封裝的組件。 查看國內(nèi)預(yù)覽站 查看國外預(yù)覽站 1. EasyForm 表單組件封裝 src/components/EasyForm/index.vue Form 表單

    2024年02月07日
    瀏覽(68)
  • 服務(wù)端使用ASP.NET Core SignalR與Vue3(TypeScript與JavaScript)前端建立通信(以進(jìn)度條為例)

    服務(wù)端使用ASP.NET Core SignalR與Vue3(TypeScript與JavaScript)前端建立通信(以進(jìn)度條為例)

    1. ASP.NET Core ? ? ? ? ? ASP.NET Core 是一個跨平臺、高性能及開源的框架,用于生成基于云且連接互聯(lián)網(wǎng)的新式應(yīng)用程式。 官方文檔:ASP.NET documentation | Microsoft Learn ?2.? ASP.NET Core SignalR ? ? ? ? ASP.NET Core SignalR 是開源庫,用于服務(wù)端與客戶端建立實時通信,可以自動管理連接

    2024年02月06日
    瀏覽(22)
  • uniapp+vue3+ts+vite+echarts開發(fā)圖表類小程序,將echarts導(dǎo)入項目使用的詳細(xì)步驟,耗時一天終于弄好了

    uniapp+vue3+ts+vite+echarts開發(fā)圖表類小程序,將echarts導(dǎo)入項目使用的詳細(xì)步驟,耗時一天終于弄好了

    想在uniapp和vue3環(huán)境中使用echarts是一件相當(dāng)前衛(wèi)的事情,官方適配的還不是很好,echarts的使用插件寫的是有些不太清晰的,這里我花費了一天的時間,終于將這個使用步驟搞清楚了,并且建了一個倉庫,大家可以直接clone下來使用。先看一下pc端和小程序端的效果: 微信小程

    2024年02月05日
    瀏覽(227)
  • [完整]流程解決Vue3項目搭建步驟

    npm init vue@latest 或者 npm create vite@latest 進(jìn)行初始化項目并創(chuàng)建項目名稱code,進(jìn)入code目錄進(jìn)行基本部署。 cd code 、 npm install 、 npm run dev 完成vue3項目搭建。 npm install vue-router@next --save 分離式:**在src目錄下創(chuàng)建router文件夾,并在文件夾下創(chuàng)建index.js和routes.js index.js :(只用來存放

    2024年02月16日
    瀏覽(16)
  • 2023Vue2如何遷移Vue3:附上具體步驟!??!

    Vue3已經(jīng)發(fā)布了,它帶來了許多改進(jìn)和新特性。如果你正在使用Vue2,你可能會想知道如何將你的應(yīng)用程序遷移至Vue3。在本篇博文中,我們將討論如何遷移Vue2應(yīng)用到Vue3。 Vue3提供了一些新特性和改進(jìn),例如更好的性能、響應(yīng)式API的改進(jìn)、更好的TypeScript支持等等。此外,Vue3還提

    2024年02月16日
    瀏覽(12)
  • Vue使用markdown編輯器

    1.安裝 2.main.js全局注冊 3.vue頁面使用 4.文章預(yù)覽

    2024年01月25日
    瀏覽(25)
  • 前端技術(shù)Html,Css,JavaScript,Vue3

    1.基本標(biāo)簽 2.文本格式化 3.鏈接 4.圖片 5.無序列表 6.有序列表 7.表格 8.表單 1.選擇器 2.文本和字體 3.鏈接 4.隱藏 5.定位position 6.浮動 7.對齊 8.圖像 1.輸出 2.函數(shù) 3.常用事件 4.DOM 5.改變Html 6.DOM 元素 (節(jié)點) 尾部創(chuàng)建新的 HTML 元素 (節(jié)點) - appendChild() 頭部創(chuàng)建新的 HTML 元素 (節(jié)點)

    2024年02月13日
    瀏覽(53)
  • VS Code 配置 Vue3 模板 詳細(xì)步驟

    VS Code 配置 Vue3 模板 詳細(xì)步驟

    1、打開 VS Code ,在頁面左下角找到這個設(shè)置圖標(biāo),然后找到 “用戶代碼片段” ? 2、接著點擊 “新建全局代碼片段文件” ?3、在輸入框中輸入你要設(shè)置的模板名,然后回車確認(rèn) 4、接下來配置自己想要模板代碼,或者也可以借鑒我寫的這個,具體根據(jù)自己的需求來配置 5、接

    2024年01月15日
    瀏覽(17)
  • vue3安裝eslint和prettier,最簡單的步驟

    vue3安裝eslint和prettier,最簡單的步驟

    ? 第1步: 安裝eslint ?第2步: 在根文件夾中,創(chuàng)建.eslintrc.js文件 ?第3步: 在package.json文件中新增命令 第4步: 安裝eslint-plugin-vue 第5步: 安裝prettier ?第6步: 在根文件夾創(chuàng)建 .prettierrc.js文件 第7步: 安裝eslint-config-prettier 第8步: 安裝eslint-plugin-prettier 第9步: 在.eslintrc.js文

    2024年02月05日
    瀏覽(19)
  • vite+vue3+ts項目構(gòu)建詳細(xì)步驟(配置多語言版本)

    vite+vue3+ts項目構(gòu)建詳細(xì)步驟(配置多語言版本)

    時過境遷,我們見證了諸如 webpack、Rollup 和 Parcel 等工具的變遷,它們極大地改善了前端開發(fā)者的開發(fā)體驗。 然而,當(dāng)我們開始構(gòu)建越來越大型的應(yīng)用時,需要處理的 JavaScript 代碼量也呈指數(shù)級增長。包含數(shù)千個模塊的大型項目相當(dāng)普遍?;?JavaScript 開發(fā)的工具就會開始遇

    2024年02月05日
    瀏覽(23)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包