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.mzph.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的数字;而十六进制城的…