欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

一、項目背景與需求分析

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

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

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

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

1. 初始化 Vue 3 項目

我們使用 Vite 來初始化 Vue 3 項目,并選擇 TypeScript 模板:

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

2. 安裝依賴

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

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

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

npm install marked highlight.js

三、實現(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="請輸入 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);

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

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

    // 保存內(nèi)容到本地存儲(自動保存)
    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; // 存儲圖片的 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. 組件說明

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

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

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

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

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

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

1. 自動保存功能

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

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

2. 文件上傳功能

我們通過 HTML5 的 FileReader API 實現(xiàn)了文件上傳支持。當(dāng)用戶上傳圖片文件時,圖片會轉(zhuǎn)換為 Data URL,并自動插入到 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; // 存儲圖片的 URL
      const markdownImage = `![外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳](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é)

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

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

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

相關(guān)文章

  • Vue3配置axios跨域?qū)崿F(xiàn)過程解析

    Vue3配置axios跨域?qū)崿F(xiàn)過程解析

    這篇文章主要介紹了Vue3配置axios跨域?qū)崿F(xiàn)過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-11-11
  • vue組件間的通信,子組件向父組件傳值的方式匯總

    vue組件間的通信,子組件向父組件傳值的方式匯總

    這篇文章主要介紹了vue組件間的通信,子組件向父組件傳值的方式匯總,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • vue2中如何自定義組件的v-model

    vue2中如何自定義組件的v-model

    這篇文章主要介紹了vue2中如何自定義組件的v-model,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • 深入理解vue中的scoped屬性

    深入理解vue中的scoped屬性

    vue中的 scoped 屬性,其實就是給每一個dom節(jié)點元素都添加了不重復(fù)的自定義屬性(如:data-v-6810cbe5),本文給大家介紹vue中的scoped屬性相關(guān)知識,感興趣的朋友一起看看吧
    2023-12-12
  • vue學(xué)習(xí)之Vue-Router用法實例分析

    vue學(xué)習(xí)之Vue-Router用法實例分析

    這篇文章主要介紹了vue學(xué)習(xí)之Vue-Router用法,結(jié)合實例形式分析了Vue-Router路由原理與常見操作技巧,需要的朋友可以參考下
    2020-01-01
  • 詳解vue組件之間的通信

    詳解vue組件之間的通信

    這篇文章主要介紹了vue組件之間的通信,幫助大家更好的理解和學(xué)習(xí)前端的相關(guān)知識,感興趣的朋友可以了解下
    2020-08-08
  • vue實現(xiàn)的多頁面項目如何優(yōu)化打包的步驟詳解

    vue實現(xiàn)的多頁面項目如何優(yōu)化打包的步驟詳解

    這篇文章主要介紹了vue實現(xiàn)的多頁面項目如何優(yōu)化打包的步驟詳解,文中通過示例代碼以及圖文介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • Vue項目安裝使用moment.js方式

    Vue項目安裝使用moment.js方式

    文章介紹了如何在Vue項目中安裝和使用moment.js,包括安裝步驟、導(dǎo)入方法、漢化設(shè)置以及在Vue實例中使用moment.js進(jìn)行日期處理
    2024-11-11
  • vue-cli2打包前和打包后的css前綴不一致的問題解決

    vue-cli2打包前和打包后的css前綴不一致的問題解決

    這篇文章主要介紹了vue-cli2打包前和打包后的css前綴不一致的問題解決,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-08-08
  • 一個因@click.stop引發(fā)的bug的解決

    一個因@click.stop引發(fā)的bug的解決

    這篇文章主要介紹了一個因@click.stop引發(fā)的bug的解決,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-01-01

最新評論