作者 若依
提交者 Gitee

!180 富文本编辑组件支持只读

Merge pull request !180 from JOSWAY/master
1 -<template>  
2 - <div class="editor" ref="editor" :style="styles"></div>  
3 -</template>  
4 -  
5 -<script>  
6 -import Quill from "quill";  
7 -import "quill/dist/quill.core.css";  
8 -import "quill/dist/quill.snow.css";  
9 -import "quill/dist/quill.bubble.css";  
10 -  
11 -export default {  
12 - name: "Editor",  
13 - props: {  
14 - /* 编辑器的内容 */  
15 - value: {  
16 - type: String,  
17 - default: "",  
18 - },  
19 - /* 高度 */  
20 - height: {  
21 - type: Number,  
22 - default: null,  
23 - },  
24 - /* 最小高度 */  
25 - minHeight: {  
26 - type: Number,  
27 - default: null,  
28 - },  
29 - },  
30 - data() {  
31 - return {  
32 - Quill: null,  
33 - currentValue: "",  
34 - options: {  
35 - theme: "snow",  
36 - bounds: document.body,  
37 - debug: "warn",  
38 - modules: {  
39 - // 工具栏配置  
40 - toolbar: [  
41 - ["bold", "italic", "underline", "strike"], // 加粗 斜体 下划线 删除线  
42 - ["blockquote", "code-block"], // 引用 代码块  
43 - [{ list: "ordered" }, { list: "bullet" }], // 有序、无序列表  
44 - [{ indent: "-1" }, { indent: "+1" }], // 缩进  
45 - [{ size: ["small", false, "large", "huge"] }], // 字体大小  
46 - [{ header: [1, 2, 3, 4, 5, 6, false] }], // 标题  
47 - [{ color: [] }, { background: [] }], // 字体颜色、字体背景颜色  
48 - [{ align: [] }], // 对齐方式  
49 - ["clean"], // 清除文本格式  
50 - ["link", "image", "video"] // 链接、图片、视频  
51 - ],  
52 - },  
53 - placeholder: "请输入内容",  
54 - readOnly: false,  
55 - },  
56 - };  
57 - },  
58 - computed: {  
59 - styles() {  
60 - let style = {};  
61 - if (this.minHeight) {  
62 - style.minHeight = `${this.minHeight}px`;  
63 - }  
64 - if (this.height) {  
65 - style.height = `${this.height}px`;  
66 - }  
67 - return style;  
68 - },  
69 - },  
70 - watch: {  
71 - value: {  
72 - handler(val) {  
73 - if (val !== this.currentValue) {  
74 - this.currentValue = val === null ? "" : val;  
75 - if (this.Quill) {  
76 - this.Quill.pasteHTML(this.currentValue);  
77 - }  
78 - }  
79 - },  
80 - immediate: true,  
81 - },  
82 - },  
83 - mounted() {  
84 - this.init();  
85 - },  
86 - beforeDestroy() {  
87 - this.Quill = null;  
88 - },  
89 - methods: {  
90 - init() {  
91 - const editor = this.$refs.editor;  
92 - this.Quill = new Quill(editor, this.options);  
93 - this.Quill.pasteHTML(this.currentValue);  
94 - this.Quill.on("text-change", (delta, oldDelta, source) => {  
95 - const html = this.$refs.editor.children[0].innerHTML;  
96 - const text = this.Quill.getText();  
97 - const quill = this.Quill;  
98 - this.currentValue = html;  
99 - this.$emit("input", html);  
100 - this.$emit("on-change", { html, text, quill });  
101 - });  
102 - this.Quill.on("text-change", (delta, oldDelta, source) => {  
103 - this.$emit("on-text-change", delta, oldDelta, source);  
104 - });  
105 - this.Quill.on("selection-change", (range, oldRange, source) => {  
106 - this.$emit("on-selection-change", range, oldRange, source);  
107 - });  
108 - this.Quill.on("editor-change", (eventName, ...args) => {  
109 - this.$emit("on-editor-change", eventName, ...args);  
110 - });  
111 - },  
112 - },  
113 -};  
114 -</script>  
115 -  
116 -<style>  
117 -.editor, .ql-toolbar {  
118 - white-space: pre-wrap!important;  
119 - line-height: normal !important;  
120 -}  
121 -.quill-img {  
122 - display: none;  
123 -}  
124 -.ql-snow .ql-tooltip[data-mode="link"]::before {  
125 - content: "请输入链接地址:";  
126 -}  
127 -.ql-snow .ql-tooltip.ql-editing a.ql-action::after {  
128 - border-right: 0px;  
129 - content: "保存";  
130 - padding-right: 0px;  
131 -}  
132 -  
133 -.ql-snow .ql-tooltip[data-mode="video"]::before {  
134 - content: "请输入视频地址:";  
135 -}  
136 -  
137 -.ql-snow .ql-picker.ql-size .ql-picker-label::before,  
138 -.ql-snow .ql-picker.ql-size .ql-picker-item::before {  
139 - content: "14px";  
140 -}  
141 -.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="small"]::before,  
142 -.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="small"]::before {  
143 - content: "10px";  
144 -}  
145 -.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="large"]::before,  
146 -.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="large"]::before {  
147 - content: "18px";  
148 -}  
149 -.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="huge"]::before,  
150 -.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="huge"]::before {  
151 - content: "32px";  
152 -}  
153 -  
154 -.ql-snow .ql-picker.ql-header .ql-picker-label::before,  
155 -.ql-snow .ql-picker.ql-header .ql-picker-item::before {  
156 - content: "文本";  
157 -}  
158 -.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="1"]::before,  
159 -.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="1"]::before {  
160 - content: "标题1";  
161 -}  
162 -.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="2"]::before,  
163 -.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="2"]::before {  
164 - content: "标题2";  
165 -}  
166 -.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="3"]::before,  
167 -.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="3"]::before {  
168 - content: "标题3";  
169 -}  
170 -.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="4"]::before,  
171 -.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="4"]::before {  
172 - content: "标题4";  
173 -}  
174 -.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="5"]::before,  
175 -.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="5"]::before {  
176 - content: "标题5";  
177 -}  
178 -.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="6"]::before,  
179 -.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="6"]::before {  
180 - content: "标题6";  
181 -}  
182 -  
183 -.ql-snow .ql-picker.ql-font .ql-picker-label::before,  
184 -.ql-snow .ql-picker.ql-font .ql-picker-item::before {  
185 - content: "标准字体";  
186 -}  
187 -.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="serif"]::before,  
188 -.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="serif"]::before {  
189 - content: "衬线字体";  
190 -}  
191 -.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="monospace"]::before,  
192 -.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="monospace"]::before {  
193 - content: "等宽字体";  
194 -}  
195 -</style>  
  1 +<template>
  2 + <div class="editor" ref="editor" :style="styles"></div>
  3 +</template>
  4 +
  5 +<script>
  6 +import Quill from "quill";
  7 +import "quill/dist/quill.core.css";
  8 +import "quill/dist/quill.snow.css";
  9 +import "quill/dist/quill.bubble.css";
  10 +
  11 +export default {
  12 + name: "Editor",
  13 + props: {
  14 + /* 编辑器的内容 */
  15 + value: {
  16 + type: String,
  17 + default: "",
  18 + },
  19 + /* 高度 */
  20 + height: {
  21 + type: Number,
  22 + default: null,
  23 + },
  24 + /* 最小高度 */
  25 + minHeight: {
  26 + type: Number,
  27 + default: null,
  28 + },
  29 + /* 只读 */
  30 + readOnly: {
  31 + type: Boolean,
  32 + default: false,
  33 + }
  34 + },
  35 + data() {
  36 + return {
  37 + Quill: null,
  38 + currentValue: "",
  39 + options: {
  40 + theme: "snow",
  41 + bounds: document.body,
  42 + debug: "warn",
  43 + modules: {
  44 + // 工具栏配置
  45 + toolbar: [
  46 + ["bold", "italic", "underline", "strike"], // 加粗 斜体 下划线 删除线
  47 + ["blockquote", "code-block"], // 引用 代码块
  48 + [{ list: "ordered" }, { list: "bullet" }], // 有序、无序列表
  49 + [{ indent: "-1" }, { indent: "+1" }], // 缩进
  50 + [{ size: ["small", false, "large", "huge"] }], // 字体大小
  51 + [{ header: [1, 2, 3, 4, 5, 6, false] }], // 标题
  52 + [{ color: [] }, { background: [] }], // 字体颜色、字体背景颜色
  53 + [{ align: [] }], // 对齐方式
  54 + ["clean"], // 清除文本格式
  55 + ["link", "image", "video"] // 链接、图片、视频
  56 + ],
  57 + },
  58 + placeholder: "请输入内容",
  59 + readOnly: this.readOnly,
  60 + },
  61 + };
  62 + },
  63 + computed: {
  64 + styles() {
  65 + let style = {};
  66 + if (this.minHeight) {
  67 + style.minHeight = `${this.minHeight}px`;
  68 + }
  69 + if (this.height) {
  70 + style.height = `${this.height}px`;
  71 + }
  72 + return style;
  73 + },
  74 + },
  75 + watch: {
  76 + value: {
  77 + handler(val) {
  78 + if (val !== this.currentValue) {
  79 + this.currentValue = val === null ? "" : val;
  80 + if (this.Quill) {
  81 + this.Quill.pasteHTML(this.currentValue);
  82 + }
  83 + }
  84 + },
  85 + immediate: true,
  86 + },
  87 + },
  88 + mounted() {
  89 + this.init();
  90 + },
  91 + beforeDestroy() {
  92 + this.Quill = null;
  93 + },
  94 + methods: {
  95 + init() {
  96 + const editor = this.$refs.editor;
  97 + this.Quill = new Quill(editor, this.options);
  98 + this.Quill.pasteHTML(this.currentValue);
  99 + this.Quill.on("text-change", (delta, oldDelta, source) => {
  100 + const html = this.$refs.editor.children[0].innerHTML;
  101 + const text = this.Quill.getText();
  102 + const quill = this.Quill;
  103 + this.currentValue = html;
  104 + this.$emit("input", html);
  105 + this.$emit("on-change", { html, text, quill });
  106 + });
  107 + this.Quill.on("text-change", (delta, oldDelta, source) => {
  108 + this.$emit("on-text-change", delta, oldDelta, source);
  109 + });
  110 + this.Quill.on("selection-change", (range, oldRange, source) => {
  111 + this.$emit("on-selection-change", range, oldRange, source);
  112 + });
  113 + this.Quill.on("editor-change", (eventName, ...args) => {
  114 + this.$emit("on-editor-change", eventName, ...args);
  115 + });
  116 + },
  117 + },
  118 +};
  119 +</script>
  120 +
  121 +<style>
  122 +.editor, .ql-toolbar {
  123 + white-space: pre-wrap!important;
  124 + line-height: normal !important;
  125 +}
  126 +.quill-img {
  127 + display: none;
  128 +}
  129 +.ql-snow .ql-tooltip[data-mode="link"]::before {
  130 + content: "请输入链接地址:";
  131 +}
  132 +.ql-snow .ql-tooltip.ql-editing a.ql-action::after {
  133 + border-right: 0px;
  134 + content: "保存";
  135 + padding-right: 0px;
  136 +}
  137 +
  138 +.ql-snow .ql-tooltip[data-mode="video"]::before {
  139 + content: "请输入视频地址:";
  140 +}
  141 +
  142 +.ql-snow .ql-picker.ql-size .ql-picker-label::before,
  143 +.ql-snow .ql-picker.ql-size .ql-picker-item::before {
  144 + content: "14px";
  145 +}
  146 +.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="small"]::before,
  147 +.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="small"]::before {
  148 + content: "10px";
  149 +}
  150 +.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="large"]::before,
  151 +.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="large"]::before {
  152 + content: "18px";
  153 +}
  154 +.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="huge"]::before,
  155 +.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="huge"]::before {
  156 + content: "32px";
  157 +}
  158 +
  159 +.ql-snow .ql-picker.ql-header .ql-picker-label::before,
  160 +.ql-snow .ql-picker.ql-header .ql-picker-item::before {
  161 + content: "文本";
  162 +}
  163 +.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="1"]::before,
  164 +.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="1"]::before {
  165 + content: "标题1";
  166 +}
  167 +.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="2"]::before,
  168 +.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="2"]::before {
  169 + content: "标题2";
  170 +}
  171 +.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="3"]::before,
  172 +.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="3"]::before {
  173 + content: "标题3";
  174 +}
  175 +.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="4"]::before,
  176 +.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="4"]::before {
  177 + content: "标题4";
  178 +}
  179 +.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="5"]::before,
  180 +.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="5"]::before {
  181 + content: "标题5";
  182 +}
  183 +.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="6"]::before,
  184 +.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="6"]::before {
  185 + content: "标题6";
  186 +}
  187 +
  188 +.ql-snow .ql-picker.ql-font .ql-picker-label::before,
  189 +.ql-snow .ql-picker.ql-font .ql-picker-item::before {
  190 + content: "标准字体";
  191 +}
  192 +.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="serif"]::before,
  193 +.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="serif"]::before {
  194 + content: "衬线字体";
  195 +}
  196 +.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="monospace"]::before,
  197 +.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="monospace"]::before {
  198 + content: "等宽字体";
  199 +}
  200 +</style>