vue中根據html動態渲染內容2.0

上次使用的是p標簽用的contenteditable代替的可編輯的input,最后實現還是選擇了用el-input的textarea方式。
一開始考慮的是需要根據用戶輸入自動撐開輸入框,所以選擇了p標簽可編輯。
最后發現還是el-input會更好一點,只不過需要處理輸入框撐開的樣式問題。

好的,話不多說!
代碼如下:

<script setup lang="ts">
// 存儲每個 input 框的值
const inputValues = ref<string[]>([]);
// 存儲 input 元素的 ref
const inputRefs: any = ref([]);
const isInputFocused = ref<boolean[]>([]);
const isClearIconClicked = ref<boolean[]>([]); // 用于延遲隱藏清除圖標的定時器
const clearIconHideTimer: any = ref([]);
// 提取重復的判斷邏輯到一個函數中
const shouldDisableOrHide = (itemConf, index) => {return (itemConf.value.baseConf.isReadOnly ||!(itemConf.value.customConf?.inputGroup[index]?.isSupportEdit ?? true));
};
// 計算屬性,用于生成渲染內容
const renderedContent = computed(() => {if (!itemConf.value.customConf?.inputHtml) return null;const parts = itemConf.value.customConf.inputHtml.split(/_{1,}/);let nodes: any = [];parts.forEach((part, index) => {if (part) {const replacedSpaces = part.replace(/ /g, '&nbsp;');const replacedPart = replacedSpaces.replace(/<div>/g, '<br>').replace(/<\/div>/g, '');nodes.push(h('span', { class: 'custom-span', innerHTML: replacedPart }));}if (index < parts.length - 1) {if (!inputValues.value[index]) {inputValues.value[index] = '';}if (!isInputFocused.value[index]) {isInputFocused.value[index] = false;}if (!isClearIconClicked.value[index]) {isClearIconClicked.value[index] = false;}if (!clearIconHideTimer.value[index]) {clearIconHideTimer.value[index] = 0;}const clearIcon = h(ElIcon,{class: ['clear_icon',{'is-hidden':inputValues.value[index].length === 0 ||shouldDisableOrHide(itemConf, index) ||!isInputFocused.value[index],},],onClick: () => {if (!shouldDisableOrHide(itemConf, index)) {isClearIconClicked.value[index] = true;inputValues.value[index] = '';adjustInputWidth(index);handleChange(itemConf.value.customConf.inputGroup[index], '');// 點擊后清除隱藏定時器clearTimeout(clearIconHideTimer.value[index]);}},},{ default: () => h(CircleClose) },);const inputNode = h(ElInput, {type: 'textarea',modelValue: inputValues.value[index],'onUpdate:modelValue': (val: string) => {inputValues.value[index] = val;adjustInputWidth(index);},rows: 1,clearable: true,autosize: {minRows: 1, // 最小行數maxRows: 3, // 最大行數},class: ['underline_input',{'is-disabled': shouldDisableOrHide(itemConf, index),},],disabled: shouldDisableOrHide(itemConf, index),placeholder: unref(itemConf).customConf?.inputGroup[index]?.placeholder || '請輸入',onFocus: () => {isInputFocused.value[index] = true;clearTimeout(clearIconHideTimer.value[index]);},onBlur: () => {handleChange(itemConf.value.customConf.inputGroup[index], inputValues.value[index]);clearIconHideTimer.value[index] = setTimeout(() => {if (!isClearIconClicked.value[index]) {isInputFocused.value[index] = false;}isClearIconClicked.value[index] = false;}, 100);},// ref: (el) => (inputRefs.value[index] = el),});nodes.push(h('p', { class: 'underline_input_wrap' }, [inputNode, clearIcon]));}});return h('div', nodes);
});const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
// 這個就是調整寬度的方法
const adjustInputWidth = (index: number) => {const textarea = inputRefs.value?.[index] || undefined;if (ctx && textarea) {ctx.font = '14px system-ui'; // 必須與 CSS 字體設置一致const text = inputValues.value[index] || textarea.placeholder;const textWidth = ctx.measureText(text).width;textarea.style.width = `${Math.max(textWidth + 30, 101)}px`; // 101px 為最小寬度} else {textarea.style.width = '101px';}
};// 在組件掛載時初始化輸入框寬度
onMounted(() => {nextTick(() => {inputRefs.value = unref(wrap_component)?.querySelectorAll('.underline_input') || [];inputRefs.value.forEach((textarea) => {textarea.style.width = 'auto !important';if (parseInt(textarea.style.width) < 101) {textarea.style.width = '101px';}});
});
</script><style lang="less" scoped>
.underline_input_wrap {display: inline-block;position: relative;margin-top: 20px;margin-bottom: 0;margin-right: 10px;max-width: calc(100% - 50px);
}
:deep(.underline_input) {width: 100%;border-radius: 6px 6px 6px 6px;border: none;margin-top: 0;margin-bottom: 0;display: inline-block;box-sizing: border-box;vertical-align: middle;color: #606266;.el-textarea__inner {background: #f5f7fb;// 寬度高度自適應min-height: 40px !important;min-width: 101px !important;max-width: 100%;max-height: 100px;line-height: 31px;resize: none !important; // 禁止用戶手動調整文本框大小box-shadow: none;white-space: pre-wrap;word-break: break-all;/* 隱藏滾動條 */&::-webkit-scrollbar {width: 0;height: 0;}&::-webkit-scrollbar-thumb {background: transparent;}&::-webkit-scrollbar-track {background: transparent;}&:focus {outline: none;border: 1px solid #1a77ff;color: #606266;}&:disabled {color: #bbbfc4;cursor: not-allowed;}&::placeholder {color: #a8abb2;font-size: 14px;}}
}.underline_input.is-disabled {color: #bbbfc4;cursor: not-allowed;
}.underline_input[contenteditable='true']:empty::before,
.underline_input.is-disabled:empty::before {content: attr(placeholder);color: #bbbfc4;
}:deep(.clear_icon) {position: absolute;width: 14px;height: 14px;right: 2px;top: 50%;transform: translateY(-50%);cursor: pointer;color: #999;z-index: 10; /* 增加 z-index 確保在最上層 */&:hover {color: #666;}&.is-hidden {display: none;}
}
</style>

至于樣式大家可根據自己需要進行調整。

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

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

相關文章

CentOS 系統磁盤擴容并掛載到根目錄(/)的詳細步驟

在使用 CentOS 系統時&#xff0c;經常會遇到需要擴展磁盤空間的情況。例如&#xff0c;當虛擬機的磁盤空間不足時&#xff0c;可以通過增加磁盤容量并將其掛載到根目錄&#xff08;/&#xff09;來解決。以下是一個完整的操作流程&#xff0c;詳細介紹了如何將新增的 10G 磁盤…

LINUX基礎 [二] - Linux常見指令

目錄 &#x1f4bb;前言 &#x1f4bb;指令 &#x1f3ae;ls指令 &#x1f3ae;pwd指令 &#x1f3ae;whoami指令 &#x1f3ae;cd指令 &#x1f3ae;clear指令 &#x1f3ae;touch指令 &#x1f3ae;mkdir指令 &#x1f3ae;rmdir指令 &#x1f3ae;rm指令 &#…

基于php的成績分析和預警與預測網站(源碼+lw+部署文檔+講解),源碼可白嫖!

摘要 人類現已邁入二十一世紀&#xff0c;科學技術日新月異&#xff0c;經濟、資訊等各方面都有了非常大的進步&#xff0c;尤其是資訊與網絡技術的飛速發展&#xff0c;對政治、經濟、軍事、文化、教育等各方面都有了極大的影響。 利用電腦網絡的這些便利&#xff0c;發展一套…

《從底層邏輯剖析:分布式軟總線與傳統計算機硬件總線的深度對話》

在科技飛速發展的當下&#xff0c;我們正見證著計算機技術領域的深刻變革。計算機總線作為信息傳輸的關鍵樞紐&#xff0c;其發展歷程承載著技術演進的脈絡。從傳統計算機硬件總線到如今備受矚目的分布式軟總線&#xff0c;每一次的變革都為計算機系統性能與應用拓展帶來了質的…

Spring Boot 3.5新特性解析:自動配置再升級,微服務開發更高效

&#x1f4dd; 摘要 Spring Boot 3.5作為Spring生態的最新版本&#xff0c;帶來了多項令人振奮的改進。本文將深入解析其中最核心的自動配置增強特性&#xff0c;以及它們如何顯著提升微服務開發效率。通過詳細的代碼示例和通俗易懂的講解&#xff0c;您將全面了解這些新特性在…

【前端】webpack一本通

今日更新完畢&#xff0c;不定期補充&#xff0c;建議關注收藏點贊。 目錄 簡介Loader和Plugin的不同&#xff1f;&#xff08;必會&#xff09; 使用webpack默認只能處理js文件 ->引入加載器對JS語法降級&#xff0c;兼容低版本語法合并文件再次打包進階 工作原理Webpack 的…

leetcode 264. Ugly Number II

動態規劃解決。 關鍵是理解如何生成新的丑數。這道題和經典的斐波那契數列問題其實是一樣的。求第n個數&#xff0c;需要用第n個數前面的數來求。不同的是&#xff0c;斐波那契數列不會重復。而本題的丑數&#xff0c;會重復出現。 class Solution { public:int nthUglyNumbe…

深入理解 HTML5 語義元素:提升網頁結構與可訪問性

引言 在構建網頁的過程中&#xff0c;合理的結構與清晰的語義對于網頁的質量、可維護性以及搜索引擎優化&#xff08;SEO&#xff09;都至關重要。HTML5 引入了一系列語義元素&#xff0c;為開發者提供了更精準描述網頁內容的工具。本文將深入探討 HTML5 語義元素的作用、使用…

PyCharm顯示主菜單和工具欄

顯示主菜單 新版 PyCharm 是不顯示主菜單的&#xff0c;要想顯示主菜單和工具欄&#xff0c;則通過 “視圖” → “外觀” &#xff0c;勾選 “在單獨的工具欄中顯示主菜單” 和 “工具欄” 即可。 設置工具欄 此時工具欄里并沒有什么工具&#xff0c;因此我們需要自定義工具…

CyclicBarrier 基本用法

CyclicBarrier 基本用法 簡介 CyclicBarrier 是 Java 并發包&#xff08;java.util.concurrent&#xff09;中的一個同步輔助類。它允許一組線程相互等待&#xff0c;直到到達某個公共屏障點&#xff08;common barrier point&#xff09;。只有當所有參與的線程都到達屏障點…

[特殊字符] 手機連接車機熱點并使用 `iperf3` 測試網絡性能

好的&#xff0c;以下是根據你的描述整理出來的步驟及解釋&#xff1a; &#x1f4f6; 手機連接車機熱點并使用 iperf3 測試網絡性能 本文將通過 iperf3 來測試手機和車機之間的網絡連接性能。我們會讓車機作為服務端&#xff0c;手機作為客戶端&#xff0c;進行 UDP 流量傳輸…

FPGA上實現SD卡連續多塊讀的命令

在FPGA上實現SD卡連續多塊讀的命令 CMD17命令一次只能讀取1個塊 CMD18命令一次可以連續讀取多個塊&#xff0c;直到停止命令CMD12 CMD18命令讀的塊數程序可任意設置 目錄 前言 一、SD卡多塊讀命令CMD18 二、停止讀命令CMD12 三、SD卡初始化SD卡連續塊讀操作的verilog代碼 …

DeepSeek 助力 Vue3 開發:打造絲滑的日歷(Calendar)

前言&#xff1a;哈嘍&#xff0c;大家好&#xff0c;今天給大家分享一篇文章&#xff01;并提供具體代碼幫助大家深入理解&#xff0c;徹底掌握&#xff01;創作不易&#xff0c;如果能幫助到大家或者給大家一些靈感和啟發&#xff0c;歡迎收藏關注哦 &#x1f495; 目錄 Deep…

NSGA-II 多目標優化 —— 理論、案例與交互式 GUI 實現

目錄 NSGA-II 多目標優化 —— 理論、案例與交互式 GUI 實現一、引言二、NSGA-II 基本原理2.1 非支配排序2.2 擁擠距離2.3 算法流程三、數學模型與算法推導3.1 多目標優化問題描述3.2 非支配關系與排序3.3 擁擠距離計算四、NSGA-II 的優缺點4.1 優點4.2 缺點五、典型案例分析5.…

庫學習04——numpy

一、基本屬性 二、 創建數組 &#xff08;一&#xff09;arange a np.arange(10,20,2) # [10,12,14,16,18] 只有一個參數n的話&#xff0c;默認是從0到n-1的一維數組。 &#xff08;二&#xff09;自定義reshape a np.arange(12).reshape((3,4)) [[ 0 1 2 3][ 4 5 …

NVIDIA Jetson 快速切換CUDA版本| 多CUDA版本

當NVIDIA Jetson中安裝了多個CUDA時&#xff0c;可以通過命令&#xff0c;快速切換不同版本的。 這樣在環境變量和代碼編譯時&#xff0c;能使用指定版本的CUDA了。 本文適用于Jetson Nano、TX1/TX2、Xavier 和 Orin系列的設備&#xff0c;供大家參考。 cuda參考地址&#xf…

當開源邂逅AI,公益長出翅膀 | 回顧3.30 上海「開源×AI 賦能公益」Meetup

在春和景明的三月&#xff0c;一場打破常規的公益聚會在上海剪愛公益發展中心肇清項目點溫暖上演。這&#xff0c;便是G-Star公益行帶來的「開源AI 賦能公益」Meetup&#xff0c;一場技術與善意交織、創新與溫暖共生的奇妙之旅。 活動現場&#xff0c;沒有高冷的技術壁壘&#…

高階函數/柯里化/純函數

本篇文章主要是介紹一下標題里面的概念&#xff0c;在面試的時候經常文檔&#xff0c;結合閱讀到的資料&#xff0c;結合本人的個人見解出品了該文章&#xff0c;如有寫的不好的地方或理解有誤的&#xff0c;還望閣下多多指教。 1、高階函數 什么是高階函數&#xff1f; 接受…

Docker+Jenkins+Gitee自動化項目部署

前置條件 docker安裝成功 按照下面配置加速 sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-EOF {"registry-mirrors": ["https://register.librax.org"] } EOF sudo systemctl daemon-reload sudo systemctl restart docker一、…

穿梭在數字王國:Python進制轉換奇遇記

穿梭在數字王國:Python進制轉換奇遇記 想象一下,你是一位勇敢的探險家,正在穿越神秘的"數字王國"。在這個王國里,不同的地區使用著不同的語言(或者說,進制)。二進制村的居民只懂"0"和"1";八進制鎮的人們使用0到7的數字;而十六進制城的…