Ver código fonte

新增富文本组件支持

RuoYi 2 anos atrás
pai
commit
ee2205d4f1
4 arquivos alterados com 168 adições e 8 exclusões
  1. 1 0
      package.json
  2. 163 0
      src/components/Editor/index.vue
  3. 3 2
      src/main.js
  4. 1 6
      src/views/system/notice/index.vue

+ 1 - 0
package.json

@@ -16,6 +16,7 @@
   },
   "dependencies": {
     "@element-plus/icons-vue": "2.0.10",
+    "@vueup/vue-quill": "1.1.0",
     "@vueuse/core": "9.5.0",
     "axios": "0.27.2",
     "echarts": "5.4.0",

+ 163 - 0
src/components/Editor/index.vue

@@ -0,0 +1,163 @@
+<template>
+  <div class="editor">
+      <quill-editor
+        v-model:content="content"
+        contentType="html"
+        @textChange="(e) => $emit('update:modelValue', content)"
+        :options="options"
+        :style="styles"
+      />
+  </div>
+</template>
+
+<script setup>
+import { QuillEditor } from '@vueup/vue-quill';
+import '@vueup/vue-quill/dist/vue-quill.snow.css';
+
+const props = defineProps({
+  /* 编辑器的内容 */
+  modelValue: {
+    type: String,
+  },
+  /* 高度 */
+  height: {
+    type: Number,
+    default: null,
+  },
+  /* 最小高度 */
+  minHeight: {
+    type: Number,
+    default: null,
+  },
+  /* 只读 */
+  readOnly: {
+    type: Boolean,
+    default: false,
+  },
+});
+
+const options = ref({
+  theme: "snow",
+  bounds: document.body,
+  debug: "warn",
+  modules: {
+    // 工具栏配置
+    toolbar: [
+      ["bold", "italic", "underline", "strike"],       // 加粗 斜体 下划线 删除线
+      ["blockquote", "code-block"],                    // 引用  代码块
+      [{ list: "ordered" }, { list: "bullet" }],       // 有序、无序列表
+      [{ indent: "-1" }, { indent: "+1" }],            // 缩进
+      [{ size: ["small", false, "large", "huge"] }],   // 字体大小
+      [{ header: [1, 2, 3, 4, 5, 6, false] }],         // 标题
+      [{ color: [] }, { background: [] }],             // 字体颜色、字体背景颜色
+      [{ align: [] }],                                 // 对齐方式
+      ["clean"],                                       // 清除文本格式
+      ["link", "image", "video"]                       // 链接、图片、视频
+    ],
+  },
+  placeholder: '请输入内容',
+  readOnly: props.readOnly,
+  theme: 'snow'
+});
+
+const styles = computed(() => {
+  let style = {};
+  if (props.minHeight) {
+    style.minHeight = `${props.minHeight}px`;
+  }
+  if (props.height) {
+    style.height = `${props.height}px`;
+  }
+  return style;
+})
+
+const content = ref("");
+watch(() => props.modelValue, (v) => {
+  if (v !== content) {
+    content.value = v === undefined ? "<p></p>" : v;
+  }
+}, { immediate: true });
+
+
+</script>
+
+<style>
+.editor, .ql-toolbar {
+  white-space: pre-wrap !important;
+  line-height: normal !important;
+}
+.quill-img {
+  display: none;
+}
+.ql-snow .ql-tooltip[data-mode="link"]::before {
+  content: "请输入链接地址:";
+}
+.ql-snow .ql-tooltip.ql-editing a.ql-action::after {
+  border-right: 0px;
+  content: "保存";
+  padding-right: 0px;
+}
+
+.ql-snow .ql-tooltip[data-mode="video"]::before {
+  content: "请输入视频地址:";
+}
+
+.ql-snow .ql-picker.ql-size .ql-picker-label::before,
+.ql-snow .ql-picker.ql-size .ql-picker-item::before {
+  content: "14px";
+}
+.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="small"]::before,
+.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="small"]::before {
+  content: "10px";
+}
+.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="large"]::before,
+.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="large"]::before {
+  content: "18px";
+}
+.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="huge"]::before,
+.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="huge"]::before {
+  content: "32px";
+}
+
+.ql-snow .ql-picker.ql-header .ql-picker-label::before,
+.ql-snow .ql-picker.ql-header .ql-picker-item::before {
+  content: "文本";
+}
+.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="1"]::before,
+.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="1"]::before {
+  content: "标题1";
+}
+.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="2"]::before,
+.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="2"]::before {
+  content: "标题2";
+}
+.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="3"]::before,
+.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="3"]::before {
+  content: "标题3";
+}
+.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="4"]::before,
+.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="4"]::before {
+  content: "标题4";
+}
+.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="5"]::before,
+.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="5"]::before {
+  content: "标题5";
+}
+.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="6"]::before,
+.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="6"]::before {
+  content: "标题6";
+}
+
+.ql-snow .ql-picker.ql-font .ql-picker-label::before,
+.ql-snow .ql-picker.ql-font .ql-picker-item::before {
+  content: "标准字体";
+}
+.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="serif"]::before,
+.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="serif"]::before {
+  content: "衬线字体";
+}
+.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="monospace"]::before,
+.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="monospace"]::before {
+  content: "等宽字体";
+}
+</style>

+ 3 - 2
src/main.js

@@ -6,13 +6,11 @@ import ElementPlus from 'element-plus'
 import locale from 'element-plus/lib/locale/lang/zh-cn' // 中文语言
 
 import '@/assets/styles/index.scss' // global css
-
 import App from './App'
 import store from './store'
 import router from './router'
 import directive from './directive' // directive
 
-
 // 注册指令
 import plugins from './plugins' // plugins
 import { download } from '@/utils/request'
@@ -31,6 +29,8 @@ import { parseTime, resetForm, addDateRange, handleTree, selectDictLabel, select
 import Pagination from '@/components/Pagination'
 // 自定义表格工具组件
 import RightToolbar from '@/components/RightToolbar'
+// 富文本组件
+import Editor from "@/components/Editor"
 // 文件上传组件
 import FileUpload from "@/components/FileUpload"
 // 图片上传组件
@@ -62,6 +62,7 @@ app.component('FileUpload', FileUpload)
 app.component('ImageUpload', ImageUpload)
 app.component('ImagePreview', ImagePreview)
 app.component('RightToolbar', RightToolbar)
+app.component('Editor', Editor)
 
 app.use(router)
 app.use(store)

+ 1 - 6
src/views/system/notice/index.vue

@@ -143,12 +143,7 @@
                </el-col>
                <el-col :span="24">
                   <el-form-item label="内容">
-                     <el-input
-                        :rows="6"
-                        type="textarea"
-                        placeholder="请输入内容"
-                        v-model="form.noticeContent"
-                     />
+                    <editor v-model="form.noticeContent" :min-height="192"/>
                   </el-form-item>
                </el-col>
             </el-row>