Quill的菜单栏控制模块toolbar的container

lxf2023-12-18 01:40:01

序言

今天在review以前代码,看到了以前应用Quill时,碰见了Vue和Quill兼容问题的区域,后边克服了。但没记下来,今日将它记录一下,便于之后查看。

情况出现

Quill的菜单栏控制模块toolbar,我们都是自定的,根据dom完成,把相对应的dom的id发送给toolbar的container。

  <div id="toolbar">
    <span class="ql-formats">
      <select class="ql-header" v-model="headerVal">
        <option
          v-for="item in headerArr"
          :key="item.label"
          :value="item.value"
        >{{item.label}}</option>
      </select>
    </span>
  </div>  
// 数据类型
   headerVal: '',
   headerArr: [
      {
        label: '文章正文',
        value: ''
      }, {
        label: '一级标题',
        value: '1'
      }, {
        label: '二级标题',
        value: '2'
      }, {
        label: '三级标题',
        value: '3'
      }
   ]

我们想默认选中文章正文,可设置headerVal去设定选定。乍一看没什么问题。也挑中。

Quill的菜单栏控制模块toolbar的container

可是进行后,才知道里边这个选项并没有选定。

Quill的菜单栏控制模块toolbar的container

大家预估是这样子的:

Quill的菜单栏控制模块toolbar的container

并且Quill其本身有一个逻辑性,便是当我们的鼠标光标集中在文章标题下,toolbar文章的标题那项就会变成相匹配文章的标题那项。

假如你集中在一般文字下,toolbar文章的标题那项就会变成文章正文那项并选定。

应用上边的这类书写后,这个思路也被忽略了,并没有选定。

究竟是什么严重影响?

找准问题

思考未果,便去查询Quill的源代码,看一下它本来是如何完成了。

选取一部分有关编码:

if (input.tagName === 'SELECT') {
    let option;
    if (range == null) {
      option = null;
    } else if (formats[format] == null) {
      option = input.querySelector('option[selected]');
    } else if (!Array.isArray(formats[format])) {
      let value = formats[format];
      if (typeof value === 'string') {
        value = value.replace(/\"/g, '\\"');
      }
      option = input.querySelector(`option[value="${value}"]`);
    }
    if (option == null) {
      input.value = '';   // TODO make configurable?
      input.selectedIndex = -1;
    } else {
      option.selected = true;
    }
 }

能够看见他会找现阶段增设了selected属性option,若是有就设定选定,并没有也不选定。

最后我们去看你们3D渲染后dom,看有没有selected特性,才知道,并没有selected特性。

Quill的菜单栏控制模块toolbar的container

要是没有,那就要手动式设置上才可以。

因此三下五除二,就改好了。

  <select class="ql-header">
    <option
      v-for="item in headerArr"
      :key="item.label"
      :value="item.value"
      :selected="item.selected"
    >{{item.label}}</option>
  </select>
  // headerArr文件格式
   headerArr: [
      {
        label: '文章正文',
        value: '',
        selected: true
      }, {
        label: '一级标题',
        value: '1'
      }, {
        label: '二级标题',
        value: '2'
      }, {
        label: '三级标题',
        value: '3'
      }
   ]         

一般来说,那样手动式设定应当能设上了啊。

可是出乎意料的是,未设置上。还是没selected特性。

难道是vue过虑了selected特性?

不会轻易设定selected特性?

带上这种困惑,去搜索下材料,才知道,可以说是vue问题。

连接在这儿

Quill的菜单栏控制模块toolbar的container

官方回应说selected是作为元素prop,而非原素的特性。所以设定selected特性没有任何意义。

节选自vue一部分源代码:

  for (let i = 0, l = el.options.length; i < l; i  ) {
    const option = el.options[i];
    const optionValue = getValue(option);
    if (isMultiple) {
      if (isArray(value)) {
        option.selected = looseIndexOf(value, optionValue) > -1;
      }
      else {
        option.selected = value.has(optionValue);
      }
    }
    else {
      if (looseEqual(getValue(option), value)) {
        if (el.selectedIndex !== i)
          el.selectedIndex = i;
        return;
      }
    }
  }

也能看到vue会设定option二维数组的selected和select的selectedIndex,可是不会轻易设定dom的selected特性。

问题改进

那么要如何解决呢?此刻可以用命令处理。

根据命令插进dom时,把它selected特性属性设置上。那样应当就可以解决了,真的是一波三折。

先申请注册命令:

import Vue from 'vue'
// 特性命令 v-attr:selected="true" v-attr:selected="false"
Vue.directive('attr', function (el, binding, vnode) {
  let value = binding.value
  // true应用空字符串取代
  if (value === true) value = ''
  if (value === '' || value) {
    el.setAttribute(binding.arg, value)
  }
})

然后来使用命令

<select class="ql-header">
    <option
      v-for="item in headerArr"
      :key="item.label"
      :value="item.value"
      v-attr:selected="item.selected"
    >{{item.label}}</option>
</select>

最后可以完全处理问题。

Quill的菜单栏控制模块toolbar的container

汇总

Vue如果跟Quill兼容问题应该怎么办,那就要看一下是哪儿遇到的问题,再找相对应的方式,要是没有,就能看有没有最合适的方式。

方式全是人想出来,给油!

本站是一个以CSS、JavaScript、Vue、HTML为中心的前端开发技术网址。我们的使命是为众多前端工程师者提供全方位、全方位、好用的前端工程师专业知识和技术服务。 在网站上,大家可以学到最新前端开发技术,掌握前端工程师最新发布的趋势和良好实践。大家提供大量实例教程和实例,让大家可以快速上手前端工程师的关键技术和程序。 本站还提供了一系列好用的工具软件,帮助你更高效地开展前端工程师工作中。公司提供的一种手段和软件都要经过精心策划和改进,能够帮助你节约时间精力,提高研发效率。 此外,本站还拥有一个有活力的小区,你可以在社区里与其它前端工程师者沟通交流技术性、交流经验、处理问题。我们坚信,街道的能量能够帮助你能够更好地进步与成长。 在网站上,大家可以寻找你需要的一切前端工程师网络资源,使您成为一名更加出色的网页开发者。欢迎你添加我们的大家庭,一起探索前端工程师的无限潜能!