EP29 - ex1. Markdown

更新於 發佈於 閱讀時間約 17 分鐘
看官方文件看個幾篇就好累~
終於輪到實用範例摟!
這篇要做一個Markdown編輯器,真的假的?!?

首先在開啟第二組實用練習之前,我要把先前的範例整理到一個View裡頭,先前的邏輯是 index.html ⮕ main.js ⮕ App.vue 再把畫面渲染到id=App的元素上,現在要將資料夾內容改成以下的狀況,目的是要把一些練習組件放在Views裡頭管理

raw-image

Vue Router

研究一下可以用vue router來控管一下view頁面,先來去npm安裝一下。

raw-image


安裝指令:

npm install vue-router@4

安裝完之後,要進行入口修改一下
創建Router資料夾,並建立index.js




修改入口 - main.js

import './assets/main.css'

import { createApp } from 'vue'
import App from './App.vue'
import router from './router';


// createApp(App).mount('#app')
createApp(App).use(router).mount('#app');

新增router - router/index.js

import { createRouter, createWebHistory } from 'vue-router';
import BasicExamples from '../views/BasicExamples.vue';
import PracticalExamples from '../views/PracticalExamples.vue';

const routes = [
{ path: '/basic-examples', component: BasicExamples },
{ path: '/practical-examples', component: PracticalExamples },
];

const router = createRouter({
history: createWebHistory(),
routes,
});

export default router;

修改#app - App.vue

<script setup>
import { RouterView } from 'vue-router';
</script>

<template>
<div class="app-container">
<div class="nav-container">
<div class="card">
<router-link to="/basic-examples">Basic Examples</router-link>
</div>
<div class="card">
<router-link to="/practical-examples">Practical Examples</router-link>
</div>
</div>
<div class="content-container">
<RouterView />
</div>
</div>
</template>


<style>
.app-container {
display: flex;
/* 使用 Flexbox 排版 */
width: 100%;
}

.nav-container {
display: flex;
flex-direction: column;
/* 使導航項目垂直排列 */
margin: 2rem 0;
gap: 1rem;
/* 設定導航欄的寬度 */
width: 200px;
/* 導航欄固定寬度 */
}

.card {
background: white;
border: 1px solid #ddd;
border-radius: 8px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
padding: 2rem;
text-align: center;
transition: transform 0.2s;
}

.card:hover {
transform: scale(1.05);
}

.card a {
color: #42b983;
text-decoration: none;
font-size: 1.2rem;
font-weight: bold;
}

.card a:hover {
text-decoration: underline;
}

.content-container {
/* max-width: 1200px; */
/* 最大寬度 */
width: 100%;
/* 寬度100% */
margin: 0 auto;
/* 自動左右邊距使其居中 */
padding: 20px;
/* 內邊距 */
}

@media (min-width: 1024px) {
#app {
display: block;
/* 使用 block 或其他佈局 */
/* 移除 grid-template-columns */
padding: 0 2rem;
/* 保留內邊距 */
}
}
</style>

有了router之後,邏輯變成這樣

index.html ⮕ main.js ⮕ App.vue + index.js

Vue Router 的效果與運作原理

Vue Router 是 Vue.js 的官方路由管理器,用於構建單頁應用程序 (SPA)。它的主要功能是根據當前的 URL 路徑來顯示不同的視圖組件。以下是 Vue Router 的運作過程和效果的簡要說明:

  • 初始化:應用程序啟動時,index.html 中的 div 元素設置了 id="app"。這個 div 是 Vue 應用的根容器。
  • 主入口:在 main.js 中,創建了 Vue 應用實例,並將它掛載到 #app 元素上。同時,Vue Router 被引入並使用。
  • 根組件App.vue 作為根組件,其中包含了導航欄和 RouterViewRouterView 是一個占位組件,會根據當前路由顯示相應的視圖。
  • 路由配置:在 router/index.js 中定義了路由配置,這些配置決定了 URL 對應哪個組件。
  • 導航:通過 <router-link> 元素創建的導航鏈接,可以在應用內部切換不同的路徑,從而改變 RouterView 中顯示的內容。

調整樣式和結構

為了確保內容區域在寬螢幕下顯示正常,移除不必要的樣式,並確保 #app 沒有多餘的樣式影響:

@media (min-width: 1024px) {
#app {
display: block; /* 使用 block 或其他佈局 */
/* 移除 grid-template-columns */
padding: 0 2rem; /* 保留內邊距 */
}
}

範例 - MarkDown

先安裝所需套件

// 範例 安裝套件
npm install marked
npm install lodash-es

程式碼 (60行)

<!--
A simple markdown editor.
-->

<script setup>
import { marked } from 'marked'
import { debounce } from 'lodash-es'
import { ref, computed } from 'vue'

const input = ref('# hello')

const output = computed(() => marked(input.value))

const update = debounce((e) => {
input.value = e.target.value
}, 100)
</script>

<template>
<p>Example 1:</p>
<div class="editor">
<textarea class="input" :value="input" @input="update"></textarea>
<div class="output" v-html="output"></div>
</div>
</template>

<style>
body {
margin: 0;
}

.editor {
height: 100vh;
display: flex;
}

.input,
.output {
overflow: auto;
width: 50%;
height: 100%;
box-sizing: border-box;
padding: 0 20px;
}

.input {
border: none;
border-right: 1px solid #ccc;
resize: none;
outline: none;
background-color: #f6f6f6;
font-size: 14px;
font-family: 'Monaco', courier, monospace;
padding: 20px;
}

code {
color: #f66;
}
</style>

<script setup> 部分

引入模組

<script setup>
import { marked } from 'marked' // 引入 marked 庫,用於將 Markdown 轉換為 HTML
import { debounce } from 'lodash-es' // 引入 lodash-es 的 debounce 函數,用於防止頻繁觸發輸入事件
import { ref, computed } from 'vue' // 從 Vue 中引入 ref 和 computed 函數

定義狀態和計算屬性

const input = ref('# hello')  // 定義一個 ref 變數 input,初始值為 '# hello'

const output = computed(() => marked(input.value)) // 定義一個 computed 屬性 output,值為將 input 的值轉換為 HTML 後的結果

定義更新函數

const update = debounce((e) => {
input.value = e.target.value // 定義一個 update 函數,使用 debounce 來限制頻繁觸發。當輸入框內容變化時,更新 input 的值
}, 100) // debounce 時間設置為 100 毫秒
</script>

<template> 部分

<template>
<p>Example 1:</p> <!-- 顯示一個標題 "Example 1:" -->
<div class="editor">
<textarea class="input" :value="input" @input="update"></textarea> <!-- 輸入框,綁定 input 變數,當輸入變化時觸發 update 函數 -->
<div class="output" v-html="output"></div> <!-- 輸出區域,顯示由 output 計算屬性生成的 HTML -->
</div>
</template>

<style> 部分

body {
margin: 0; // 設置 body 元素的 margin 為 0,去除預設的外邊距
}

.editor {
height: 100vh; // 設置編輯器的高度為視窗高度的 100%
display: flex; // 使用 flexbox 排版
}

.input,
.output {
overflow: auto; // 設置溢出時顯示滾動條
width: 50%; // 設置輸入和輸出區域的寬度各占 50%
height: 100%; // 設置高度為 100%
box-sizing: border-box; // 設置 box-sizing 為 border-box,包含 padding 和 border 在內的總寬度和高度
padding: 0 20px; // 設置左右 padding 為 20px
}

.input {
border: none; // 移除邊框
border-right: 1px solid #ccc; // 設置右邊框為 1px 寬的實線,顏色為 #ccc
resize: none; // 禁止調整大小
outline: none; // 移除聚焦時的外輪廓
background-color: #f6f6f6; // 設置背景顏色為 #f6f6f6
font-size: 14px; // 設置字體大小為 14px
font-family: 'Monaco', courier, monospace; // 設置字體為 Monaco, courier, monospace
padding: 20px; // 設置內邊距為 20px
}

code {
color: #f66; // 設置 code 元素的字體顏色為 #f66
}
</style>

總結

這個 Markdown 編輯器主要分為三個部分:

  1. 輸入區域:使用 <textarea> 元素來輸入 Markdown 內容,並綁定到 Vue 的 input 變數。
  2. 輸出區域:使用 <div> 元素來顯示轉換後的 HTML 內容,並綁定到 Vue 的 output 計算屬性。
  3. 樣式設置:使用 CSS 來設置輸入和輸出區域的佈局和樣式,使其在視窗中占據對稱的空間。

透過 marked 將 Markdown 轉換為 HTML,並使用 lodash-esdebounce 函數來防止頻繁觸發輸入事件,這樣可以避免性能問題。

經由import了兩個套件,以及短短的60行就實現了一個簡易的Markdown編輯器,
真的蠻有趣的!!!藉此也了解到debounce函數的用法~
然後慢慢地把範例檔案集中在這裡~Readme等有空再整理~ vue example

以下是測試Markdown的效果,大家快來玩看看吧~

raw-image





留言
avatar-img
留言分享你的想法!
avatar-img
卡關的人生
2會員
73內容數
分享生活趣事~
卡關的人生的其他內容
2024/11/10
Vue 提供了多種動畫技術來提升應用程式的互動性,包括基於 CSS 類別的動畫、基於狀態的動畫,以及使用監視器來動畫化數值。基於類別的動畫可通過動態添加 CSS 類別來觸發,像是觸發按鈕搖動效果。基於狀態的動畫則是透過樣式綁定,根據互動動態調整元素的外觀,例如根據滑鼠位置改變背景顏色。
Thumbnail
2024/11/10
Vue 提供了多種動畫技術來提升應用程式的互動性,包括基於 CSS 類別的動畫、基於狀態的動畫,以及使用監視器來動畫化數值。基於類別的動畫可通過動態添加 CSS 類別來觸發,像是觸發按鈕搖動效果。基於狀態的動畫則是透過樣式綁定,根據互動動態調整元素的外觀,例如根據滑鼠位置改變背景顏色。
Thumbnail
2024/11/09
Web Components 是一組網頁原生 API,允許開發者創建可重複使用的自訂元素。Vue 與 Web Components 是互補的技術,Vue 支援整合和創建自訂元素。
Thumbnail
2024/11/09
Web Components 是一組網頁原生 API,允許開發者創建可重複使用的自訂元素。Vue 與 Web Components 是互補的技術,Vue 支援整合和創建自訂元素。
Thumbnail
2024/11/08
Vue 建議使用模板構建應用程式,但在需要 JavaScript 的全程式化功能時,渲染函數可派上用場。渲染函數通過 h() 函數創建 vnode,h 是 hyperscript 的簡寫,能生成 HTML 的 JavaScript。
Thumbnail
2024/11/08
Vue 建議使用模板構建應用程式,但在需要 JavaScript 的全程式化功能時,渲染函數可派上用場。渲染函數通過 h() 函數創建 vnode,h 是 hyperscript 的簡寫,能生成 HTML 的 JavaScript。
Thumbnail
看更多
你可能也想看
Thumbnail
孩子寫功課時瞇眼?小心近視!這款喜光全光譜TIONE⁺光健康智慧檯燈,獲眼科院長推薦,網路好評不斷!全光譜LED、180cm大照明範圍、5段亮度及色溫調整、350度萬向旋轉,讓孩子學習更舒適、保護眼睛!
Thumbnail
孩子寫功課時瞇眼?小心近視!這款喜光全光譜TIONE⁺光健康智慧檯燈,獲眼科院長推薦,網路好評不斷!全光譜LED、180cm大照明範圍、5段亮度及色溫調整、350度萬向旋轉,讓孩子學習更舒適、保護眼睛!
Thumbnail
創作者營運專員/經理(Operations Specialist/Manager)將負責對平台成長及收入至關重要的 Partnership 夥伴創作者開發及營運。你將發揮對知識與內容變現、影響力變現的精準判斷力,找到你心中的潛力新星或有聲量的中大型創作者加入 vocus。
Thumbnail
創作者營運專員/經理(Operations Specialist/Manager)將負責對平台成長及收入至關重要的 Partnership 夥伴創作者開發及營運。你將發揮對知識與內容變現、影響力變現的精準判斷力,找到你心中的潛力新星或有聲量的中大型創作者加入 vocus。
Thumbnail
看官方文件好累,終於要來看實用範例摟!這篇要做一個Markdown編輯器,真的假的?!
Thumbnail
看官方文件好累,終於要來看實用範例摟!這篇要做一個Markdown編輯器,真的假的?!
Thumbnail
改稿真的不是一件需要太多情緒的事,把錯的挑出來、改掉,就這麼簡單!很少有什麼「大錯」需要去爭執誰對誰錯。不過真的滿多時候鬼遮眼或是偶爾真的會發生某種「明明前一版是對的,這一版居然是錯的」的鬼故事,把問題找出來解決就好!
Thumbnail
改稿真的不是一件需要太多情緒的事,把錯的挑出來、改掉,就這麼簡單!很少有什麼「大錯」需要去爭執誰對誰錯。不過真的滿多時候鬼遮眼或是偶爾真的會發生某種「明明前一版是對的,這一版居然是錯的」的鬼故事,把問題找出來解決就好!
Thumbnail
當自己是「編輯」,面對任務,先做出第一版再說 10月在一家社區舊書店做義工時,日常工作的一項是編輯活動貼文的文案,再發布到社交平台。這是練文筆、練習寫作的機會,所以心血來潮,捕捉到一點靈感時,我會去主動寫。寫完後,交由組員和同事修改。 有時大家修改完,我會發覺「啊,自己原先所寫的東西有點囉唆
Thumbnail
當自己是「編輯」,面對任務,先做出第一版再說 10月在一家社區舊書店做義工時,日常工作的一項是編輯活動貼文的文案,再發布到社交平台。這是練文筆、練習寫作的機會,所以心血來潮,捕捉到一點靈感時,我會去主動寫。寫完後,交由組員和同事修改。 有時大家修改完,我會發覺「啊,自己原先所寫的東西有點囉唆
Thumbnail
寫論文是一個奇怪的工作。 上上個星期終於完成了一篇期刊論文的草稿,然後作為通訊作者把文章提交到期刊的收稿系統裡面了。途中經歷了很多關卡,最後交稿之後不禁思考,如果待在學術界的話,這輩子會重複多少次這樣的歷程呢,想想覺得有點可怕。 第一關:英文寫作 我對我自己的英文寫作不是很有信心,先前考公務員
Thumbnail
寫論文是一個奇怪的工作。 上上個星期終於完成了一篇期刊論文的草稿,然後作為通訊作者把文章提交到期刊的收稿系統裡面了。途中經歷了很多關卡,最後交稿之後不禁思考,如果待在學術界的話,這輩子會重複多少次這樣的歷程呢,想想覺得有點可怕。 第一關:英文寫作 我對我自己的英文寫作不是很有信心,先前考公務員
Thumbnail
俗話說「萬事起頭難」還真是一點也沒錯,從開始動筆寫《The Nature of Code閱讀心得筆記——使用Python實作》,到寫完頭一章,再到把文章放上網站開始發表,總共隔了快三個月的時間。
Thumbnail
俗話說「萬事起頭難」還真是一點也沒錯,從開始動筆寫《The Nature of Code閱讀心得筆記——使用Python實作》,到寫完頭一章,再到把文章放上網站開始發表,總共隔了快三個月的時間。
Thumbnail
這是一份編輯工作,是一份我曾經做過類似內容的工作。
Thumbnail
這是一份編輯工作,是一份我曾經做過類似內容的工作。
Thumbnail
難怪一直跳行,工程師大大辛苦了。
Thumbnail
難怪一直跳行,工程師大大辛苦了。
Thumbnail
趁著新版的編輯器啟用,藉著發這篇文,再體驗一下有哪些使用體驗不良的地方。接著要說點站方或作者可能不是很愛聽的。
Thumbnail
趁著新版的編輯器啟用,藉著發這篇文,再體驗一下有哪些使用體驗不良的地方。接著要說點站方或作者可能不是很愛聽的。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News