vue el-cascader组件change失效以及下拉框不消失的问题

1.前言

最近项目上用到el-cascader这个组件,需要可以选第一级菜单,也需要可以选第二级菜单,点击完成之后需要关闭下拉框。其实功能比较简单,找了很多资料,没有找到合适的方案,下面还是自己想了个方案才解决问题

2. 碰到的问题

1.如何让下拉框消失?
2.change方法只是值发生改变才会触发,如果是同一个值就不会触发这个方法,我看有些人还去改源码?

3. 如何解决这两个问题

首先需要change方法

    //关闭联级面板
    cascaderChange() {
      //监听值发生变化就关闭它
      this.$refs.cascaderLocation.dropDownVisible = false;
      this.$refs.cascaderType.dropDownVisible = false;
    },

然后还需要visible-change这个方法,当下拉框出现值为true,下拉框消失值为false

//地点
<el-cascader
  v-model="formSearch.location"
  :show-all-levels="false"
  :options="locations"
  :props="{ checkStrictly: true, expandTrigger: 'hover' }"
  ref="cascaderLocation"
  @change="cascaderChange"
  clearable
  style="width:210px;"
  @visible-change="value => cascaderVisibleChange(value, 'location')"
></el-cascader>

//算法类型
<el-cascader
  v-model="formSearch.type"
  :show-all-levels="false"
  :options="algorithms"
  :props="{ checkStrictly: true, expandTrigger: 'hover' }"
  style="width:130px;"
  ref="cascaderType"
  @change="cascaderChange"
  @visible-change="value => cascaderVisibleChange(value, 'type')"
></el-cascader>

项目里面用了两种类型的,逻辑是当点开下拉框,先把原始值保存起来,再把值直接赋值为空,保存起来的目的是防止用户没选直接关闭了下拉框,这种情况就需要用到原来保存起来的值

cascaderVisibleChange(value, type) {
  if (value) {
    if (type == "location") {
      this.oldLocation = this.formSearch.location;
      this.formSearch.location = "";
    } else if (type == "type") {
      this.oldType = this.formSearch.type;
      this.formSearch.type = "";
    }
  } else {
    if (type == "location" && !this.formSearch.location) {
      this.formSearch.location = this.oldLocation;
    } else if (type == "type" && !this.formSearch.type) {
      this.formSearch.type = this.oldType;
    }
  }
}

结果如下图:
在这里插入图片描述

<think>我们正在使用vue-quill-editor富文本编辑器,需要将字体大小下拉框的选项显示为中文(例如:"小号"、"中号"、"大号"等),而是默认的英文或像素值(如"12px")。根据引用[2]中的方法,我们可以自定义字体大小的白名单(whitelist),但是白名单中设置的是具体的像素值,并且在下拉框中显示的就是这些像素值(如"12px")。现在希望显示的是对应的中文文本。思路:1.我们需要修改下拉框的显示文本,但实际值仍然是像素值。2.可以通过自定义下拉框选项来实现,使用一个数组映射像素值到中文文本。3.Quill允许我们自定义模块,特别是工具栏的按钮和下拉框。步骤:参考引用[2]中自定义字体大小的方式,我们首先注册了自定义的字体大小列表(像素值)。然后,我们需要在工具栏配置中为字体大小下拉框提供自定义的选项文本。但是,Quill的工具栏配置中,对于字体大小下拉框(size),我们可以通过提供一个数组来指定显示文本和实际值的映射。具体来说,我们可以这样配置:在toolbar选项中,对于size,我们可以传入一个数组,数组的每个元素是一个数组,内层数组的第一个元素是显示文本,第二个元素是实际值。例如: ```javascripttoolbar:{...size:[['小号','12px'],['中号','14px'],['大号','16px']] }```然而,根据Quill的官方文档,实际上Quill的size按钮的配置格式是:一个字符串数组,每个字符串是有效的尺寸(如'12px'),然后显示的就是这个字符串。但Quill也支持对象数组格式来同时设置文本和值,但注意Quill1.x版本中可能支持直接这样配置。因此,我们需要使用另一种方法:自定义一个下拉框,并覆盖原有的size下拉框。具体步骤:1.首先,我们仍然需要注册可用的字体大小(像素值),因为编辑时需要应用这些样式。2.然后,在工具栏配置中,我们使用自定义的下拉框,而是使用Quill自带的size按钮。我们可以参考引用[2]中的自定义字体部分,但这里我们需要自定义的是字体大小的下拉框。由于Quill允许我们自定义工具栏模块,我们可以创建一个自定义的下拉框模块,该模块显示中文文本,但实际值还是像素值。但是,为了简化,我们可以利用Quill的扩展机制,覆盖默认的size按钮的显示文本。然而,Quill并没有直接提供修改下拉选项文本的配置项。因此,我们可以采取以下步骤:方法一:在Quill初始化后,通过操作DOM来修改下拉框的选项文本。但这种方法够优雅,且可能在动态变化时失效。方法二:自定义一个工具栏模块,完全按照我们需要的格式来创建下拉框。这里我们采用方法二,因为这样更符合Quill的扩展方式。步骤:1.引入Quill2.定义一个自定义模块,用于生成一个带有中文选项的下拉框。3.在工具栏中配置使用这个自定义模块。具体代码:首先,我们定义一个自定义的字体大小下拉框模块:```javascript//自定义字体大小下拉框模块const SizeStyle= Quill.import('attributors/style/size') SizeStyle.whitelist =['12px','14px','16px','18px','20px','32px']//设置允许的字体大小Quill.register(SizeStyle, true) //自定义工具栏模块constfontSizeStyle= {'12px':'小号','14px': '中号','16px':'大号','18px': '较大','20px': '特大','32px': '超大'} letSize= Quill.import('formats/size')Size.whitelist= ['12px', '14px', '16px', '18px', '20px', '32px']Quill.register(Size,true)constFontSize =Quill.import('formats/size')classCustomSizeextends FontSize {staticcreate(value){const node= super.create(value)returnnode}} Quill.register(CustomSize,true)//定义自定义模块class CustomFontSize{constructor(quill, options) {this.quill =quillthis.options= optionsthis.container= quill.containerletselect= document.createElement('select')select.classList.add('ql-size')select.innerHTML =`<optionvalue="">字体大小</option><option value="12px">小号</option><optionvalue="14px">中号</option><option value="16px">大号</option><optionvalue="18px">较大</option><optionvalue="20px">特大</option><optionvalue="32px">超大</option>`quill.container.parentNode.insertBefore(select,quill.container)select.addEventListener('change',(e) =>{quill.format('size',e.target.value)})}} //注册自定义模块Quill.register('modules/customSize', CustomFontSize) ```然后,在Vue组件中,我们在初始化Quill编辑器时,使用这个自定义模块:```javascriptimportQuill from'quill'export default{data(){return {editorOption: {modules: {toolbar: {container: [['bold', 'italic','underline', 'strike'],// ...其他工具栏按钮[{'size': []}]//这里我们使用默认的size,而是使用自定义模块],handlers: {//如果需要,可以在这里添加其他处理函数}},customSize: {}//启用自定义字体大小模块}}}}} ```但是,这样会同时出现两个字体大小下拉框(原有的和自定义的)。因此,我们需要在工具栏配置中去掉原有的size按钮,只保留我们自定义的下拉框。修改:在toolbar.container中,我们要包含size按钮,因为我们已经在自定义模块中创建了一个下拉框。但是,我们如何将自定义的下拉框放在工具栏中呢?我们可以将自定义下拉框的创建放在工具栏容器中,而是放在编辑器容器前面。因此,我们需要修改自定义模块,将下拉框添加到工具栏容器中。更好的做法是:在Quill的工具栏配置中,我们使用一个自定义按钮,然后在自定义按钮的处理函数中动态创建下拉框,但这样比较复杂。另一种思路:我们直接修改Quill的默认size下拉框的文本。但是Quill默认的size下拉框是通过一个数组生成的,我们无法直接修改其显示文本。因此,我们可能需要完全自定义工具栏,将整个工具栏自己实现。但这样工作量太大。参考Quill官方关于自定义工具栏的文档:https://quilljs.com/docs/modules/toolbar/我们可以在工具栏配置中,使用一个自定义的选择器,然后通过CSS隐藏原来的下拉框,并添加我们自己的下拉框。但这样也够好。经过研究,我们可以通过覆盖Quill的默认下拉框的渲染方式来实现。但是Quill并提供这个功能。所以,我们采用另一种方法:在组件挂载后,通过DOM操作修改下拉框的选项文本。步骤:1.在Quill初始化后,获取到工具栏中的.ql-size下拉框元素。2.遍历这个下拉框的每个option,根据其value设置对应的中文文本。代码示例:```javascriptmounted() {this.$nextTick(()=> {//找到工具栏中的.ql-size下拉框constsizeSelect= this.$el.querySelector('.ql-size')if (sizeSelect) {constoptions =sizeSelect.querySelectorAll('option')options.forEach(option=> {constvalue =option.valueif (value){//根据value设置中文文本option.textContent =fontSizeStyle[value] ||value}})}})} ```其中,fontSizeStyle是我们定义的一个映射对象:```javascriptconstfontSizeStyle= {'12px': '小号','14px':'中号','16px': '大号','18px':'较大','20px':'特大','32px':'超大' }```这种方法比较简单,但需要注意,如果工具栏是动态生成的,可能需要监听变化或者使用MutationObserver。但是,在vue-quill-editor中,工具栏是在初始化时生成的,所以我们在mounted钩子中操作是可行的。综合以上,我们选择在mounted中修改DOM的方法。具体步骤总结:1.组件中,按照引用[2]的方法注册自定义的字体大小白名单(像素值)。2.组件的toolbar配置中,配置size按钮,使用像素值数组(这样下拉框会有这些选项)。3.组件的mounted钩子中,使用DOM操作将下拉框的选项文本替换为中文。代码示例:在vue组件中: ```javascriptimport Quill from'quill'//自定义字体大小白名单const Size= Quill.import('attributors/style/size') Size.whitelist= ['12px', '14px', '16px', '18px', '20px', '32px'] Quill.register(Size, true) exportdefault {data() {return{content: '',editorOption:{modules:{toolbar:{container:[//其他工具栏按钮...[{'size': ['12px', '14px', '16px', '18px', '20px', '32px'] }] //使用像素值数组]}}}}},mounted() {this.replaceSizeSelectText()},methods:{replaceSizeSelectText() {//等待编辑器渲染完成this.$nextTick(() =>{const toolbar= this.$refs.quillEditor.quill.getModule('toolbar').containerconstsizeSelect= toolbar.querySelector('.ql-size')if (sizeSelect) {constfontSizeMap= {'12px': '小号','14px':'中号','16px': '大号','18px':'较大','20px':'特大','32px':'超大'}Array.from(sizeSelect.options).forEach(option =>{if (option.value) {option.text =fontSizeMap[option.value]|| option.value}})}})}}} ```注意:这里假设组件的模板中给vue-quill-editor组件设置了ref="quillEditor"。这种方法的好处是简单直接,需要自定义模块,但缺点是依赖于DOM操作,如果Quill的内部结构变化可能会失效过,只要Quill的工具栏中size下拉框的类名(.ql-size)变,就可以使用。另外,如果用户动态改变工具栏(比如通过修改toolbar配置),可能需要重新调用replaceSizeSelectText方法。因此,我们也可以考虑使用MutationObserver来监听工具栏的变化,但一般情况下,工具栏初始化后会改变。综上所述,我们采用上述DOM操作的方法来实现需求。注意:在vue-quill-editor中,我们可能需要等待编辑器实例创建完成,所以使用$nextTick。如果编辑器是异步创建的(比如在对话框内),则需要在编辑器显示后再调用replaceSizeSelectText。因此,根据实际情况调整调用时机。最后,我们提供完整的代码示例:组件代码: ```vue<template><div><quill-editorref="quillEditor"v-model="content":options="editorOption"/></div> </template><script>import Quill from'quill'//自定义字体大小白名单const Size= Quill.import('attributors/style/size') Size.whitelist= ['12px', '14px', '16px', '18px', '20px', '32px'] Quill.register(Size, true) exportdefault {data() {return{content:'',editorOption: {modules: {toolbar: {container: [['bold','italic', 'underline','strike'],//其他工具栏按钮...[{'size': ['12px', '14px', '16px', '18px', '20px', '32px'] }] //配置size按钮]}}}}},mounted(){this.replaceSizeSelectText()},methods: {replaceSizeSelectText(){this.$nextTick(()=> {//获取Quill工具栏容器const toolbar= this.$refs.quillEditor.quill.getModule('toolbar').containerconstsizeSelect= toolbar.querySelector('select.ql-size')if (sizeSelect) {constfontSizeMap= {'12px': '小号','14px':'中号','16px': '大号','18px':'较大','20px':'特大','32px':'超大'}//遍历下拉框的每个选项Array.from(sizeSelect.options).forEach(option =>{if (option.value) {//根据value设置中文文本option.text= fontSizeMap[option.value] ||option.value}})}})}} }</script> ```这样,字体大小下拉框就会显示为中文了。注意:如果下拉框的选项没有全部替换,请检查whitelist是否和下拉框配置的数组一致,以及映射表是否覆盖了所有选项。另外,如果工具栏中有多个.ql-size元素(通常只有一个),需要确保选择器正确。如果编辑器有多个实例,需要对每个实例都执行此操作。以上方法实现了将字体大小下拉框的选项显示为中文的需求。</think>要将 `vue-quill-editor` 的字体大小下拉框显示文本改为中文,需要自定义字体大小选项并覆盖默认的英文显示。以下是具体实现步骤: ### 解决方案 1. **自定义字体大小映射关系** 创建中文字体大小与像素值的映射关系: ```javascript const fontSizeMap = { '12px': '小号', '14px': '中号', '16px': '大号', '18px': '较大', '20px': '特大', '32px': '超大' }; ``` 2. **注册自定义字体大小选项** 在组件初始化时注册自定义字体大小: ```javascript import Quill from 'quill'; // 注册自定义字体大小 const Size = Quill.import('attributors/style/size'); Size.whitelist = Object.keys(fontSizeMap); // 设置允许的字体大小 Quill.register(Size, true); ``` 3. **覆盖下拉框渲染逻辑** 修改下拉框的显示文本: ```javascript mounted() { this.$nextTick(() => { const sizeSelect = this.$refs.quillEditor.quill.getModule('toolbar').container.querySelector('.ql-size'); if (sizeSelect) { Array.from(sizeSelect.options).forEach(option => { if (option.value) { option.textContent = fontSizeMap[option.value] || option.value; } }); // 添加中文标题 const titleOption = document.createElement('option'); titleOption.textContent = '字体大小'; titleOption.disabled = true; titleOption.selected = true; sizeSelect.insertBefore(titleOption, sizeSelect.firstChild); } }); } ``` 4. **完整组件示例** ```vue <template> <quill-editor ref="quillEditor" v-model="content" :options="editorOptions" /> </template> <script> import Quill from 'quill'; import { quillEditor } from 'vue-quill-editor'; // 字体大小映射 const fontSizeMap = { '12px': '小号', '14px': '中号', '16px': '大号', '18px': '较大', '20px': '特大', '32px': '超大' }; // 注册自定义字体大小 const Size = Quill.import('attributors/style/size'); Size.whitelist = Object.keys(fontSizeMap); Quill.register(Size, true); export default { components: { quillEditor }, data() { return { content: '', editorOptions: { modules: { toolbar: { container: [ [{ 'size': Object.keys(fontSizeMap) }] // 配置下拉框选项 ] } } } }; }, mounted() { this.$nextTick(this.customizeFontSizeDropdown); }, methods: { customizeFontSizeDropdown() { const toolbar = this.$refs.quillEditor.quill.getModule('toolbar').container; const sizeSelect = toolbar.querySelector('.ql-size'); if (sizeSelect) { // 替换选项文本 Array.from(sizeSelect.options).forEach(option => { if (option.value) { option.textContent = fontSizeMap[option.value]; } }); // 添加中文标题 const titleOption = document.createElement('option'); titleOption.textContent = '字体大小'; titleOption.disabled = true; titleOption.selected = true; sizeSelect.insertBefore(titleOption, sizeSelect.firstChild); } } } }; </script> ``` ### 关键说明 1. **`whitelist` 配置** 通过 `Size.whitelist` 定义允许的字体大小值,确保下拉框只显示预设选项[^2]。 2. **DOM 操作时机** 在 `mounted` + `$nextTick` 中操作 DOM,确保 Quill 工具栏已渲染完成。 3. **标题选项** 添加禁用的首选项作为中文标题,提升用户体验。 4. **像素值保留** 实际保存的值仍是像素值(如 `14px`),仅显示文本替换为中文。 ### 效果预览 修改后下拉框将显示为: ``` 字体大小 小号 中号 大号 较大 特大 超大 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值