vue3實現markdown文檔轉HTML并可更換樣式

vue3實現markdown文檔轉HTML

安裝marked

npm install marked
<template><!-- 后臺可添加樣式編輯器 --><div class="markdown-editor" :class="{ 'fullscreen': isFullscreen, 'preview-mode': isPreviewMode }"><div class="editor-container"><!-- Markdown 輸入區域 --><div class="markdown-input" v-show="!isPreviewMode"><el-card class="editor-card"><template #header><div class="header"><div class="toolbar"><!-- 導出文件 --><el-button-group><el-button size="small" @click="exportFile" title="導出文件"><el-icon><Download /></el-icon></el-button></el-button-group><!-- 格式化工具 --><el-button-group><el-button size="small" @click="insertMarkdown('heading')" title="標題"><strong>H</strong></el-button><el-button size="small" @click="insertMarkdown('bold')" title="加粗"><strong>B</strong></el-button><el-button size="small" @click="insertMarkdown('italic')" title="斜體"><em>I</em></el-button><el-button size="small" @click="insertMarkdown('quote')" title="引用"><el-icon><ChatLineSquare /></el-icon></el-button><el-button size="small" @click="insertMarkdown('code')" title="代碼"><el-icon><Notebook /></el-icon></el-button><el-button size="small" @click="insertMarkdown('link')" title="鏈接"><el-icon><Link /></el-icon></el-button><el-button size="small" @click="insertMarkdown('image')" title="圖片"><el-icon><Picture /></el-icon></el-button><el-button size="small" @click="insertMarkdown('list')" title="列表"><el-icon><List /></el-icon></el-button></el-button-group><!-- 預覽控制 --><el-button-group><el-button size="small" @click="togglePreview" title="預覽模式" :type="isPreviewMode ? 'primary' : ''"class="preview-button"><el-icon><View /></el-icon>預覽</el-button></el-button-group></div></div></template><el-input v-model="markdownContent" type="textarea" :rows="20" placeholder="請輸入 Markdown 內容..."@input="handleContentChange" /></el-card></div><!-- HTML 預覽區域 --><div class="preview-container"><el-card class="preview-card"><template #header><div class="header"><div><span v-show="!isPreviewMode">HTML 預覽</span><el-button v-show="isPreviewMode" size="small" @click="togglePreview" title="退出預覽"class="preview-exit-button"><el-icon><Close /></el-icon>退出預覽</el-button></div><div style="display: flex; gap: 10px;align-items: center;"><!-- 預覽頁面導出為圖片 --><!-- <div class="export-img"><el-button size="small" @click="exportImg" title="下載png圖片"><el-icon><Download /></el-icon></el-button></div> --></div></div></template><div class="preview-content"><div class="card" ref="card"><div class="card-header"></div><div class="card-content"><div class="card-content-inner" v-html="htmlContent"></div></div><div class="card-footer"></div></div></div></el-card></div><div><!-- 樣式選擇區 --><el-card class="style-card"><template #header><div class="header"><span>style 選擇</span><el-button @click="handleAddStyle" size="small"  title="添加樣式"class="preview-exit-button"><el-icon><Close /></el-icon>添加樣式</el-button></div></template><!-- 樣式列表 --><div class="style-content"><divv-for="style in styleList":key="style.value"class="style-item":class="{ 'active': currentStyle === style.value }"@click="setStyle(style.value)">{{ style.name }}</div></div></el-card></div></div><!-- 添加樣式彈窗 --><AddStyleDialog ref="addStyleDialogRef" @confirm="handleStyleConfirm" @preview="handleStylePreview"></AddStyleDialog></div>
</template><script setup lang="ts">
import AddStyleDialog from './components/AddStyleDialog.vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { ref, onMounted, reactive,onUnmounted } from 'vue'
import { marked } from 'marked'
import {Download, ChatLineSquare, Notebook, Link,Picture, List, View, FullScreen
} from '@element-plus/icons-vue'const addStyleDialogRef = ref()
const editorContainerRef = ref<HTMLElement>()
const addedStyles = ref<{name: string; element: HTMLStyleElement}[]>([])const handleAddStyle = () => {addStyleDialogRef.value?.open()
}// 確認添加樣式
const handleStyleConfirm = () => {}// 預覽樣式
const handleStylePreview = (styleData: { name: string; code: string }) => {currentStyle.value = ''// 移除所有舊的樣式標簽const oldStyles = document.querySelectorAll('style[data-md-style]')oldStyles.forEach(style => style.remove())// 創建新的樣式標簽const styleTag = document.createElement('style')styleTag.type = 'text/css'styleTag.setAttribute('data-md-style', 'true') // 添加標識,方便后續刪除// 根據選擇的樣式設置內容styleTag.innerHTML = styleData.code// 插入到頁面頭部document.head.appendChild(styleTag)
}// 樣式列表
const styleList = [{name: '樣式1',value: 'style1'},{name: '樣式2',value: 'style2'}
]// 編輯器狀態
const markdownContent = ref('')
const currentStyle = ref('style1') // 默認選擇樣式1
const htmlContent = ref('')
const textareaRef = ref<HTMLTextAreaElement | null>(null)
const card: any = ref('')
const isPreviewMode = ref(false)
const isFullscreen = ref(false)// 編輯歷史
const history = reactive({past: [] as string[],future: [] as string[]
})// 文件操作函數
const exportFile = () => {const blob = new Blob([markdownContent.value], { type: 'text/markdown' })const url = URL.createObjectURL(blob)const a = document.createElement('a')a.href = urla.download = 'markdown.md'a.click()URL.revokeObjectURL(url)
}// 編輯歷史操作
const saveHistory = () => {history.past.push(markdownContent.value)history.future = []if (history.past.length > 50) {history.past.shift()}
}// 預覽控制
const togglePreview = () => {isPreviewMode.value = !isPreviewMode.value
}const toggleFullscreen = () => {const element = document.documentElementif (!isFullscreen.value) {if (element.requestFullscreen) {element.requestFullscreen()}} else {if (document.exitFullscreen) {document.exitFullscreen()}}isFullscreen.value = !isFullscreen.value
}let cssData1 = `
.card {max-width: 420px;background: #ffffff;border-radius: 16px;overflow: hidden;box-shadow: 0 4px 24px rgba(0, 0, 0, 0.06);font-family: 'PingFang SC', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif;line-height: 1.65;color: #333;margin: 24px auto;transition: all 0.3s ease;
}.card:hover {transform: translateY(-4px);box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
}.card-header {background: #ff2442;height: 6px;border-radius: 16px 16px 0 0;
}.card-content {padding: 32px;
}.card-content-inner {padding: 0;
}.card-content-inner > *:first-child {margin-top: 0;
}.card-content-inner > *:last-child {margin-bottom: 0;
}.card-content-inner h1 {font-size: 24px;font-weight: 700;margin: 0 0 24px;color: #1a1a1a;letter-spacing: -0.2px;line-height: 1.4;position: relative;padding-bottom: 16px;
}.card-content-inner h1:after {content: "";position: absolute;bottom: 0;left: 0;width: 36px;height: 3px;background: #ff2442;border-radius: 2px;
}.card-content-inner h2 {font-size: 20px;font-weight: 600;margin: 32px 0 20px;color: #2c2c2c;padding-bottom: 8px;border-bottom: 1px solid #f5f5f5;
}.card-content-inner p {font-size: 16px;margin: 0 0 24px;color: #444;text-align: justify;hyphens: auto;
}.card-content-inner ol,
.card-content-inner ul {padding-left: 24px;margin: 0 0 24px;
}.card-content-inner ol li,
.card-content-inner ul li {margin-bottom: 12px;padding-left: 8px;
}.card-content-inner ol li {position: relative;counter-increment: list-counter;
}.card-content-inner ol li::before {content: counter(list-counter);position: absolute;left: -26px;top: 2px;width: 20px;height: 20px;background: #ffebee;color: #ff2442;border-radius: 50%;display: flex;align-items: center;justify-content: center;font-size: 12px;font-weight: 600;
}.card-content-inner ul li::before {content: "?";color: #ff2442;font-weight: bold;display: inline-block;width: 1em;margin-left: -1em;
}.card-content-inner strong {color: #ff2442;font-weight: 600;
}.card-content-inner a {color: #ff2442;text-decoration: none;border-bottom: 1px solid rgba(255, 36, 66, 0.3);transition: all 0.2s ease;
}.card-content-inner a:hover {color: #e01e3c;border-bottom-color: #e01e3c;
}.card-content-inner code {background: #fff0f2;padding: 2px 6px;border-radius: 4px;font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;font-size: 14px;color: #ff2442;
}.card-content-inner pre {background: #fffafb;padding: 18px;border-radius: 8px;overflow-x: auto;margin: 0 0 24px;font-size: 14px;line-height: 1.5;border-left: 3px solid #ff2442;
}.card-content-inner pre code {background: none;padding: 0;color: #444;font-size: 14px;
}.card-content-inner blockquote {border-left: 3px solid #ffcdd2;padding: 4px 20px 4px 20px;margin: 0 0 24px;color: #666;background: #fffafa;border-radius: 0 8px 8px 0;font-style: italic;
}.card-content-inner hr {border: 0;height: 1px;background: linear-gradient(to right, rgba(255, 36, 66, 0.1), transparent);margin: 32px 0;
}.card-footer {padding: 16px 32px;background: #fffafa;border-top: 1px solid #f9f0f0;color: #999;font-size: 13px;display: flex;justify-content: space-between;
}/* 小紅書特色元素 */
.card-content-inner h1 + p {font-size: 17px;color: #666;margin-top: -8px;margin-bottom: 28px;
}.card-content-inner img {max-width: 100%;border-radius: 12px;margin: 24px 0;display: block;box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
}/* 留白增強 */
.card-content-inner p + h2 {margin-top: 36px;
}.card-content-inner ul + h2,
.card-content-inner ol + h2 {margin-top: 40px;
}
`
let cssData2 = `
.card {max-width: 680px;background: #ffffff;border-radius: 12px;overflow: hidden;box-shadow: 0 8px 30px rgba(0, 0, 0, 0.06);font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, sans-serif;line-height: 1.7;color: #333;margin: 40px auto;transition: transform 0.3s ease;
}.card:hover {transform: translateY(-3px);
}.card-header {background: linear-gradient(135deg, #6e8efb, #a777e3);height: 6px;border-radius: 12px 12px 0 0;
}.card-content {padding: 40px;
}.card-content-inner {padding: 0;
}.card-content-inner > *:first-child {margin-top: 0;
}.card-content-inner > *:last-child {margin-bottom: 0;
}.card-content-inner h1 {font-size: 28px;font-weight: 700;margin: 0 0 30px;color: #1a1a1a;letter-spacing: -0.01em;line-height: 1.3;
}.card-content-inner h2 {font-size: 22px;font-weight: 600;margin: 40px 0 20px;color: #2c2c2c;padding-bottom: 8px;border-bottom: 1px solid #f0f0f0;
}.card-content-inner h3 {font-size: 18px;font-weight: 600;margin: 35px 0 15px;color: #3a3a3a;
}.card-content-inner p {font-size: 17px;margin: 0 0 28px;color: #444;text-align: justify;hyphens: auto;
}.card-content-inner ol,
.card-content-inner ul {padding-left: 24px;margin: 0 0 28px;
}.card-content-inner ol li,
.card-content-inner ul li {margin-bottom: 12px;padding-left: 12px;
}.card-content-inner ol li {position: relative;counter-increment: list-counter;
}.card-content-inner ol li::before {content: counter(list-counter);position: absolute;left: -24px;top: 0;width: 24px;height: 24px;background: #f5f7ff;color: #6e8efb;border-radius: 50%;display: flex;align-items: center;justify-content: center;font-size: 13px;font-weight: 500;
}.card-content-inner ul li::before {content: "?";color: #a777e3;font-weight: bold;display: inline-block;width: 1em;margin-left: -1em;
}.card-content-inner strong {color: #2c2c2c;font-weight: 600;
}.card-content-inner em {font-style: italic;color: #555;
}.card-content-inner a {color: #6e8efb;text-decoration: none;border-bottom: 1px solid rgba(110, 142, 251, 0.3);transition: all 0.2s ease;
}.card-content-inner a:hover {color: #a777e3;border-bottom-color: #a777e3;
}.card-content-inner code {background: #f8f9ff;padding: 3px 6px;border-radius: 4px;font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;font-size: 15px;color: #6e8efb;
}.card-content-inner pre {background: #f8f9ff;padding: 20px;border-radius: 8px;overflow-x: auto;margin: 0 0 30px;font-size: 15px;line-height: 1.5;border-left: 3px solid #a777e3;
}.card-content-inner pre code {background: none;padding: 0;color: #444;font-size: 15px;
}.card-content-inner blockquote {border-left: 3px solid #e0e0e0;padding: 4px 20px 4px 24px;margin: 0 0 30px;color: #555;font-style: italic;background: #fafbff;border-radius: 0 8px 8px 0;
}.card-content-inner hr {border: 0;height: 1px;background: #f0f0f0;margin: 40px 0;
}.card-footer {padding: 20px 40px;background: #fafbff;border-top: 1px solid #f0f0f0;color: #777;font-size: 14px;display: flex;justify-content: space-between;
}/* 留白增強 */
.card-content-inner p + h2,
.card-content-inner ul + h2,
.card-content-inner ol + h2 {margin-top: 50px;
}.card-content-inner p + h3 {margin-top: 40px;
}.card-content-inner img {max-width: 100%;border-radius: 8px;margin: 30px 0;display: block;
}
`
const setStyle = (e:any) => {currentStyle.value = e// 移除所有舊的樣式標簽const oldStyles = document.querySelectorAll('style[data-md-style]')oldStyles.forEach(style => style.remove())// 創建新的樣式標簽const styleTag = document.createElement('style')styleTag.type = 'text/css'styleTag.setAttribute('data-md-style', 'true') // 添加標識,方便后續刪除// 根據選擇的樣式設置內容styleTag.innerHTML = currentStyle.value === 'style1' ? cssData1 : cssData2// 插入到頁面頭部document.head.appendChild(styleTag)
}// 配置marked選項
marked.setOptions({breaks: true, // 將回車轉換為 <br>gfm: true, // 啟用 GitHub 風格的 Markdown// sanitize: false, // 允許HTML標簽
})// 使用marked進行Markdown轉HTML
const convertMarkdownToHtml = (markdown: string): any => {return marked(markdown)
}// 處理內容變化
const handleContentChange = () => {saveHistory()updatePreview()
}// 更新預覽
const updatePreview = () => {htmlContent.value = convertMarkdownToHtml(markdownContent.value)
}// 在光標位置插入Markdown語法
const insertMarkdown = (type: string) => {const textarea = document.querySelector('.el-textarea__inner') as HTMLTextAreaElementif (!textarea) returnconst start = textarea.selectionStartconst end = textarea.selectionEndconst selected = markdownContent.value.substring(start, end)let insertion = ''switch (type) {case 'bold':insertion = `**${selected || '粗體文本'}**`breakcase 'italic':insertion = `*${selected || '斜體文本'}*`breakcase 'heading':insertion = `\n## ${selected || '標題'}\n`breakcase 'link':insertion = `[${selected || '鏈接文本'}](https://example.com)`breakcase 'list':insertion = `\n- ${selected || '列表項'}\n- 列表項\n- 列表項\n`breakcase 'quote':insertion = `\n> ${selected || '引用文本'}\n`breakcase 'code':insertion = selected ?`\`\`\`\n${selected}\n\`\`\`` :`\`\`\`\n代碼塊\n\`\`\``breakcase 'image':insertion = `![${selected || '圖片描述'}](https://example.com/image.jpg)`breakdefault:return}const newContent =markdownContent.value.substring(0, start) +insertion +markdownContent.value.substring(end)markdownContent.value = newContent// 保存歷史記錄saveHistory()// 更新預覽updatePreview()// 聚焦回文本區域setTimeout(() => {textarea.focus()const newCursorPos = start + insertion.lengthtextarea.setSelectionRange(newCursorPos, newCursorPos)}, 0)
}// 復制HTML到剪貼板
const copyHtml = () => {navigator.clipboard.writeText(htmlContent.value).then(() => {ElMessage({message: 'HTML已復制到剪貼板',type: 'success',duration: 2000})}).catch(err => {ElMessage({message: '復制失敗: ' + err,type: 'error',duration: 2000})})
}// 組件掛載時初始化
onMounted(() => {// 設置示例Markdown內容markdownContent.value = `# MD2Card> MD2Card 是一個 markdown 轉知識卡片工具,可以讓你用 Markdown 制作優雅的圖文海報。 🌟![](https://picsum.photos/600/300)## 它的主要功能:1. 將 Markdown 轉化為**知識卡片**
2. 多種主題風格任你選擇
3. 長文自動拆分,或者根據 markdown --- 橫線拆分
4. 可以復制圖片到剪貼板,或者下載為PNG、SVG圖片
5. 所見即所得
6. 免費
`updatePreview()// 初始化應用默認樣式setStyle(currentStyle.value)
})onUnmounted(()=>{// 移除所有的樣式標簽const oldStyles = document.querySelectorAll('style[data-md-style]')oldStyles.forEach(style => style.remove())
})
</script><style scoped lang="scss">
.markdown-editor {height: calc(100vh - 40px);box-sizing: border-box;overflow: hidden;
}.markdown-editor.fullscreen {position: fixed;top: 0;left: 0;right: 0;bottom: 0;z-index: 9999;padding: 0;
}.editor-container {height: 100%;display: flex;.markdown-input,.preview-container {flex: 1;height: 100%;overflow-y: auto;}.style-card{width: 260px;}
}.editor-card,
.preview-card,
.style-card {height: 100%;position: relative;transition: all 0.3s ease;display: flex;flex-direction: column;.preview-content{height: auto;}:deep(.el-card__body) {flex: 1;overflow: auto;padding: 0;display: flex;flex-direction: column;}/* Editor card specific styles */&.editor-card {:deep(.el-textarea) {flex: 1;display: flex;flex-direction: column;.el-textarea__inner {flex: 1;resize: none;border: none;box-shadow: none;padding: 20px;}}}/* Preview card specific styles */&.preview-card {height: 100%;:deep(.el-card__body) {// height: 100%;// overflow: auto;padding: 0;display: flex;flex-direction: column;}.card {flex: 1;min-height: 0; /* 修復flex容器滾動問題 */padding: 20px;}.card-content {height: auto;}}/* Style card specific styles */&.style-card {.style-content {flex: 1;overflow: auto;padding: 10px;.style-item {padding: 8px 12px;margin-bottom: 8px;border: 1px solid #e0deed;color: #0f0a29;background: #fff;border-radius: 4px;cursor: pointer;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;transition: all 0.2s ease;&:hover {border-color: #a598e5;}&.active {border-color: #4c33cc;color: #4c33cc;background: #f6f5fc;font-weight: 500;}}}}
}.header {display: flex;justify-content: space-between;align-items: center;
}.toolbar {display: flex;gap: 10px;
}/* 工具欄按鈕組之間的分隔 */
.toolbar .el-button-group+.el-button-group {margin-left: 8px;padding-left: 8px;border-left: 1px solid #dcdfe6;
}/* 激活狀態的按鈕樣式 */
:deep(.el-button--primary) {background-color: var(--el-color-primary-light-3);border-color: var(--el-color-primary-light-3);color: #fff;
}/* 預覽模式下的布局調整 */
.preview-button {z-index: 1000;
}.preview-mode {:deep(.el-row) {.el-col:first-child {display: none;}.el-col:last-child {width: 100%;position: relative;.preview-exit-button {position: absolute;top: 76px;left: 26px;z-index: 2000;background-color: #fff;box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);color: var(--el-text-color-primary);&:hover {background-color: var(--el-color-primary-light-9);}}}}.header .preview-button {display: none;}
}/* 預覽按鈕樣式 */
.preview-button {margin-right: 10px;
}/* 預覽模式下的退出按鈕樣式 */
.preview-exit-button {/* position: absolute;top: 10px;left: 10px;z-index: 2000; */background-color: #fff;box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);color: var(--el-text-color-primary);&:hover {background-color: var(--el-color-primary-light-9);}
}/* 全屏模式下的樣式調整 */
.fullscreen {:deep(.el-main) {padding: 0;}.editor-card,.preview-card {border-radius: 0;}
}/* 響應式布局 */
@media screen and (max-width: 768px) {.toolbar {flex-wrap: wrap;}.toolbar .el-button-group {margin-bottom: 8px;}.header {flex-direction: column;align-items: flex-start;gap: 10px;}
}
</style>

添加彈窗

<template><el-dialog v-model="dialogVisible" title="添加CSS樣式" width="700px" top="5vh"><div class="css-editor-container"><!-- 樣式名稱輸入框 --><el-inputv-model="styleName"placeholder="樣式名稱(如:my-style)"style="margin-bottom: 15px"/><!-- 帶有基本語法高亮的 CSS 編輯器 --><div class="code-editor-wrapper"><textareav-model="cssCode"@input="updateHighlight"class="code-input"spellcheck="false"placeholder="請輸入CSS代碼..."></textarea></div></div><!-- 底部按鈕 --><template #footer><span class="dialog-footer"><el-button @click="handlePreview">預覽</el-button><el-button type="primary" @click="handleConfirm">確認</el-button></span></template></el-dialog>
</template><script setup>
import { ref, computed } from 'vue'const dialogVisible = ref(false)
const styleName = ref('')
const cssCode = ref('')const updateHighlight = () => {// 自動更新高亮
}// 打開對話框
const open = () => {dialogVisible.value = truecssCode.value = ''styleName.value = ''
}// 確認按鈕處理函數
const emit = defineEmits(['confirm','preview'])
const handleConfirm = () => {// 打印輸入的CSS樣式和樣式名稱console.log('樣式名稱:', styleName.value)console.log('CSS樣式:', cssCode.value)// // 觸發confirm事件,將數據傳遞給父組件// emit('confirm', {//   name: styleName.value.trim(),//   code: cssCode.value.trim()// })// // 關閉對話框// dialogVisible.value = false
}const handlePreview = () => {// 預覽CSS樣式console.log('預覽CSS樣式:', cssCode.value)// // 觸發confirm事件,將數據傳遞給父組件emit('preview', {name: styleName.value.trim(),code: cssCode.value.trim()})// 關閉對話框dialogVisible.value = false
}defineExpose({ open })
</script><style scoped>
.css-editor-container {display: flex;flex-direction: column;
}.code-editor-wrapper {position: relative;height: 300px;border: 1px solid #dcdfe6;border-radius: 4px;overflow: hidden;margin-bottom: 15px;
}.code-highlight {position: absolute;top: 0;left: 0;width: 100%;height: 100%;margin: 0;padding: 10px;font-family: 'Courier New', monospace;font-size: 14px;line-height: 1.5;white-space: pre-wrap;word-wrap: break-word;overflow: auto;background: #f5f7fa;pointer-events: none;z-index: 1;
}.code-input {position: absolute;top: 0;left: 0;width: 100%;height: 100%;margin: 0;padding: 10px;font-family: 'Courier New', monospace;font-size: 14px;line-height: 1.5;color: #333;background: transparent;border: none;outline: none;resize: none;z-index: 2;
}/* 語法高亮樣式 */
.comment {color: #999;font-style: italic;
}.punctuation {color: #333;
}.selector {color: #905;
}.property {color: #07a;
}.value {color: #690;
}.dialog-footer {display: flex;justify-content: flex-end;gap: 10px;
}
</style>

注:
這是一個靜態的功能參考,在這里的樣式使用的給定的樣式切換,后續對接接口后可換成一個下拉列表,選擇后通過接口返回的css樣式數據來更換一樣的效果。這里預想的是回臺直接返回樣式的一個字符串格式內容,其他的想法可自行修改。
這里的css樣式只是使用了一個文本輸入框實現了功能效果,不帶樣式代碼高亮顯示的功能

在這里插入圖片描述
在這里插入圖片描述

樣式可使用deepseek來生成

復制這段文字,修改生成條件就可生成不同的樣式的css代碼,直接粘貼到css代碼輸入框中,點擊預覽就可看到新css樣式的效果。

/* 
可以讓 deepseek 等大模型實現css,實現卡片樣式自定義,以下是發送的提示詞模板:我需要在 md2card.com 實現自定義小紅書卡片樣式
以下是 md2card.com 中卡片的HTML結構:
```html
<div class="card"><div class="card-header"></div><div class="card-content"><div class="card-content-inner"><h1 data-text="標題">標題</h1><h2 data-text="標題二">標題二</h2><p>內容</p><ol><li data-index="0">列表</li></ol></div></div><div class="card-footer"></div>
</div>`card-content-inner` 為 markdown 編譯后的內容區域,還包括標題、列表、引用、代碼、加粗等常見 markdown 編譯的內容請為我設計一張卡片,其風格為“簡約現代”,可以進一步融入“留白”的設計理念,應用“小紅書知識分享”的場景
【設計風格要求】:
【輸入要求】:只需要返回 css 代碼*/
.card {
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/88186.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/88186.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/88186.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Temu 實時獲取商品動態:一個踩坑后修好的抓數腳本筆記

Temu 作為一個增長迅猛的購物平臺&#xff0c;其商品價格、庫存等信息&#xff0c;對許多做運營分析的小伙伴來說非常有參考價值。 我在寫這個小工具的時候&#xff0c;踩了很多坑&#xff0c;特別記錄下來&#xff0c;希望對你有用。 初版代碼&#xff1a;想當然的“直接來一下…

【軟考高級系統架構論文】論數據分片技術及其應用

論文真題 數據分片就是按照一定的規則,將數據集劃分成相互獨立、 正交的數據子集,然后將數據子集分布到不同的節點上。通過設計合理的數據分片規則,可將系統中的數據分布在不同的物理數據庫中,達到提升應用系統數據處理速度的目的。 請圍繞“論數據分片技術及其應用”論題…

VR飛奪瀘定橋沉浸式歷史再現?

當你戴上 VR 設備開啟這場震撼人心的 VR 飛奪瀘定橋體驗&#xff0c;瞬間就會被拉回到 1935 年那個戰火紛飛的 VR 飛奪瀘定橋的歲月&#xff0c;置身于瀘定橋的西岸 。映入眼簾的是一座由 13 根鐵索組成的瀘定橋&#xff0c;它橫跨在波濤洶涌的大渡河上&#xff0c;橋下江水咆哮…

libwebsockets編譯

#安裝 libwebsocket git clone https://github.com/warmcat/libwebsockets && \ mkdir libwebsockets/build && cd libwebsockets/build && \ cmake -DMAKE_INSTALL_PREFIX:PATH/usr -DCMAKE_C_FLAGS"-fpic" .. && \ make &&…

使用docker部署epg節目單,同時管理自己的直播源

配置 Docker 環境 拉取鏡像并運行&#xff1a; docker run -d \--name php-epg \-v /etc/epg:/htdocs/data \-p 5678:80 \--restart unless-stopped \taksss/php-epg:latest 默認數據目錄為 /etc/epg &#xff0c;根據需要自行修改 默認端口為 5678 &#xff0c;根據需要自行修…

H5新增屬性

? 一、表單相關新增屬性&#xff08;Form Attributes&#xff09; 這些屬性增強了表單功能&#xff0c;提升用戶體驗和前端驗證能力。 1. placeholder 描述&#xff1a;在輸入框為空時顯示提示文本。示例&#xff1a; <input type"text" placeholder"請輸…

【C++】簡單學——引用

引用的概念 為一個變量指定一個別名 引用的規則 用之前要初始化使用了之后就不能修改指向了&#xff08;對一個引用賦值實際上是對原本被引用的那個值進行賦值&#xff0c;而不是改變指向&#xff09;一個對象可以同時有多個引用 問&#xff1a;引用可以完全代替指針嗎&…

C#編程與1200PLC S7通信

讀取q0.0的狀態,i0.0的狀態實時在窗口更新 PLC里寫一個程序 用常閉按鈕接i0.0信號 &#xff0c;延時接通Q0.0 按按鈕&#xff0c;上位機測試效果, 2396fcfa823aa951d 程序前提是引用了S7通信文件 using Sharp7; using System; using System.Collections.Generic; using S…

el-table復選框分頁多選

場景&#xff1a; 你想要對el-table表格數據進行批量處理&#xff0c;會使用復選框&#xff0c;但如果表格的數據是分頁請求回來的&#xff0c;則在切換頁碼的時候&#xff0c;之前選中的數據會被清空掉&#xff0c;本文就是為了解決這個問題。 解決思路&#xff1a; 主要分…

大IPD之——學習華為的市場隊伍建設(二十)

企業要生存&#xff0c;就必須要擁有自己的核心競爭力。這樣在行業內與其他企業競爭時&#xff0c;才能立于不敗之地&#xff0c;而伴隨著企業的市場化&#xff0c;市場機制對企業價值創造的影響力越來越大。30多年來&#xff0c;華為高度重視市場隊伍與市場能力建設&#xff0…

Datawhlale_快樂學習大模型_task02_NLP 基礎概念

書籍地址 簡要總結一下個人理解 文章目錄 1.1 NLP1.2 發展歷程1.3 NLP任務1.3.1 中文分詞1.3.2 子詞切分1.3.3 詞性標注1.3.4 文本分類1.3.5 實體識別1.3.6 關系抽取1.3.7 文本摘要1.3.8 機器翻譯1.3.9 自動問答 1.4 文本表示的發展1.4.1 詞向量1.4.2 語言模型1.4.3 Word2Vec…

AUTOSAR圖解==>AUTOSAR_AP_SWS_Persistency

AUTOSAR 持久化功能集群解析 1. 引言 AUTOSAR (AUTomotive Open System ARchitecture) 適配平臺中的持久化功能集群(Persistency Functional Cluster)是一個核心組件&#xff0c;為應用程序提供數據持久化服務。本文檔詳細分析了AUTOSAR持久化功能集群的架構、主要組件和工作…

Ollama常用命令詳解:本地大語言模型管理指南

前言 Ollama是一個強大的本地大語言模型管理工具&#xff0c;讓我們可以輕松地在本地部署和運行各種開源大模型。本文將詳細介紹Ollama的核心命令使用方法&#xff0c;幫助您快速上手本地AI模型的管理和使用。 1. 查看已安裝模型 - ollama list 基本用法 ollama list功能說…

[免費]SpringBoot+Vue共享單車信息系統【論文+源碼+SQL腳本】

大家好&#xff0c;我是java1234_小鋒老師&#xff0c;看到一個不錯的SpringBootVue共享單車信息系統【論文源碼SQL腳本】&#xff0c;分享下哈。 項目視頻演示 【免費】SpringBootVue共享單車信息系統 Java畢業設計_嗶哩嗶哩_bilibili 項目介紹 快速發展的社會中&#xff…

內網提權-DC-3靶場實驗(Ubantu16.04)

靶場地址 https://download.vulnhub.com/dc/DC-3-2.zip 打開DC-3 使用kali掃描獲取靶場ip 目錄掃描獲取后臺地址 弱口令admin/snoopy進入后臺 此處可寫入一句話木馬 創建文件寫入一句話木馬 哥斯拉上線 使用lsb_release -a命令查看內核版本 方法一 使用ubuntu漏洞庫發現該…

Nginx:互斥鎖 accept_mutex配置

如何配置 Nginx 的互斥鎖 accept_mutex 1. 理解 accept_mutex 的作用 accept_mutex 是 Nginx 用于控制多工作進程&#xff08;worker processes&#xff09;接收新連接時避免「驚群問題&#xff08;Thundering Herd&#xff09;」的機制。 啟用時&#xff08;accept_mutex o…

aws(學習筆記第四十六課) codepipeline-build-deploy

文章目錄 aws(學習筆記第四十六課) codepipeline-build-deploy學習內容:1. 代碼鏈接及整體架構1.1 代碼鏈接1.2 整體架構1.2.1 初始化階段的`codecommit repo`以及`codebuild project`設定1.2.2 創建`vpc`,`public alb`,`alb listener`以及`fargate service`等1.2.3 創建`so…

Vue 項目中的組件職責劃分評審與組件設計規范制定

在現代前端系統中&#xff0c;Vue&#xff08;無論是 2.x 還是 3.x&#xff09;提供了良好的組件化機制&#xff0c;為構建復雜交互系統打下了基礎。然而&#xff0c;隨著項目規模增長&#xff0c;組件職責不清、代碼重疊、維護困難等問題頻發&#xff0c;嚴重影響開發效率與可…

react 的過渡動畫

一、React的過渡動畫 1、react-transition-group 在開發中&#xff0c;我們想要給一個組件的顯示和消失&#xff0c;添加某種過渡動畫&#xff0c;可以很好的增加用戶體驗&#xff0c; React社區為我們提供了react-transition-group用來完成過渡動畫&#xff0c; React曾為…

深度學習:PyTorch人工神經網絡優化方法分享(1)

本文目錄&#xff1a; 一、從梯度角度入手&#xff08;一&#xff09;梯度下降算法回顧&#xff08;二&#xff09;常用優化算法1.SGD&#xff08;Stochastic Gradient Descent&#xff09;- 隨機梯度下降2.BGD (Batch Gradient Descent) - 批量梯度下降3.MBGD (Mini-Batch Gra…