VUE3语法-(readonly的用法)将数据设置成只读模式

本文介绍了如何在Vue3中使用`reactive`和`readonly`创建一个不可修改的响应式变量,并展示了尝试修改只读数据时的错误。通过实例演示了如何在setup方法中设置定时器改变只读数据引发的错误。

1、功能概述

在Vue中定义一个变量,这个变量的值不允许被修改,核心是通过readonly设置成只读。

如果不会使用ref和reactive响应式数据参考如下博客:

https://blog.youkuaiyun.com/tangshiyilang/article/details/134701103

2、具体实现

如下案例:

1、通过reactive定义一个响应式数据testData,并将testData通过readonly设置成只读模式。

2、在setup中设置了一个定时器,2s后修改readonlyData中的参数

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://unpkg.com/vue@3"></script>
</head>
<body>
  <div id="app">{{readonlyData.name}}</div>
  <script type="module">
    const app=Vue.createApp({

       //创建setup
       setup(props,context){
        const {reactive,readonly}=Vue;//从vue中引入ref
        //创建reactive设置响应式数据
        let testData=reactive({name:'小春'+new Date()});
        //将值设置只读状态
        let readonlyData=readonly(testData);
         setTimeout(()=>{
          readonlyData.name='大春'
         },2000)
         return {readonlyData}
        }
    });
    //vue实例只作用于app这个DOM节点中
    const vm=app.mount('#app');//viewModel是组件帮助我们完成的
  </script>
</body>

</html>

3、结果输出

1、从图中可以看出,页面中通过{{readonlyData.name}}显示了原始数据”小春”

2、2s之后数据报错:set opration on key “name” failed:target is readonly

56f332f6ae1b458a867f61b45aa1aff2.png

<think>在Vue-Quill-Editor中实现不可编辑模式只读模式)可以通过多种方式实现。以下是最常见的几种方法及其详细实现: ###方法1:使用Quill的`enable`/`disable`方法Quill编辑器实例提供了`enable`和`disable`方法,可以动态切换编辑状态。 ```vue<template><div><quill-editorref="myQuillEditor"v-model:content="content":options="editorOptions"content-type="html"/><button @click="toggleEditMode">{{isReadOnly ?&#39;启用编辑&#39;: &#39;禁用编辑&#39; }}</button></div></template> <script> import{ Quill,quillEditor }from &#39;vue-quill-editor&#39;import &#39;quill/dist/quill.core.css&#39;import &#39;quill/dist/quill.snow.css&#39; exportdefault {components: {quillEditor},data(){return {content: &#39;<p>初始内容</p>&#39;,isReadOnly: false,editorOptions: {modules: {toolbar: [[&#39;bold&#39;,&#39;italic&#39;, &#39;underline&#39;],//其他工具栏选项...]},theme:&#39;snow&#39;}}},methods: {toggleEditMode() {this.isReadOnly =!this.isReadOnlyconsteditor =this.$refs.myQuillEditor.quillif (this.isReadOnly) {editor.disable()} else{editor.enable()}}}} </script>``` ###方法2:通过`readOnly`选项在Quill的配置选项中,可以直接设置`readOnly`属性为`true`来使编辑器只读。```vue<template><div><quill-editorv-model:content="content":options="editorOptions"content-type="html"/><button @click="toggleEditMode">{{editorOptions.readOnly ?&#39;启用编辑&#39;: &#39;禁用编辑&#39; }}</button></div></template> <script> import{ quillEditor} from&#39;vue-quill-editor&#39; import&#39;quill/dist/quill.core.css&#39; import&#39;quill/dist/quill.snow.css&#39;export default{components:{quillEditor},data() {return{content:&#39;<p>初始内容</p>&#39;,editorOptions: {readOnly:false,//初始为可编辑modules:{toolbar:[[&#39;bold&#39;, &#39;italic&#39;,&#39;underline&#39;],//其他工具栏选项...]},theme: &#39;snow&#39;}}},methods:{toggleEditMode(){this.editorOptions.readOnly= !this.editorOptions.readOnly}} }</script> ```###方法3:使用CSS隐藏工具栏(只读模式下不需要工具栏)在只读模式下,通常不需要显示工具栏,可以通过CSS隐藏工具栏。```vue<template><div><quill-editorref="myQuillEditor"v-model:content="content":options="editorOptions":class="{&#39;read-only-mode&#39;: isReadOnly}"content-type="html"/><button @click="toggleEditMode">{{isReadOnly ?&#39;启用编辑&#39;: &#39;禁用编辑&#39; }}</button></div></template> <script> import{ quillEditor} from&#39;vue-quill-editor&#39; import&#39;quill/dist/quill.core.css&#39; import&#39;quill/dist/quill.snow.css&#39;export default{components:{quillEditor},data() {return{content:&#39;<p>初始内容</p>&#39;,isReadOnly:false,editorOptions:{modules:{toolbar:[[&#39;bold&#39;, &#39;italic&#39;,&#39;underline&#39;],//其他工具栏选项...]},theme: &#39;snow&#39;}}},methods:{toggleEditMode(){this.isReadOnly= !this.isReadOnlyconst editor= this.$refs.myQuillEditor.quillif(this.isReadOnly){editor.disable()}else {editor.enable()}}} }</script> <style> /*只读模式下隐藏工具栏*/ .read-only-mode.ql-toolbar {display: none; }</style> ```###方法4:使用`contenteditable`属性(高级控制) 通过直接操作DOM元素的`contenteditable`属性,可以更细粒度地控制编辑状态。```vue<template><div><quill-editorref="myQuillEditor"v-model:content="content":options="editorOptions"content-type="html"/><button @click="toggleEditMode">{{isReadOnly ?&#39;启用编辑&#39;: &#39;禁用编辑&#39; }}</button></div></template> <script> import{ quillEditor} from&#39;vue-quill-editor&#39; import&#39;quill/dist/quill.core.css&#39; import&#39;quill/dist/quill.snow.css&#39;export default{components:{quillEditor},data() {return{content:&#39;<p>初始内容</p>&#39;,isReadOnly:false,editorOptions:{modules:{toolbar:[[&#39;bold&#39;, &#39;italic&#39;,&#39;underline&#39;],//其他工具栏选项...]},theme: &#39;snow&#39;}}},methods:{toggleEditMode(){this.isReadOnly= !this.isReadOnlyconst editorElement =this.$refs.myQuillEditor.$el.querySelector(&#39;.ql-editor&#39;)if (editorElement) {editorElement.contentEditable= !this.isReadOnly}}} }</script> ```##注意事项1.**状态同步**:在只读模式下,虽然用户不能编辑内容,但程序仍然可以通过`v-model`修改内容。2.**工具栏状态**:在只读模式下,建议隐藏工具栏,因为工具栏的操作在只读模式下没有意义。 3. **样式调整**:只读模式下,可以添加一些样式来区分编辑状态,比如改变背景色或边框。##完整示例:结合多种方法的最佳实践以下是一个结合了状态控制、工具栏隐藏和样式变化的完整示例: ```vue<template><divclass="quill-container":class="{ &#39;read-only&#39;: isReadOnly}"><quill-editorref="myQuillEditor"v-model:content="content":options="editorOptions"content-type="html"/><button@click="toggleEditMode" class="toggle-btn">{{ isReadOnly? &#39;启用编辑&#39; :&#39;禁用编辑&#39;}}</button></div> </template><script>import {quillEditor }from &#39;vue-quill-editor&#39;import &#39;quill/dist/quill.core.css&#39;import &#39;quill/dist/quill.snow.css&#39; exportdefault {components: {quillEditor},data(){return {content: &#39;<p>初始内容</p>&#39;,isReadOnly: false,editorOptions: {modules: {toolbar: [[&#39;bold&#39;,&#39;italic&#39;, &#39;underline&#39;,&#39;strike&#39;],[{&#39;list&#39;:&#39;ordered&#39;},{ &#39;list&#39;:&#39;bullet&#39; }],[{ &#39;header&#39;:[1,2,3,4,5,6,false]}],[{&#39;color&#39;: []}, {&#39;background&#39;: []}],[&#39;link&#39;, &#39;image&#39;]]},theme: &#39;snow&#39;}}},methods:{toggleEditMode(){this.isReadOnly= !this.isReadOnlyconst editor= this.$refs.myQuillEditor.quillif(this.isReadOnly){editor.disable()} else{editor.enable()}}}} </script><style>.quill-container.read-only .ql-toolbar{display:none;} .quill-container.read-only .ql-container{border:1px solid#eee;background-color: #f9f9f9; }.toggle-btn{margin-top:10px;padding:5px10px;background:#3498db;color:white;border: none;border-radius:4px;cursor:pointer;} </style>``` ##解释1.**Quill的`enable`和`disable`方法**:这些是Quill内置的方法,用于启用或禁用编辑功能。当禁用时,用户将无法编辑内容,但内容仍然可以通过代码更新。2.**`readOnly`选项**:在Quill配置中设置`readOnly:true`可以达到同样的效果,但通过动态绑定选项,我们可以响应式地切换只读状态。 3. **CSS控制工具栏**:在只读模式下,我们通常不需要工具栏,因此通过CSS隐藏它。 4. **样式变化**:通过添加类名,我们可以改变只读模式下的编辑器样式,使其看起来不同,以提示用户当前为只读状态。## §§相关问题§§:1.如何在Vue-Quill-Editor中实现内容变更的自动保存? 2.如何自定义Vue-Quill-Editor的工具栏,添加自定义按钮?3.Vue-Quill-Editor中如何实现图片的自定义上传功能?4.在Vue3中如何使用Vue-Quill-Editor,有哪些注意事项?</think># Vue-Quill-Editor 不可编辑模式只读模式)实现指南 在 Vue-Quill-Editor 中实现不可编辑模式只读模式)有多种方法,下面我将详细介绍最常用的几种实现方式及其优缺点。 ## 方法1:使用 Quill 的 `enable`/`disable` 方法 这是最直接的方法,使用 Quill 的内置方法来控制编辑状态。 ```vue <template> <div> <quill-editor ref="myQuillEditor" v-model:content="content" :options="editorOptions" content-type="html" /> <button @click="toggleEditMode"> {{ isReadOnly ? &#39;启用编辑&#39; : &#39;禁用编辑&#39; }} </button> </div> </template> <script> import { quillEditor } from &#39;vue-quill-editor&#39; import &#39;quill/dist/quill.core.css&#39; import &#39;quill/dist/quill.snow.css&#39; export default { components: { quillEditor }, data() { return { content: &#39;<p>初始内容</p>&#39;, isReadOnly: false, editorOptions: { modules: { toolbar: [ [&#39;bold&#39;, &#39;italic&#39;, &#39;underline&#39;, &#39;strike&#39;], [{ &#39;list&#39;: &#39;ordered&#39;}, { &#39;list&#39;: &#39;bullet&#39; }], [{ &#39;header&#39;: [1, 2, 3, 4, 5, 6, false] }], [{ &#39;color&#39;: [] }, { &#39;background&#39;: [] }], [&#39;link&#39;, &#39;image&#39;] ] }, theme: &#39;snow&#39; } } }, methods: { toggleEditMode() { this.isReadOnly = !this.isReadOnly const editor = this.$refs.myQuillEditor.quill if (this.isReadOnly) { editor.disable() } else { editor.enable() } } } } </script> <style> /* 只读模式下的样式 */ .ql-container.ql-disabled { background-color: #f9f9f9; border-color: #eee; cursor: not-allowed; } </style> ``` ### 解释 - `editor.disable()`: 将编辑器设置只读模式 - `editor.enable()`: 恢复编辑模式 - 优点:简单直接,使用 Quill 内置功能 - 缺点:工具栏仍然可见(但按钮不可用) ## 方法2:通过 `readOnly` 选项配置 Quill 支持在初始化时通过配置选项设置只读模式。 ```vue <template> <div> <quill-editor v-model:content="content" :options="editorOptions" content-type="html" /> <button @click="toggleEditMode"> {{ editorOptions.readOnly ? &#39;启用编辑&#39; : &#39;禁用编辑&#39; }} </button> </div> </template> <script> import { quillEditor } from &#39;vue-quill-editor&#39; import &#39;quill/dist/quill.core.css&#39; import &#39;quill/dist/quill.snow.css&#39; export default { components: { quillEditor }, data() { return { content: &#39;<p>初始内容</p>&#39;, editorOptions: { readOnly: false, // 初始为可编辑 modules: { toolbar: [ // 同上 ] }, theme: &#39;snow&#39; } } }, methods: { toggleEditMode() { this.editorOptions.readOnly = !this.editorOptions.readOnly } } } </script> ``` ### 解释 - 通过 `readOnly: true` 选项设置只读模式 - 优点:声明式配置,Vue 响应式系统自动处理 - 缺点:动态切换时可能需要重新初始化编辑器 ## 方法3:完全隐藏工具栏(只读模式优化) 在只读模式下,通常不需要显示工具栏,可以通过 CSS 或动态配置隐藏。 ```vue <template> <div> <quill-editor ref="myQuillEditor" v-model:content="content" :options="editorOptions" content-type="html" :class="{ &#39;read-only-mode&#39;: isReadOnly }" /> <button @click="toggleEditMode"> {{ isReadOnly ? &#39;启用编辑&#39; : &#39;禁用编辑&#39; }} </button> </div> </template> <script> import { quillEditor } from &#39;vue-quill-editor&#39; import &#39;quill/dist/quill.core.css&#39; import &#39;quill/dist/quill.snow.css&#39; export default { components: { quillEditor }, data() { return { content: &#39;<p>初始内容</p>&#39;, isReadOnly: false, // 可编辑模式下的配置 editableOptions: { modules: { toolbar: [ // 同上 ] }, theme: &#39;snow&#39; }, // 只读模式下的配置 readOnlyOptions: { modules: { toolbar: false // 隐藏工具栏 }, theme: &#39;bubble&#39; // 使用更简洁的主题 } } }, computed: { editorOptions() { return this.isReadOnly ? this.readOnlyOptions : this.editableOptions } }, methods: { toggleEditMode() { this.isReadOnly = !this.isReadOnly } } } </script> <style> /* 只读模式下的样式 */ .read-only-mode .ql-container { border: none; background: transparent; } .read-only-mode .ql-editor { padding: 0; } </style> ``` ### 解释 - 使用计算属性动态返回不同的配置 - 只读模式下隐藏工具栏并使用更简洁的主题 - 添加 CSS 样式优化只读模式的外观 ## 方法4:自定义只读组件(高级封装) 对于需要高度定制的只读模式,可以创建专门的只读组件。 ```vue <template> <div> <div v-if="isReadOnly" class="read-only-content" v-html="content"></div> <quill-editor v-else ref="myQuillEditor" v-model:content="content" :options="editorOptions" content-type="html" /> <button @click="toggleEditMode"> {{ isReadOnly ? &#39;启用编辑&#39; : &#39;禁用编辑&#39; }} </button> </div> </template> <script> import { quillEditor } from &#39;vue-quill-editor&#39; import &#39;quill/dist/quill.core.css&#39; import &#39;quill/dist/quill.snow.css&#39; export default { components: { quillEditor }, data() { return { content: &#39;<p>初始内容</p>&#39;, isReadOnly: false, editorOptions: { modules: { toolbar: [ // 同上 ] }, theme: &#39;snow&#39; } } }, methods: { toggleEditMode() { this.isReadOnly = !this.isReadOnly } } } </script> <style> .read-only-content { padding: 12px 15px; border: 1px solid #ccc; border-radius: 4px; min-height: 200px; background: #f9f9f9; } /* 只读模式下公式的特殊样式 */ .read-only-content .ql-formula { display: inline-block; padding: 2px 5px; background: #f0f8ff; border-radius: 3px; } </style> ``` ### 解释 - 使用 `v-if` 和 `v-else` 切换编辑器和只读视图 - 只读视图使用 `v-html` 显示内容 - 优点:完全控制只读模式的外观和行为 - 缺点:需要手动处理样式和特殊内容(如公式) ## 方法5:使用 CSS 禁用编辑(快速解决方案) 最简单的只读模式实现方式,适合不需要复杂交互的场景。 ```vue <template> <div> <quill-editor ref="myQuillEditor" v-model:content="content" :options="editorOptions" content-type="html" :class="{ &#39;read-only-mode&#39;: isReadOnly }" /> <button @click="toggleEditMode"> {{ isReadOnly ? &#39;启用编辑&#39; : &#39;禁用编辑&#39; }} </button> </div> </template> <script> import { quillEditor } from &#39;vue-quill-editor&#39; import &#39;quill/dist/quill.core.css&#39; import &#39;quill/dist/quill.snow.css&#39; export default { components: { quillEditor }, data() { return { content: &#39;<p>初始内容</p>&#39;, isReadOnly: false, editorOptions: { modules: { toolbar: [ // 同上 ] }, theme: &#39;snow&#39; } } }, methods: { toggleEditMode() { this.isReadOnly = !this.isReadOnly } } } </script> <style> /* 只读模式样式 */ .read-only-mode .ql-toolbar { display: none; /* 隐藏工具栏 */ } .read-only-mode .ql-editor { cursor: default; /* 改变光标样式 */ user-select: text; /* 允许文本选择 */ } /* 禁用内容编辑 */ .read-only-mode .ql-container { pointer-events: none; /* 禁用所有交互 */ } /* 允许选择文本 */ .read-only-mode .ql-editor { pointer-events: auto; } </style> ``` ### 解释 - 使用 CSS 的 `pointer-events: none` 禁用编辑器交互 - 保留文本选择功能(`user-select: text`) - 优点:实现简单,无需修改 JavaScript - 缺点:可能影响辅助功能 ## 最佳实践:响应式只读模式组件 结合上述方法的优点,创建一个功能完善的只读模式切换组件: ```vue <template> <div class="editor-container" :class="{ &#39;read-only&#39;: isReadOnly }"> <div v-if="showReadOnlyView" class="read-only-view" v-html="processedContent"></div> <quill-editor v-else ref="quillEditor" v-model:content="content" :options="editorOptions" content-type="html" /> <div class="editor-controls"> <button @click="toggleEditMode" class="mode-toggle"> <span v-if="isReadOnly">编辑内容</span> <span v-else>完成编辑</span> </button> <button v-if="!isReadOnly" @click="saveContent" class="save-btn"> 保存 </button> </div> </div> </template> <script> import { quillEditor } from &#39;vue-quill-editor&#39; import &#39;quill/dist/quill.core.css&#39; import &#39;quill/dist/quill.snow.css&#39; export default { components: { quillEditor }, props: { initialContent: { type: String, default: &#39;<p>输入内容...</p>&#39; }, readOnly: { type: Boolean, default: false } }, data() { return { content: this.initialContent, isReadOnly: this.readOnly, editorOptions: { modules: { toolbar: [ [&#39;bold&#39;, &#39;italic&#39;, &#39;underline&#39;, &#39;strike&#39;], [{ &#39;list&#39;: &#39;ordered&#39;}, { &#39;list&#39;: &#39;bullet&#39; }], [{ &#39;header&#39;: [1, 2, 3, 4, 5, 6, false] }], [{ &#39;color&#39;: [] }, { &#39;background&#39;: [] }], [&#39;link&#39;, &#39;image&#39;, &#39;video&#39;, &#39;formula&#39;], [&#39;clean&#39;] ], // 自定义模块可以在这里添加 }, theme: &#39;snow&#39;, placeholder: &#39;请输入内容...&#39; } } }, computed: { showReadOnlyView() { return this.isReadOnly }, processedContent() { // 这里可以添加只读模式下的内容处理逻辑 // 例如:添加特定的类名或样式 return this.content.replace( /<p>/g, &#39;<p class="read-only-paragraph">&#39; ) } }, watch: { readOnly(newVal) { this.isReadOnly = newVal } }, methods: { toggleEditMode() { this.isReadOnly = !this.isReadOnly this.$emit(&#39;mode-change&#39;, this.isReadOnly) if (!this.isReadOnly) { this.$nextTick(() => { // 切换到编辑模式后聚焦编辑器 const editor = this.$refs.quillEditor?.quill if (editor) { editor.focus() } }) } }, saveContent() { this.$emit(&#39;save&#39;, this.content) }, // 外部调用的方法 setReadOnly(readOnly) { this.isReadOnly = readOnly } } } </script> <style> .editor-container { border: 1px solid #ccc; border-radius: 8px; overflow: hidden; position: relative; } /* 编辑模式样式 */ .ql-toolbar { background: #f8f9fa; border-bottom: 1px solid #e9ecef; } .ql-container { min-height: 300px; } /* 只读模式样式 */ .editor-container.read-only { border-color: #e9ecef; } .read-only-view { padding: 15px; min-height: 300px; background: #f9f9f9; line-height: 1.6; } .read-only-paragraph { margin-bottom: 1em; } /* 控制按钮 */ .editor-controls { padding: 10px; background: #f8f9fa; border-top: 1px solid #e9ecef; display: flex; justify-content: flex-end; gap: 10px; } .mode-toggle, .save-btn { padding: 6px 12px; border: none; border-radius: 4px; cursor: pointer; font-size: 14px; } .mode-toggle { background: #3498db; color: white; } .save-btn { background: #2ecc71; color: white; } </style> ``` ### 组件功能说明 1. **响应式只读模式**: - 通过 `isReadOnly` 状态控制显示编辑视图还是只读视图 - 支持通过 prop 初始化只读状态 2. **内容处理**: -只读视图中使用 `processedContent` 计算属性处理内容 - 可以添加只读模式下的特殊样式 3. **控制按钮**: - 模式切换按钮 - 保存按钮(仅在编辑模式下显示) 4. **事件和API**: - 触发 `mode-change` 事件通知父组件状态变化 - 触发 `save` 事件保存内容 - 提供 `setReadOnly` 方法供外部调用 ## 只读模式下的高级优化 ### 1. 公式渲染优化 在只读模式下,公式可能需要特殊处理: ```javascript // 在 processedContent 计算属性中 processedContent() { let content = this.content; // 为公式添加特殊类名 content = content.replace( /<span class="ql-formula"([^>]*)>/g, &#39;<span class="ql-formula read-only-formula"$1>&#39; ); return content; } ``` ```css /* 只读模式下的公式样式 */ .read-only-formula { padding: 2px 4px; background: #f0f8ff; border-radius: 3px; display: inline-block; } ``` ### 2. 链接处理 在只读模式下,可以添加点击链接的行为: ```javascript mounted() { if (this.isReadOnly) { this.$nextTick(() => { this.addLinkHandlers(); }); } }, methods: { addLinkHandlers() { const links = this.$el.querySelectorAll(&#39;.read-only-view a&#39;); links.forEach(link => { link.addEventListener(&#39;click&#39;, this.handleLinkClick); }); }, handleLinkClick(event) { event.preventDefault(); const href = event.target.href; alert(`链接被点击: ${href}`); // 或者使用 this.$router.push() 处理内部链接 } } ``` ### 3. 内容高亮 在只读模式下添加语法高亮: ```vue <template> <div v-if="showReadOnlyView" class="read-only-view"> <pre v-highlightjs><code class="javascript" v-html="processedContent"></code></pre> </div> </template> <script> import hljs from &#39;highlight.js&#39;; import &#39;highlight.js/styles/github.css&#39;; export default { directives: { highlightjs(el) { const blocks = el.querySelectorAll(&#39;code&#39;); blocks.forEach(block => { hljs.highlightBlock(block); }); } } } </script> ``` ## 只读模式最佳实践 1. **性能优化**: - 对于大型文档,使用虚拟滚动 - 避免在只读模式下加载不必要的模块 2. **可访问性**: -只读模式添加 ARIA 属性 - 确保文本有足够的对比度 3. **打印优化**: - 添加打印样式表 - 隐藏不必要的元素 ```css @media print { .editor-controls, .ql-toolbar { display: none; } .read-only-view, .ql-container { border: none; background: transparent; } } ``` ##
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雾林小妖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值