最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Vue3+Vite實(shí)現(xiàn)一個(gè)Markdown編輯器組件

 更新時(shí)間:2025年04月10日 09:58:48   作者:前端極客探險(xiǎn)家  
在現(xiàn)代前端開(kāi)發(fā)中,Markdown 編輯器廣泛應(yīng)用于博客,文檔,Wiki,代碼注釋等場(chǎng)景,本文將使用 Vue 3 構(gòu)建一個(gè)簡(jiǎn)單的 Markdown 編輯器組件,感興趣的小伙伴可以了解下

一、項(xiàng)目背景與需求分析

在現(xiàn)代前端開(kāi)發(fā)中,Markdown 編輯器廣泛應(yīng)用于博客、文檔、Wiki、代碼注釋等場(chǎng)景。一個(gè)優(yōu)秀的 Markdown 編輯器需要具備以下功能:

  • 實(shí)時(shí)預(yù)覽:用戶輸入時(shí),能夠看到實(shí)時(shí)的渲染效果。
  • 語(yǔ)法高亮:支持 Markdown 語(yǔ)法的實(shí)時(shí)高亮顯示。
  • 導(dǎo)出功能:支持將編輯的內(nèi)容導(dǎo)出為 Markdown 或 HTML 格式,方便分享和存檔。
  • 自動(dòng)保存:避免用戶丟失未保存內(nèi)容。
  • 文件上傳:支持上傳文件(如圖片),并在 Markdown 內(nèi)容中嵌入顯示。

本文將使用 Vue 3 構(gòu)建一個(gè)簡(jiǎn)單的 Markdown 編輯器組件,并實(shí)現(xiàn)上述基本功能。

二、搭建基礎(chǔ)項(xiàng)目

1. 初始化 Vue 3 項(xiàng)目

我們使用 Vite 來(lái)初始化 Vue 3 項(xiàng)目,并選擇 TypeScript 模板:

npm create vite@latest markdown-editor --template vue-ts
cd markdown-editor

2. 安裝依賴

接下來(lái),我們安裝實(shí)現(xiàn) Markdown 渲染和語(yǔ)法高亮所需要的依賴:

marked:用于將 Markdown 轉(zhuǎn)換為 HTML。

highlight.js:用于提供 Markdown 語(yǔ)法的高亮顯示。

npm install marked highlight.js

三、實(shí)現(xiàn) Markdown 編輯器組件

1. 創(chuàng)建 Markdown 編輯器組件

在 src/components 目錄下創(chuàng)建 MarkdownEditor.vue 文件,封裝 Markdown 編輯器功能。

<template>
  <div class="markdown-editor">
    <textarea
      v-model="content"
      class="editor-textarea"
      placeholder="請(qǐng)輸入 Markdown 內(nèi)容..."
      @input="saveToLocalStorage"
    ></textarea>
    <div class="preview">
      <div v-html="renderedContent" class="preview-content"></div>
    </div>
    <div class="export-buttons">
      <button @click="exportMarkdown">導(dǎo)出 Markdown</button>
      <button @click="exportHTML">導(dǎo)出 HTML</button>
    </div>
    <div class="file-upload">
      <input type="file" @change="handleFileUpload" />
      <p>上傳圖片并在 Markdown 中顯示</p>
    </div>
  </div>
</template>

<script lang="ts">
import { defineComponent, ref, computed, onMounted } from 'vue';
import { marked } from 'marked';
import hljs from 'highlight.js';

export default defineComponent({
  name: 'MarkdownEditor',
  setup() {
    const content = ref('');
    const fileUrl = ref<string | null>(null);

    // 從本地存儲(chǔ)加載內(nèi)容
    onMounted(() => {
      const savedContent = localStorage.getItem('markdown-content');
      if (savedContent) {
        content.value = savedContent;
      }
    });

    // 將 Markdown 轉(zhuǎn)換為 HTML 并加上語(yǔ)法高亮
    const renderedContent = computed(() => {
      marked.setOptions({
        highlight: (code: string) => {
          return hljs.highlightAuto(code).value;
        },
      });
      return marked(content.value);
    });

    // 保存內(nèi)容到本地存儲(chǔ)(自動(dòng)保存)
    const saveToLocalStorage = () => {
      localStorage.setItem('markdown-content', content.value);
    };

    // 導(dǎo)出 Markdown 內(nèi)容
    const exportMarkdown = () => {
      const blob = new Blob([content.value], { type: 'text/markdown' });
      const url = URL.createObjectURL(blob);
      const link = document.createElement('a');
      link.href = url;
      link.download = 'document.md';
      link.click();
    };

    // 導(dǎo)出 HTML 內(nèi)容
    const exportHTML = () => {
      const blob = new Blob([renderedContent.value], { type: 'text/html' });
      const url = URL.createObjectURL(blob);
      const link = document.createElement('a');
      link.href = url;
      link.download = 'document.html';
      link.click();
    };

    // 文件上傳功能
    const handleFileUpload = (event: Event) => {
      const fileInput = event.target as HTMLInputElement;
      const file = fileInput.files ? fileInput.files[0] : null;
      if (file) {
        const reader = new FileReader();
        reader.onload = () => {
          const imageUrl = reader.result as string;
          fileUrl.value = imageUrl; // 存儲(chǔ)圖片的 URL
          const markdownImage = `![image](${imageUrl})`; // 將圖片路徑轉(zhuǎn)化為 Markdown 格式
          content.value += `\n\n${markdownImage}\n`; // 插入到 Markdown 內(nèi)容中
        };
        reader.readAsDataURL(file); // 將圖片讀取為 Data URL
      }
    };

    return {
      content,
      renderedContent,
      exportMarkdown,
      exportHTML,
      handleFileUpload,
    };
  },
});
</script>

<style scoped>
.markdown-editor {
  display: flex;
  flex-direction: column;
  gap: 20px;
  padding: 20px;
}

.editor-textarea {
  width: 100%;
  height: 300px;
  padding: 10px;
  font-size: 16px;
  line-height: 1.5;
  border: 1px solid #ccc;
  border-radius: 8px;
  resize: none;
}

.preview {
  background-color: #f8f8f8;
  padding: 20px;
  border: 1px solid #ccc;
  border-radius: 8px;
  min-height: 300px;
}

.preview-content {
  max-width: 100%;
  word-wrap: break-word;
}

.export-buttons {
  display: flex;
  gap: 10px;
}

button {
  padding: 10px 20px;
  background-color: #007bff;
  color: white;
  border: none;
  border-radius: 8px;
  cursor: pointer;
}

button:hover {
  background-color: #0056b3;
}

.file-upload {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

input[type="file"] {
  padding: 5px;
}
</style>

2. 組件說(shuō)明

Markdown 渲染:通過(guò) marked 將用戶輸入的 Markdown 內(nèi)容轉(zhuǎn)換為 HTML。

語(yǔ)法高亮:使用 highlight.js 對(duì)代碼塊進(jìn)行高亮顯示,增強(qiáng)代碼閱讀性。

導(dǎo)出功能:支持將 Markdown 或 HTML 內(nèi)容導(dǎo)出為文件,方便用戶保存或分享。

自動(dòng)保存功能:使用 localStorage 自動(dòng)保存 Markdown 內(nèi)容,避免用戶丟失未保存的輸入。

文件上傳支持:允許用戶上傳圖片文件,并將圖片插入到 Markdown 內(nèi)容中,生成合適的 Markdown 格式。

四、優(yōu)化與拓展

1. 自動(dòng)保存功能

通過(guò) localStorage 實(shí)現(xiàn)了自動(dòng)保存功能。每次用戶輸入內(nèi)容時(shí),Markdown 編輯器的內(nèi)容會(huì)自動(dòng)存儲(chǔ)到瀏覽器的本地存儲(chǔ)中。當(dāng)用戶刷新頁(yè)面或重新加載時(shí),保存的內(nèi)容會(huì)自動(dòng)恢復(fù)。這樣能有效避免用戶因刷新或?yàn)g覽器崩潰導(dǎo)致的數(shù)據(jù)丟失。

// 保存內(nèi)容到本地存儲(chǔ)(自動(dòng)保存)
const saveToLocalStorage = () => {
  localStorage.setItem('markdown-content', content.value);
};

2. 文件上傳功能

我們通過(guò) HTML5 的 FileReader API 實(shí)現(xiàn)了文件上傳支持。當(dāng)用戶上傳圖片文件時(shí),圖片會(huì)轉(zhuǎn)換為 Data URL,并自動(dòng)插入到 Markdown 內(nèi)容中。Markdown 內(nèi)容將以 ![image](image-url) 格式顯示上傳的圖片。

// 文件上傳功能
const handleFileUpload = (event: Event) => {
  const fileInput = event.target as HTMLInputElement;
  const file = fileInput.files ? fileInput.files[0] : null;
  if (file) {
    const reader = new FileReader();
    reader.onload = () => {
      const imageUrl = reader.result as string;
      fileUrl.value = imageUrl; // 存儲(chǔ)圖片的 URL
      const markdownImage = `![外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來(lái)直接上傳](https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=%24%7BimageUrl%7D&pos_id=img-QEVKHwoM-1744165078772)`; // 將圖片路徑轉(zhuǎn)化為 Markdown 格式
      content.value += `\n\n${markdownImage}\n`; // 插入到 Markdown 內(nèi)容中
    };
    reader.readAsDataURL(file); // 將圖片讀取為 Data URL
  }
};

五、總結(jié)

通過(guò) Vue 3 和 marked、highlight.js,我們實(shí)現(xiàn)了一個(gè)功能完善的 Markdown 編輯器組件。這個(gè)組件不僅支持實(shí)時(shí)預(yù)覽,還具備了語(yǔ)法高亮與導(dǎo)出功能,極大地方便了用戶的文檔編輯與分享需求。同時(shí),自動(dòng)保存功能和文件上傳功能進(jìn)一步提升了編輯器的可用性和用戶體驗(yàn)。

該組件可以輕松地集成到任何 Vue 3 項(xiàng)目中,為你的應(yīng)用增添強(qiáng)大的編輯能力。

到此這篇關(guān)于Vue3+Vite實(shí)現(xiàn)一個(gè)Markdown編輯器組件的文章就介紹到這了,更多相關(guān)Vue3 Markdown編輯器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • vue前端獲取不同客戶端mac地址最詳細(xì)步驟(避免踩坑)

    vue前端獲取不同客戶端mac地址最詳細(xì)步驟(避免踩坑)

    在開(kāi)發(fā)過(guò)程中,綁定賬號(hào)和電腦的功能可以通過(guò)獲取電腦的MAC地址實(shí)現(xiàn),下面這篇文章主要介紹了vue前端獲取不同客戶端mac地址的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-10-10
  • 在nuxt中使用路由重定向的實(shí)例

    在nuxt中使用路由重定向的實(shí)例

    這篇文章主要介紹了在nuxt中使用路由重定向的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-11-11
  • Flutter部件內(nèi)部狀態(tài)管理小結(jié)之實(shí)現(xiàn)Vue的v-model功能

    Flutter部件內(nèi)部狀態(tài)管理小結(jié)之實(shí)現(xiàn)Vue的v-model功能

    本文是 Flutter 部件內(nèi)部狀態(tài)管理的小結(jié),從部件的基礎(chǔ)開(kāi)始,到部件的狀態(tài)管理,并且在過(guò)程中實(shí)現(xiàn)一個(gè)類似 Vue 的 v-model 的功能,感興趣的朋友跟隨小編一起看看吧
    2019-06-06
  • vue 1.x 交互實(shí)現(xiàn)仿百度下拉列表示例

    vue 1.x 交互實(shí)現(xiàn)仿百度下拉列表示例

    本篇文章主要介紹了vue 1.x 交互實(shí)現(xiàn)仿百度下拉列表示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-10-10
  • Vue關(guān)于組件化開(kāi)發(fā)知識(shí)點(diǎn)詳解

    Vue關(guān)于組件化開(kāi)發(fā)知識(shí)點(diǎn)詳解

    在本篇文章里,小編給大家分享的是關(guān)于Vue關(guān)于組件化開(kāi)發(fā)知識(shí)點(diǎn)詳解內(nèi)容,有興趣的朋友們可以學(xué)習(xí)下。
    2020-05-05
  • vue實(shí)現(xiàn)文章點(diǎn)贊和差評(píng)功能

    vue實(shí)現(xiàn)文章點(diǎn)贊和差評(píng)功能

    這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)文章點(diǎn)贊和差評(píng)功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • 記VUE3+TS獲取組件類型的方法踩坑及解決

    記VUE3+TS獲取組件類型的方法踩坑及解決

    這篇文章主要介紹了VUE3+TS獲取組件類型的方法踩坑及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • 淺談Vue下使用百度地圖的簡(jiǎn)易方法

    淺談Vue下使用百度地圖的簡(jiǎn)易方法

    本篇文章主要介紹了淺談Vue下使用百度地圖的簡(jiǎn)易方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-03-03
  • vue組件系列之TagsInput詳解

    vue組件系列之TagsInput詳解

    TagsInput 是一種可編輯的輸入框,通過(guò)回車或者分號(hào)來(lái)分割每個(gè)標(biāo)簽,用回退鍵刪除上一個(gè)標(biāo)簽。這篇文章主要介紹了vue組件TagsInput的相關(guān)知識(shí),需要的朋友可以參考下
    2020-05-05
  • 解決vue3中內(nèi)存泄漏的問(wèn)題

    解決vue3中內(nèi)存泄漏的問(wèn)題

    在項(xiàng)目中會(huì)發(fā)現(xiàn)一個(gè)奇怪的現(xiàn)象,當(dāng)我們?cè)谑褂胑lement-plus中的圖標(biāo)組件時(shí)會(huì)出現(xiàn)內(nèi)存泄漏,所以本文講給大家講講如何解決vue3中的內(nèi)存泄漏的問(wèn)題,需要的朋友可以參考下
    2023-07-07

最新評(píng)論

东海县| 额尔古纳市| 庆城县| 松桃| 河东区| 黎平县| 朝阳区| 聊城市| 图片| 海兴县| 海盐县| 冕宁县| 台北市| 四平市| 贵南县| 吉安市| 台山市| 巨野县| 莱芜市| 开江县| 赤城县| 五家渠市| 北川| 县级市| 琼海市| 抚州市| 武功县| 凯里市| 泉州市| 彭阳县| 新河县| 阜康市| 临朐县| 皮山县| 太仓市| 神木县| 洛南县| 许昌市| 铁力市| 财经| 常德市|