前端基础入门(13):contenteditable 属性在 Vue/React 中的基础应用
·
contenteditable 属性简介
contenteditable 是 HTML5 提供的全局属性,允许用户直接在页面上编辑元素内容。它适用于富文本编辑、实时预览等场景,通过设置 contenteditable="true" 或 contenteditable="false" 控制编辑状态。
在原生 HTML 中使用
在原生 HTML 中,直接为元素添加 contenteditable 属性即可启用编辑功能:
<div contenteditable="true">点击这里可以编辑文本</div>
在 Vue 中的实现
Vue 需要通过 v-model 或自定义指令管理 contenteditable 的内容。由于 contenteditable 不是表单元素,需手动处理数据绑定。
方法 1:使用 v-html 和 @input
<template>
<div
contenteditable="true"
v-html="editableContent"
@input="handleInput"
></div>
</template>
<script>
export default {
data() {
return {
editableContent: '初始内容'
};
},
methods: {
handleInput(e) {
this.editableContent = e.target.innerHTML;
}
}
};
</script>
方法 2:封装为自定义指令
Vue.directive('editable', {
bind(el, binding, vnode) {
el.contentEditable = true;
el.innerHTML = binding.value;
el.addEventListener('input', () => {
vnode.context[binding.expression] = el.innerHTML;
});
},
update(el, binding) {
if (el.innerHTML !== binding.value) {
el.innerHTML = binding.value;
}
}
});
在模板中使用:
<div v-editable="editableContent"></div>
在 React 中的实现
React 通过 dangerouslySetInnerHTML 和状态管理实现类似功能。
方法 1:受控组件模式
import { useState } from 'react';
function EditableDiv() {
const [content, setContent] = useState('初始内容');
const handleInput = (e) => {
setContent(e.target.innerHTML);
};
return (
<div
contentEditable
dangerouslySetInnerHTML={{ __html: content }}
onInput={handleInput}
/>
);
}
方法 2:使用 ref 管理内容
import { useRef, useState } from 'react';
function EditableDiv() {
const [content, setContent] = useState('初始内容');
const divRef = useRef(null);
const handleBlur = () => {
setContent(divRef.current.innerHTML);
};
return (
<div
ref={divRef}
contentEditable
dangerouslySetInnerHTML={{ __html: content }}
onBlur={handleBlur}
/>
);
}
常见问题与优化
-
性能问题
频繁的innerHTML操作可能影响性能,建议使用onBlur替代onInput减少更新频率。 -
XSS 风险
contenteditable可能引入不安全内容,需使用 DOMPurify 等库过滤 HTML:import DOMPurify from 'dompurify'; const cleanHTML = DOMPurify.sanitize(userInput); -
光标位置丢失
动态更新内容时可能导致光标重置,可通过Range和SelectionAPI 保存和恢复光标位置。
富文本扩展
结合 document.execCommand 或第三方库(如 Quill、Tiptap)实现更复杂的富文本功能,例如加粗、插入图片等。
总结
contenteditable 在 Vue/React 中需手动处理数据绑定,通过指令、受控组件或 ref 实现双向同步。注意性能优化和安全性,复杂场景推荐使用现成的富文本编辑器库。
更多推荐
所有评论(0)