動態組件和插槽

[Vue2]動態組件和插槽

動態組件和插槽來實現外部傳入自定義渲染

組件

<template><!-- 回復的處理進度 --><div v-if="steps.length > 0" class="gain-box-header"><el-steps direction="vertical"><div class="load-but"><el-step v-for="item in steps" :key="item.id" :icon="getIcon(item)"><div slot="title" class="step_title" @click="item.isShow = !item.isShow"><div>{{ item.title || '加載中' }}</div><div><i v-if="item.isShow" class="el-icon-arrow-down"></i><i v-else class="el-icon-arrow-up"></i></div></div><template slot="description"><div v-show="item.isShow"><!-- 內置類型渲染 --><template v-if="item.type === NormalSteps.Markdown"><MdRender v-if="item.content" :content="item.content" /></template><template v-else-if="item.type === NormalSteps.Text"><div class="step_label">{{ item.content }}</div></template><template v-else-if="item.type === SpecialStep.RxtPolicyList"><div class="step_label">{{ item.content }}</div></template><!-- 自定義組件渲染 --><template v-else-if="isCustomComponent(item.type)"><component :is="getCustomComponent(item.type)" :item="item" :content="item.content":meta="item.meta"v-bind="item.props || {}"/></template><!-- 自定義插槽渲染 --><template v-else-if="isCustomSlot(item.type)"><slot :name="getSlotName(item.type)":item="item":content="item.content":meta="item.meta"><!-- 插槽默認內容 --><div class="step_label">{{ item.content }}</div></slot></template><!-- 自定義渲染函數 --><template v-else-if="isCustomRender(item.type)"><div v-html="getCustomRender(item.type, item)"></div></template><!-- 默認文本渲染 --><template v-else><div class="step_label">{{ item.content }}</div></template></div></template></el-step></div></el-steps></div>
</template><script>
import MdRender from '@/components/MdRender/think'
import { NormalSteps, SpecialStep } from '@/dicts/DictSse.js'export default {name: 'StepList',components: { MdRender },props: {steps: {type: Array,default: () => [// {//   id: '', // 唯一鍵//   type: 'md', // 類型//   title: '', // 標題//   content: '', // 內容//   isStop: false, // 是否結束//   isShow: true, // 是否展示//   isError: false, // 是否失敗 消息停止時改步驟未結束,則標記為失敗//   meta: {}, // 附加屬性//   props: {}, // 傳遞給自定義組件的額外props// }]},// 自定義組件映射 { 'custom-chart': ChartComponent }customComponents: {type: Object,default: () => ({})},// 自定義渲染函數映射 { 'custom-render': (item) => '<div>...</div>' }customRenders: {type: Object,default: () => ({})}},data() {return {NormalSteps,SpecialStep}},methods: {// 判斷使用的icongetIcon(item) {if (!item.isStop) {return 'el-icon-loading'}if (item.isError) {return 'el-icon-error'}return 'el-icon-success'},// 判斷是否為自定義組件isCustomComponent(type) {return type && type.startsWith('component:') && this.customComponents[type.replace('component:', '')]},// 獲取自定義組件getCustomComponent(type) {const componentName = type.replace('component:', '')return this.customComponents[componentName]},// 判斷是否為自定義插槽isCustomSlot(type) {return type && type.startsWith('slot:')},// 獲取插槽名稱getSlotName(type) {return type.replace('slot:', '')},// 判斷是否為自定義渲染函數isCustomRender(type) {return type && type.startsWith('render:') && this.customRenders[type.replace('render:', '')]},// 獲取自定義渲染結果getCustomRender(type, item) {const renderName = type.replace('render:', '')const renderFn = this.customRenders[renderName]return renderFn ? renderFn(item) : item.content}}
}
</script><style scoped>
.gain-box-header {width: 100%;display: flex;align-items: center;
}.load-but {width: 100%;padding: 15px 10px;background: rgba(13, 62, 135, 0.06);border-radius: 17px;border: 1px solid rgba(1, 128, 255, 0.03);
}
.load-but > span {line-height: 29px;color: #625b88;
}.step_title {display: flex;align-items: center;justify-content: space-between;
}.step_label {white-space: pre-wrap;font-size: 0.75rem;color: #606266;
}::v-deep .el-steps {width: 100%;
}::v-deep .el-step {min-height: 50px;
}::v-deep .el-step:last-child {min-height: 0;
}::v-deep .el-step__icon.is-icon {background: transparent;
}::v-deep .el-step.is-vertical .el-step__title {font-size: 14px;color: #222222;
}::v-deep .el-step.is-vertical .el-step__line {top: 27px;bottom: 3px;
}::v-deep .el-icon-success {color: #4281ed;
}::v-deep .el-icon-error {color: #c0c4cc;
}::v-deep .vuepress-markdown-body {background: transparent;
}
</style>

外部引用

<template><div><!-- 使用StepList組件 --><StepList :steps="steps" :custom-components="customComponents":custom-renders="customRenders"><!-- 自定義插槽渲染 --><template #custom-table="{ item, content, meta }"><el-table :data="content" size="mini" border><el-table-column prop="name" label="名稱" /><el-table-column prop="value" label="" /></el-table></template><template #custom-progress="{ item, meta }"><el-progress :percentage="meta.progress" :status="meta.status":stroke-width="8"/><div style="margin-top: 8px; font-size: 12px; color: #666;">{{ meta.progressText }}</div></template><template #custom-image="{ item, content }"><div class="image-container"><img :src="content" :alt="item.title" style="max-width: 100%; height: auto;" /></div></template></StepList></div>
</template><script>
import StepList from './StepList.vue'
import { NormalSteps, SpecialStep } from '@/dicts/DictSse.js'// 自定義圖表組件
const CustomChart = {props: ['item', 'content', 'meta'],template: `<div class="custom-chart"><div class="chart-title">{{ item.title }}</div><div class="chart-content"><div v-for="(data, index) in content" :key="index" class="chart-bar"><span class="bar-label">{{ data.label }}</span><div class="bar-container"><div class="bar-fill" :style="{ width: data.value + '%' }"></div></div><span class="bar-value">{{ data.value }}%</span></div></div></div>`,style: `.custom-chart { padding: 10px; }.chart-title { font-weight: bold; margin-bottom: 10px; }.chart-bar { display: flex; align-items: center; margin-bottom: 8px; }.bar-label { width: 80px; font-size: 12px; }.bar-container { flex: 1; height: 20px; background: #f0f0f0; margin: 0 10px; position: relative; }.bar-fill { height: 100%; background: #409eff; transition: width 0.3s; }.bar-value { font-size: 12px; }`
}// 自定義列表組件
const CustomList = {props: ['item', 'content', 'meta'],template: `<div class="custom-list"><div v-for="(listItem, index) in content" :key="index" class="list-item"><div class="list-icon"><i :class="listItem.icon || 'el-icon-check'"></i></div><div class="list-content"><div class="list-title">{{ listItem.title }}</div><div class="list-desc">{{ listItem.description }}</div></div></div></div>`,style: `.custom-list { padding: 10px 0; }.list-item { display: flex; align-items: flex-start; margin-bottom: 12px; }.list-icon { width: 20px; height: 20px; margin-right: 10px; display: flex; align-items: center; justify-content: center; }.list-content { flex: 1; }.list-title { font-weight: bold; margin-bottom: 4px; }.list-desc { font-size: 12px; color: #666; }`
}export default {name: 'StepListExample',components: { StepList },data() {return {// 自定義組件映射customComponents: {'chart': CustomChart,'list': CustomList},// 自定義渲染函數映射customRenders: {'highlight': (item) => {return `<div style="background: #fff3cd; padding: 10px; border-radius: 4px; border-left: 4px solid #ffc107;"><strong>?? 重要提示</strong><br/>${item.content}</div>`},'code': (item) => {return `<pre style="background: #f8f9fa; padding: 12px; border-radius: 4px; overflow-x: auto;"><code>${item.content}</code></pre>`}},// 步驟數據steps: [// 內置類型 - Markdown{id: '1',type: NormalSteps.Markdown,title: '步驟1:分析數據',content: '## 數據分析結果\n\n- 處理了 **1000** 條記錄\n- 發現 `5` 個異常值\n- 準確率達到 **95%**',isStop: true,isShow: true,isError: false,meta: {}},// 內置類型 - Text{id: '2',type: NormalSteps.Text,title: '步驟2:文本說明',content: '這是一個普通的文本說明內容,用于展示基本的文本渲染效果。',isStop: true,isShow: true,isError: false,meta: {}},// 自定義組件 - 圖表{id: '3',type: 'component:chart',title: '步驟3:數據可視化',content: [{ label: '成功率', value: 85 },{ label: '處理速度', value: 92 },{ label: '準確率', value: 78 }],isStop: true,isShow: true,isError: false,meta: {},props: {} // 額外傳遞給組件的props},// 自定義組件 - 列表{id: '4',type: 'component:list',title: '步驟4:任務清單',content: [{ title: '數據預處理', description: '清洗和格式化原始數據',icon: 'el-icon-check'},{ title: '模型訓練', description: '使用機器學習算法訓練模型',icon: 'el-icon-loading'},{ title: '結果驗證', description: '驗證模型的準確性和可靠性',icon: 'el-icon-time'}],isStop: false,isShow: true,isError: false,meta: {}},// 自定義插槽 - 表格{id: '5',type: 'slot:custom-table',title: '步驟5:數據表格',content: [{ name: '處理時間', value: '2.5秒' },{ name: '內存使用', value: '128MB' },{ name: 'CPU使用率', value: '45%' }],isStop: true,isShow: true,isError: false,meta: {}},// 自定義插槽 - 進度條{id: '6',type: 'slot:custom-progress',title: '步驟6:處理進度',content: '',isStop: false,isShow: true,isError: false,meta: {progress: 67,status: 'active',progressText: '正在處理中... 67%'}},// 自定義插槽 - 圖片{id: '7',type: 'slot:custom-image',title: '步驟7:結果展示',content: 'https://via.placeholder.com/300x200?text=Processing+Result',isStop: true,isShow: true,isError: false,meta: {}},// 自定義渲染函數 - 高亮提示{id: '8',type: 'render:highlight',title: '步驟8:重要提示',content: '請注意:此操作不可逆,請確保數據已備份!',isStop: true,isShow: true,isError: false,meta: {}},// 自定義渲染函數 - 代碼塊{id: '9',type: 'render:code',title: '步驟9:代碼示例',content: `function processData(data) {return data.map(item => ({...item,processed: true,timestamp: new Date().toISOString()}));
}`,isStop: true,isShow: true,isError: false,meta: {}}]}}
}
</script><style scoped>
.image-container {text-align: center;padding: 10px;
}
</style>

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

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

相關文章

Unreal5從入門到精通之如何實現UDP Socket通訊

文章目錄 一.前言二.什么是FSocket1. FSocket的作用2. FSocket關鍵特性三.創建Socket四.數據傳輸五.線程安全六.UDPSocketComponentUDPSocketComponent.hUUDPSocketComponent.cpp七.SocketTest測試八.最后一.前言 我們在開發UE 的過程中,會經常使用到Socket通訊,包括TCP,UD…

UI前端大數據處理新趨勢:基于邊緣計算的數據處理與響應

hello寶子們...我們是艾斯視覺擅長ui設計、前端開發、數字孿生、大數據、三維建模、三維動畫10年經驗!希望我的分享能幫助到您!如需幫助可以評論關注私信我們一起探討!致敬感謝感恩!一、引言&#xff1a;前端大數據的 “云端困境” 與邊緣計算的破局當用戶在在線文檔中實時協作…

Reading and Writing to a State Variable

本節是《Solidity by Example》的中文翻譯與深入講解&#xff0c;專為零基礎或剛接觸區塊鏈開發的小白朋友打造。我們將通過“示例 解說 提示”的方式&#xff0c;帶你逐步理解每一段 Solidity 代碼的實際用途與背后的邏輯。Solidity 是以太坊等智能合約平臺使用的主要編程語…

c# 深度解析:實現一個通用配置管理功能,打造高并發、可擴展的配置管理神器

文章目錄深入分析 ConfigManager<TKey, TValue> 類1. 類設計概述2. 核心成員分析2.1 字段和屬性2.2 構造函數3. 數據加載機制4. CRUD 操作方法4.1 添加數據4.2 刪除數據4.3 更新數據4.4 查詢數據4.5 清空數據5. 數據持久化6. 設計亮點7. 使用示例ConfigManager<TKey, …

運維打鐵: Python 腳本在運維中的常用場景與實現

文章目錄引言思維導圖常用場景與代碼實現1. 服務器監控2. 文件管理3. 網絡管理4. 自動化部署總結注意事項引言 在當今的 IT 運維領域&#xff0c;自動化和效率是至關重要的。Python 作為一種功能強大且易于學習的編程語言&#xff0c;已經成為運維人員不可或缺的工具。它可以幫…

【零基礎入門unity游戲開發——unity3D篇】3D光源之——unity反射和反射探針技術

文章目錄 前言實現天空盒反射1、新建一個cube2、全反射材質3、增加環境反射分辨率反射探針1、一樣把小球材質調成全反射2、在小球身上加添加反射探針3、設置靜態物體4、點擊烘培5、效果6、可以修改反射探針區域大小7、實時反射專欄推薦完結前言 當對象收到直接和間接光照后,它…

React Three Fiber 實現 3D 模型點擊高亮交互的核心技巧

在 WebGL 3D 開發中&#xff0c;模型交互是提升用戶體驗的關鍵功能之一。本文將基于 React Three Fiber&#xff08;R3F&#xff09;和 Three.js&#xff0c;總結 3D 模型點擊高亮&#xff08;包括模型本身和邊框&#xff09;的核心技術技巧&#xff0c;幫助開發者快速掌握復雜…

卷積神經網絡實戰:MNIST手寫數字識別

夜漸深&#xff0c;我還在&#x1f618; 老地方 睡覺了&#x1f64c; 文章目錄&#x1f4da; 卷積神經網絡實戰&#xff1a;MNIST手寫數字識別&#x1f9e0; 4.1 預備知識?? 4.1.1 torch.nn.Conv2d() 三維卷積操作&#x1f4cf; 4.1.2 nn.MaxPool2d() 池化層的作用&#x1f4…

HarmonyOS應用無響應(AppFreeze)深度解析:從檢測原理到問題定位

HarmonyOS應用無響應&#xff08;AppFreeze&#xff09;深度解析&#xff1a;從檢測原理到問題定位 在日常應用使用中&#xff0c;我們常會遇到點擊無反應、界面卡頓甚至完全卡死的情況——這些都可能是應用無響應&#xff08;AppFreeze&#xff09; 導致的。對于開發者而言&am…

湖北設立100億元人形機器人產業投資母基金

湖北設立100億元人形機器人產業投資母基金 湖北工信 2025年07月08日 12:03 湖北 &#xff0c;時長01:20 近日&#xff0c;湖北設立100億元人形機器人產業投資母基金&#xff0c;重點支持人形機器人和人工智能相關產業發展。 人形機器人產業投資母基金由湖北省財政廳依托省政府…

時序預測 | Pytorch實現CNN-LSTM-KAN電力負荷時間序列預測模型

預測效果 代碼主要功能 該代碼實現了一個結合CNN&#xff08;卷積神經網絡&#xff09;、LSTM&#xff08;長短期記憶網絡&#xff09;和KAN&#xff08;Kolmogorov-Arnold Network&#xff09;的混合模型&#xff0c;用于時間序列預測任務。主要流程包括&#xff1a; 數據加…

OCR 識別:車牌識別相機的 “火眼金睛”

車牌識別相機在交通管理、停車場收費等場景中&#xff0c;需快速準確識別車牌信息。但實際環境中&#xff0c;車牌可能存在污漬、磨損、光照不均等情況&#xff0c;傳統識別方式易出現誤讀、漏讀。OCR 技術讓車牌識別相機如虎添翼。它能精準提取車牌上的字符&#xff0c;不管是…

Java面試基礎:面向對象(2)

1. 接口里可以定義哪些方法抽象方法&#xff1a;抽象方法是接口的核心部分&#xff0c;所有實現接口的類都必須實現這些方法。抽象方法默認是 public 和 abstract 修飾&#xff0c;這些修飾符可以省略。public interface Animal {void Sound(); }默認方法&#xff1a;默認方法是…

有哪些更加簡潔的for循環?循環語句?

目錄 簡潔的for循環 循環過程修改循環變量 循環語句 不同編程語言支持的循環語句 foreach 無限循環 for循環歷史 break和continue 循環判斷結束值 循環標簽 循環語句優化 循環表達式返回值 簡潔的for循環 如果需要快速枚舉一個集合的元素&#xff0c;盡管C語言可以…

RK3568/3588 Android 12 源碼默認使用藍牙mic錄音

遇到客戶一個需求&#xff0c;如果連接了帶mic的藍牙耳機&#xff0c;默認所有的錄音要走藍牙mic通道。這個功能搞了好久&#xff0c;終于搞定了。1. 向RK尋求幫助&#xff0c;先打通 bt sco能力。此時&#xff0c;還無法默認就切換到藍牙 mic通道&#xff0c;接下來我們需求默…

解鎖HTTP:從理論到實戰的奇妙之旅

目錄一、HTTP 協議基礎入門1.1 HTTP 協議是什么1.2 HTTP 協議的特點1.3 HTTP 請求與響應的結構二、HTTP 應用場景大揭秘2.1 網頁瀏覽2.2 API 調用2.3 文件傳輸2.4 內容分發網絡&#xff08;CDN&#xff09;2.5 流媒體服務三、HTTP 應用實例深度剖析3.1 使用 JavaScript 的 fetc…

uvm_config_db examples

通過uvm_config_db類訪問的UVM配置數據庫,是在多個測試平臺組件之間傳遞不同對象的絕佳方式。 methods 有兩個主要函數用于從數據庫中放入和檢索項目,分別是 set() 和 get()。 static function void set ( uvm_component cntxt,string inst_name,string …

(C++)任務管理系統(文件存儲)(正式版)(迭代器)(list列表基礎教程)(STL基礎知識)

目錄 前言&#xff1a; 源代碼&#xff1a; 代碼解析&#xff1a; 一.頭文件和命名空間 1. #include - 輸入輸出功能2. #include - 鏈表容器3. #include - 字符串處理4. using namespace std; - 命名空間 可視化比喻&#xff1a;建造房子 &#x1f3e0; 二.menu()函數 …

Java 中的異步編程詳解

前言 在現代軟件開發中&#xff0c;異步編程&#xff08;Asynchronous Programming&#xff09; 已經成為構建高性能、高并發應用程序的關鍵技術之一。Java 作為一門廣泛應用于后端服務開發的語言&#xff0c;在其發展過程中不斷引入和優化異步編程的支持。從最初的 Thread 和…

MySQL邏輯刪除與唯一索引沖突解決

問題背景 在MySQL數據庫設計中&#xff0c;邏輯刪除&#xff08;軟刪除&#xff09;是一種常見的實踐&#xff0c;它通過設置標志位&#xff08;如is_delete&#xff09;來標記記錄被"刪除"&#xff0c;而不是實際刪除數據。然而&#xff0c;當表中存在唯一約束時&am…