vue3引入vue-quill富文本编辑器

1,818 阅读3分钟

官方文档:vueup.github.io/vue-quill/g…

安装:
 npm install @vueup/vue-quill@latest --save 

 yarn add @vueup/vue-quill@latest
注册

有全局注册和局部,由于我只有一个页面使用编辑器,这里就展示局部注册

组件VueEditor.vue

<script setup>
......
//引入
import { QuillEditor, Quill } from "@vueup/vue-quill";
import "@vueup/vue-quill/dist/vue-quill.snow.css";

//数据绑定
const content=ref('')
</script>

<template>
 <QuillEditor
      v-model:content="content" 
      contentType="html"
      theme="snow"
    />
   <!--如果要使用 html 或纯文本作为内容,请确保设置 contentType。-->
</template>

注册好后,就能简单使用了。

配置
工具栏配置

根据需要进行配置

// 工具栏配置
const toolbar = ref([
  [{ size: ["small", false, "large", "huge"] }], 
  // 标题-----[{ header: [1, 2, 3, 4, 5, 6, false] }]
  [{ header: [1, 2, 3, 4, 5, 6, false] }],
  // 字体颜色、字体背景颜色-----[{ color: [] }, { background: [] }]
  [{ color: [] }, { background: [] }], 
  // 字体种类-----[{ font: [] }]
  //   [{ font: [] }], 
  // 对齐方式-----[{ align: [] }]
  // 加粗 斜体 下划线 删除线 -----['bold', 'italic', 'underline', 'strike']
  ["bold", "italic", "underline", "strike"],
  // 引用  代码块-----['blockquote', 'code-block']
  ["blockquote", "code-block"], 
  // 1、2 级标题-----[{ header: 1 }, { header: 2 }]
  //   [{ header: 1 }, { header: 2 }], 
  // 有序、无序列表-----[{ list: 'ordered' }, { list: 'bullet' }]
  [{ list: "ordered" }, { list: "bullet" }], 
  // 上标/下标-----[{ script: 'sub' }, { script: 'super' }]
  [{ script: "sub" }, { script: "super" }],
  // 缩进-----[{ indent: '-1' }, { indent: '+1' }]
  [{ indent: "-1" }, { indent: "+1" }], // 文本方向-----[{'direction': 'rtl'}]
  // 字体大小-----[{ size: ['small', false, 'large', 'huge'] }]
  [{ align: [] }], // 清除文本格式-----['clean']
  ["clean"], // 链接、图片、视频-----['link', 'image', 'video']
  ["image"],
  ["link"],
  ["video"],
]);

如果你只需要配置工具栏不需配置自定义图片上传和图片设置,那么就可以直接这样写

 <QuillEditor
      v-model:content="content"
      contentType="html"toolbar="toolbar"
    />

配置完成后,编辑器如图所示

image.png

如果需要配置图片上传和图片设置,可以往下看

自定义图片上传

首先先安装quill-image-uploader插件

npm install quill-image-uploader --save

然后vue里面注册并使用


<script setup>
......
//引入与注册quill-image-uploader
import ImageUploader from "quill-image-uploader";

if (!Quill.imports["modules/ImageUploader"]) {
  Quill.register("modules/ImageUploader", ImageUploader);
}

//配置
const options = reactive({
  modules: {
    ImageUploader: {
      upload(file) {
        return new Promise((resolve, reject) => {
        //上传服务器
         let formdata = new FormData();
          formdata.append("file", await file);
            axios({
              url: url,
              method: "post",
              data: formdata,
            }).then((res) => {
              // console.log(res);
              resolve(res.data.data);
            });
        });
      },
    },
    toolbar: toolbar.value //配置工具栏
  },
  placeholder: '請輸入內容...',
  theme: 'snow',
});
</script>

<template>
 <QuillEditor
      v-model:content="content" 
      contentType="html"
      :options="options" //重点
    />
   <!--如果要使用 html 或纯文本作为内容,请确保设置 contentType。-->
</template>

这样就完成上传服务器的功能啦

图片设置

既然能上传图片,那就需要调整图片大小的功能

同图片上传的操作一致,也是要引入插件 首先先安装quill-blot-formatter插件

npm install quill-blot-formatter --save

注册与使用


<script setup>
......
//引入与注册quill-blot-formatter
import BlotFormatter from "quill-blot-formatter";

if (!Quill.imports["modules/BlotFormatter"]) {
  Quill.register("modules/BlotFormatter", BlotFormatter);
}

//配置
const options = reactive({
  modules: {
    //图片上传
     ImageUploader: {......},
    //图片大小位置设置
      BlotFormatter,
    toolbar: toolbar.value //配置工具栏
  },
  placeholder: '請輸入內容...',
  theme: 'snow',
});
</script>

<template>
 <QuillEditor
      v-model:content="content" 
      contentType="html"
      :options="options" //重点
    />
   <!--如果要使用 html 或纯文本作为内容,请确保设置 contentType。-->
</template>

这样就大功告成了,快去试试吧

完整代码
<script setup>
import { ref, reactive, watch, onMounted } from "vue";
import { QuillEditor, Quill } from "@vueup/vue-quill";
import "@vueup/vue-quill/dist/vue-quill.snow.css";
import ImageUploader from "quill-image-uploader";
import BlotFormatter from "quill-blot-formatter";
import axios from "axios";
import { dataAdd } from "@/apis/sign";
import { MsgStore } from "@/store/knowStore";

//注册
if (!Quill.imports["modules/ImageUploader"]) {
  Quill.register("modules/ImageUploader", ImageUploader);
}
if (!Quill.imports["modules/BlotFormatter"]) {
  Quill.register("modules/BlotFormatter", BlotFormatter);
}

// 工具栏配置
const toolbar = ref([
  [{ size: ["small", false, "large", "huge"] }], 
  // 标题-----[{ header: [1, 2, 3, 4, 5, 6, false] }]
  [{ header: [1, 2, 3, 4, 5, 6, false] }],
  // 字体颜色、字体背景颜色-----[{ color: [] }, { background: [] }]
  [{ color: [] }, { background: [] }], 
  // 字体种类-----[{ font: [] }]
  //   [{ font: [] }], 
  // 对齐方式-----[{ align: [] }]
  // 加粗 斜体 下划线 删除线 -----['bold', 'italic', 'underline', 'strike']
  ["bold", "italic", "underline", "strike"],
  // 引用  代码块-----['blockquote', 'code-block']
  ["blockquote", "code-block"], 
  // 1、2 级标题-----[{ header: 1 }, { header: 2 }]
  //   [{ header: 1 }, { header: 2 }], 
  // 有序、无序列表-----[{ list: 'ordered' }, { list: 'bullet' }]
  [{ list: "ordered" }, { list: "bullet" }], 
  // 上标/下标-----[{ script: 'sub' }, { script: 'super' }]
  [{ script: "sub" }, { script: "super" }],
  // 缩进-----[{ indent: '-1' }, { indent: '+1' }]
  [{ indent: "-1" }, { indent: "+1" }], // 文本方向-----[{'direction': 'rtl'}]
  // 字体大小-----[{ size: ['small', false, 'large', 'huge'] }]
  [{ align: [] }], // 清除文本格式-----['clean']
  ["clean"], // 链接、图片、视频-----['link', 'image', 'video']
  ["image"],
  ["link"],
  ["video"],
]);

//配置
const options = reactive({
  modules: {
    ImageUploader: {
      upload(file) {
        return new Promise((resolve, reject) => {
          //上传服务器
         let formdata = new FormData();
          formdata.append("file",  file);
            axios({
              url: url,
              method: "post",
              data: formdata,
            }).then((res) => {
              // console.log(res);
              resolve(res.data.data);
            });
          });
        });
      },
    },
    BlotFormatter,
    toolbar: toolbar.value
  },
  placeholder: '請輸入內容...',
  theme: 'snow',
});

//数据
const content = ref("");

//保存
const submit = () => {
  // console.log(content.value);
  if (content.value=='') {
    return ElMessage({
      type: "warning",
      message: "请输入正文",
    });
  }

};

</script>

<template>
  <div>
    <QuillEditor
      v-model:content="content"
      contentType="html"
      :options="options"
    >
    </QuillEditor>
  
    <div class="button">
      <el-button @click="submit" type="primary">保存</el-button>
    </div>
  </div>
</template>

<style scoped lang="scss">
.button {
  padding: 1% 0;
  text-align: center;
}

:deep(.ql-snow .ql-tooltip){
  top: 0 !important;
  left: 0 !important;
}
</style>

有什么地方不对,欢迎评论区指出来

image.png