quill 自定义主题样式


theme: smartblue

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第7天,点击查看活动详情

好久不见,我是 new_cheng。

使用富文本的时候,自带的主题样式一般比较朴素,无法满足个性化需求,我们需要自定义一套主题样式。
这里,我们以quill富文本编辑器为例,说说怎么给富文本添加自定义主题。

quill

使用开源的vue-quill-editor,创建富文本编辑器组件。我们要在编辑器的工具栏上添加一项配置:主题切换选择;默认使用富文本自带的主题,点击切换主题后,编辑器的文本内容会根据主题样式进行变更。下面我们会创建一个基于 vue-quill-editor 的公共富文本组件。

image.png

vue-quill-editor 组件的基本使用请查看官方文档:https://github.com/surmon-china/vue-quill-editor

自定义工具栏配置

首先通过toolbar模块来配置工具栏

editorOption: {
  theme: 'snow',
  modules: {
    toolbar: {
      container: [
        ...
        [
          {
            themeSysle: ['norm-theme', 'advanced-greed-theme']
          }
        ]
      ]
    }
  }
}

vue-quill-editor 组件上使用配置:

    <quillEditor
      ref="myQuillEditor"
      :class="['myQuillEditor', `${contentTheme}`, disabled ? 'isDisabled' : '']"
      :options="editorOption"
      v-model="localContents"
    ></quillEditor>

多语言配置

因为我们后面要使用的是中文名称的主题,所以还需要给工具栏添加中文多语言。

创建一个editor.js文件,存放中文多语言配置。

const titleConfig = {
  'ql-bold': '加粗',
  'ql-color': '颜色',
  'ql-font': '字体',
  'ql-clean': '清除字体样式',
  'ql-themeStyle': '主题样式'
}
export function addQuillTitle (oToolBar) {
  const aButton = oToolBar.querySelectorAll('button')
  const aSelect = oToolBar.querySelectorAll('select')
  aButton.forEach(function (item) {
    if (item.className === 'ql-script') {
      item.value === 'sub' ? item.title = '下标' : item.title = '上标'
    } else if (item.className === 'ql-indent') {
      item.value === '+1' ? item.title = '向右缩进' : item.title = '向左缩进'
    } else {
      item.title = titleConfig[item.classList[0]]
    }
  })
  aSelect.forEach(function (item) {
    item.parentNode.title = titleConfig[item.classList[0]]
  })
}

然后,在 vue-quill-editor 组件中设置ready事件:

<quillEditor
      ref="myQuillEditor"
      :options="editorOption"
      v-model="localContents"
      @ready="onEditorReady($event)"
    ></quillEditor>
methods: {
  onEditorReady (editor) {
      const toolbar = editor.getModule('toolbar')
      // import { addQuillTitle } from './editor'
      addQuillTitle(toolbar.container)
    },
}

接着,设置主题的中文名称,创建一个zh.less文件:

.ql-toolbar {
  .ql-themeStyle {
    span[data-value="norm-theme"]::before {
      content: '标准主题' !important
    }
    span[data-value="advanced-green-theme"]::before {
      content: '绿绘主题' !important
    }
  }
}

在公共富文本组件中引入zh.less:

<style lang="less">
@import './styles/zh.less';
<style>

到这里,我们就拥有了一个下拉选择主题的配置。

编写主题样式

再创建一个 less 文件: advanced-green-theme.less,该文件的内容主要是对quill样式的重写。

.advanced-green-theme {
  // .ql-editor {
    font-size: 16px !important;
    color: #222;
    line-height: 1.6;
    p {
      font-size: 16px;
    }
    h1,h2,h3,h4,h5,h6 {
      color: #333;
      font-weight: 500;
      margin: 16px 0;
      span {
        color: #333;
      }
    }
    h1 {
      font-size: 26px !important;
    }
    h2 {
      font-size: 22px !important;
      background: url('../assets/h2-bg.png');
      background-repeat: no-repeat;
      background-size: 100% 40%;
      background-position: bottom;
    }
    h4 {
      font-size: 18px !important;
      &::before {
        content: '';
        display: inline-block;
        margin-right: 17px;
        width: 21px;
        height: 12px;
        background: linear-gradient(90deg, #52cfc5 50%, rgba(59, 204, 192, .3) 50%);
      }
    }
    h3 {
      font-size: 20px !important;
    }
    ol {
      li {
        font-size: 16px;
        &::before {
          color: #52cfc5;
          font-size: 16px;
        }
      }
    }
    ul {
      li {
        font-size: 16px;
        &::before {
          color: #52cfc5;
          font-size: 16px !important;
        }
      }
    }
    a {
      color: #14a4e0;
      font-size: 18px !important;
    }
    img {
      border-radius: 12px;
      margin: 10px;
      max-width: 100%;
    }
    blockquote {
      text-size-adjust: 100%;
      border-radius: 6px;
      line-height: 1.55em;
      text-align: left;
      border: none !important;
      background: #e5f8f6;
      padding: 20px;
      margin-bottom: 20px;
      margin-top: 20px;
      font-size: 16px !important;
      &::before {
        content: "“";
        color: #3bccc0;
        font-size: 28px;
      }
      &::after {
        content: "”";
        color: #3bccc0;
        float: right;
        font-size: 28px;
        margin-top: 10px;
      }
    }
    .strong {
      font-weight: bold;
    }
  // }
}

然后在vue项目的入口文件:main.js,引入该主题文件:

import '@/components/quill-editor/styles/advanced-green-theme.less'

让主题样式生效

上面我们只是做好了配置相关的工作,要想让主题样式生效,还需要做些处理。

在 quil-editor 组件中:

<template>
<quillEditor
      ref="myQuillEditor"
      :class="['myQuillEditor', `${contentTheme}`, disabled ? 'isDisabled' : '']"
      :options="editorOption"
      v-model="localContents"
       @change="onEditorChange($event)"
      @ready="onEditorReady($event)"
    ></quillEditor>
</template>
<script>
export default {
  props: {
    content: String // 富文本内容
  },
  data () {
    return {
      contentTheme: 'norm-theme' // 保存当前使用的主题,用于设置富文本编辑器的class
    }
  },
  watch: {
  // 监听内容变化,设置主题
  content (newVal) {
    if (newVal.includes('advanced-green-theme')) {
      // 设置当前的富文本主题
      this.contentTheme = 'advanced-green-theme'
      const themeDom = document.querySelector('.ql-themeStyle')
      if (themeDom) {
        // 更新工具栏中的当前主题名称,设置为advanced-green-theme后,显示的主题名称将会是我们在前面设置的中文名称
        themeDom.children[0].dataset.value = 'advanced-green-theme'
      }
    } else {
      this.contentTheme = 'norm-theme'
    }
  }
},
  methods: {
        onEditorChange: debounce(function ({ quill, html, text }) {
      if (this.contentTheme === 'advanced-green-theme') {
        // 当使用自定义的主题时,在富文本内容外嵌套一个div
        const nHtml = `<div class="advanced-green-theme">${html}</div>`
        this.$emit('updateContent', nHtml)
      } else {
        this.$emit('updateContent', html)
      }
    }, 400),
  }
}
</script>

将富文本内容包裹一个div是为了在显示富文本内容(v-html)时,也能使用我们定义的主题样式;因为前面我们已经将主题样式在入口文件中引入了。

这里还有一个好处是为了在微信小程序中也能使用自定义的主题。

使用该组件

<QuillEditor
  :content="formData.detailContent"
  class="news-dialog-editor"
  @updateContent="updateContent"
  ></QuillEditor>
data () {
  return {
    formData: {
      detailsContent: ''
    }
  }
},
methods: {
  updateContent (val) {
    this.formData.detailContent = val
  },
}

到这里,quill 自定义主题样式就完成了。

先挖个坑,后续再讲讲怎么在微信小程序中显示带有自定义主题的富文本内容

欢迎关注我的个人公众号 @JSHub:提供最新的开发信息速报,优质的技术干货推荐。或是查看我的个人博客:

喜欢就支持一下吧
点赞10 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容