引子

填坑之路

如何实现已有Vue组件的继承扩展?

怎么才能调用基类组件的方法呢?

计算属性究竟是怎么判断要不要重算的?

如何让计算属性手动强制重算?

如何在重载 render 方法中,往原有的虚拟节点列表中注入新的虚拟节点?

结语

组件源码


引子

刚入坑Vue不到一个月,为了开发一个能跨平台的桌面App,千挑万选之下,最终选了Quasar这套框架,觉得各方面都很适合,内置支持Electron,UI样式也很不错,于是乎就开工做了起来。

Quasar的组件库虽然已经算很成熟很全面了,但实际应用中也难免碰上一些不足之处。比如在用到分隔条(QSplitter)组件的时候,就发现它只支持针对单边区域的最大最小限制。而通常App中需要的却是对两边区域都有最小限制(比如VSCode这样,左边功能区不小于170px,右边编辑区不小于300px),最大限制倒很少用到。虽然在百分比模式(unit='%')下,若想要限制右侧区域的下限为10%,可以通过设置左侧区域的上限为90%来实现,但在像素模式(unit='px')下,就没有代替方案了。更何况通常App里我们希望限制的下限必须是像素为单位的(不然大小不确定),这就很尴尬了。

由于并不是特别赶工,本着解决问题就是最好的学习方法的思路,我开始了对QSplitter组件进行二次开发的研究。

填坑之路

由于还是个Vue新手,虽然已经啃了几周的文档,但实际操作起来还是碰到了各种问题。

碰到的第一个坑,就是

如何实现已有Vue组件的继承扩展?

网上看了好多资料都提到了三种继承方式:

  1. 使用 <基类>.extend(options) 直接创建继承类

这种方式网上很少深入去讲,只放个很简单的例子来说明,甚至基本上讲的都是以 Vue.extend(<基类>) 的方式来调用,而不是 <基类>.extend(options) 。结果生成的只是基类的一个拷贝,而想要加入扩展内容,只能在new实例的时候传入额外的 options 选项表来实现(还特别强调了要用 propsData 来代替 props)。那我要这个“继承”类来干嘛呢?还不如直接new一个基类的实例,不也一样可以传options么?所以网上大多数讲的都是错的,用 <基类>.extend(options) 才是正确的写法。但需要注意的是,用 extend 函数来定义组件(无论是否继承),返回的是组件的构造函数,而不是组件定义的选项表(像.vue单文件模板那样)。

  1. 在继承组件的定义中添加 extends: <基类>

这种方式是利用了Vue组件注册时自动实现的继承处理,而且并不要求必须用 Vue.extend(options) 的方式直接定义成组件类,而是可以和.vue单文件模板一样,只定义成选项表的形式(也就是单纯的 options 对象)。我认为这样更为统一规范一些,因此最终我选用的就是这种方法。而且这样带来的额外好处是全局注册的时候可以直接取 name 字段作为组件名,也可以很灵活的进行定制化处理(因为本身就只是个options对象,只需要用 { ...options, ... } 这样的方式就可以实现定制扩展)。

  1. 把基类组件放在继承类组件的模板中,并把继承类组件的属性和事件监听作为参数传给基类组件:v-bind="$attrs" v-on="$listeners"

这种方式虽然写起来很简洁,也方便添加额外的参数和子元素,但漏洞比较多,不能算是一种真正的继承,而更像是把基类组件打了个包(叮咚,有你的快递~),在Vue调试器里会多出一层组件节点。另外对于插槽的处理也不友好,需要手动全部重新封装一遍传进去。因此我不是很推荐使用这种方法,它可能会破坏组件的接口和数据流向,产生不可预知的bug。

决定下来用第二种方式继承之后,我就开始着手编写我的扩展分隔条(MySplitter)组件了:

import { QSplitter } from 'quasar'// 扩展分隔条
export default {name: 'my-splitter',extends: QSplitter,props: {},computed: {},watch: {},methods: {},
}

由于我要增加的功能,是能够指定分隔条两侧区域的最小像素范围,而QSplitter组件本身已经有一个 limits 属性了,我并不想覆盖它的功能,因此我参考了QSplitter的源码,增加了一个 limits2 属性,定义如下:

  props: {// [ 一区最小像素范围, 二区最小像素范围 ],若设置则limits无效limits2: {type: Array,validator: v => {if (v.length !== 2) return falseif (typeof v[0] !== 'number' || typeof v[1] !== 'number') return falsereturn v[0] >= 0 && v[1] >= 0}}}

接下来就是想办法让这个 limits2 属性起效了。看了下QSplitter的源码,发现它实际上使用的是一个计算属性 computedLimits 来做最终的处理:

    computedLimits () {return this.limits !== void 0? this.limits: (this.unit === '%' ? [ 10, 90 ] : [ 50, Infinity ])}

于是我就想要重载这个属性,增加对 limits2 的判断。即当定义了 limits2 时,根据 limits2 来计算,否则保持原样。

结果第二个坑来了,

怎么才能调用基类组件的方法呢?

我找遍了网上的资料,完全找不到一个调用Vue基类组件方法的例子,这不科学!既然没的参考,于是我只好自己研究。其实说白了也不难,无非就是 console.log(QSplitter) 一下,在开发者工具里看看里面都有些啥。一看发现它并不是个对象,而是个构造函数,于是继续点进去看源码,然后就看到Vue的源码里去了

Vue组件继承实践:扩展分隔条(MySplitter)组件相关推荐

  1. 【组件开发实践】云巧流程组件对接实践

    1. 用户需求 假设A系统有如下员工请假审批流场景: 员工请假小于等于3天,只需主管直接审批:大于3天需要主管先审批,审批通过后再由二级主管进行审批.当员工请假审批流节后后,需要通知A系统进行业务处理 ...

  2. 【鸿蒙 HarmonyOS】UI 组件 ( 拖动条 Slider 组件 )

    文章目录 一.布局中设置拖动条 Slider 组件 二.代码中控制拖动条 Slider 组件 一.布局中设置拖动条 Slider 组件 注意该 Slider 组件与 进度条 Progressbar 组 ...

  3. vue 对象继承_Vue2.0中组件的继承与扩展是什么

    Vue2.0中组件的继承与扩展是什么 发布时间:2020-12-07 14:04:09 来源:亿速云 阅读:100 作者:小新 小编给大家分享一下Vue2.0中组件的继承与扩展是什么,相信大部分人都还 ...

  4. 基于Vue的事件响应式进度条组件

    写在前面 找了很多vue进度条组件,都不包含拖拽和点击事件,input range倒是原生包含input和change事件,但是直接基于input range做进度条的话,样式部分需要做大量调整和兼容 ...

  5. jsx怎么往js里传参数_实践Vue 3.0做JSX(TSX)风格的组件开发

    作者:莫夭 转发链接:https://zhuanlan.zhihu.com/p/102668383 前言 我日常工作都是使用React来做开发,但是我对React一直不是很满意,特别是在推出React ...

  6. GitChat · 前端 | Vue 组件库实践和设计

    来自 GitChat 作者:周志祥 更多IT技术分享,尽在微信公众号:GitChat技术杂谈 前言 现在前端的快速发展,已经让组件这个模式变的格外重要.对于市面上的组件库,虽然能满足大部分的项目,但是 ...

  7. Vue.js 组件复用和扩展之道

    作者简介: 李中凯 八年多工作经验 前端负责人, 擅长JavaScript/Vue. 掘金文章专栏:https://juejin.im/user/57c7cb8a0a2b58006b1b8666/po ...

  8. [vue] vue如果想扩展某个现有的组件时,怎么做呢?

    [vue] vue如果想扩展某个现有的组件时,怎么做呢? 不对原组件进行更改的:使用Vue.extend直接扩展使用Vue.mixin全局混入HOC封装 个人简介 我是歌谣,欢迎和大家一起交流前后端知 ...

  9. Material Design风格神框架vuetify 学习笔记(八) 基础组件4 头像 扩展面板 消息条 评分...

    一. 头像 v-avatar v-avatar 组件通常用于显示循环用户个人资料图片. 此组件将允许您动态尺寸并添加响应图像.图标和文字的边框半径. <v-avatar color=" ...

最新文章

  1. mysql为什么使用B+树
  2. LeetCode—33. 搜索旋转排序数组
  3. 如何启动免安装版Tomcat并将Tomcat添加到服务中
  4. 怎样高速读懂别人的项目
  5. 最早将于Q3季度发布,小米12至尊版将搭载骁龙8 Plus
  6. liunx 加入域控_[整理篇]linux加入windows域之完美方案
  7. 网站日志分析工具:WebLog Expert Lite
  8. 有人培训设计模式,吾表示难以理解,因为根本没用
  9. python 矩阵点乘_Python之Numpy库基础——矩阵运算
  10. Java实现生产者消费者问题与读者写者问题
  11. 在 Visual Studio 调试器中指定符号 (.pdb) 和源文件
  12. 在Android studio环境下使用junit框架进行单元测试
  13. Android MTK 6763 User 版本默认打开usb调试
  14. matlab箭头梯度方向场,局部路径规划算法——人工势场法
  15. CSS属性—居中对齐篇
  16. VTN线下体验店 汇聚全球高端品牌 打造非凡购物体验
  17. 服务器使用笔记本网络连接外网
  18. 计算机重装后如何连接无线网络,电脑重装系统后怎么连接无线网络连接
  19. linu上传下载命令
  20. 光纤耦合系统的公差分析

热门文章

  1. [PPT][关于图片的边框效果——小清新]
  2. React Native 按需加载 手Q狼人杀探索之路
  3. 细数各种关键绩效指标KPI
  4. 冷水机组与多联机的比较
  5. 动手学PyTorch | (5) Softmax回归实验
  6. android 直播所需权限,最新抖音强开电脑端直播权限教程,限安卓!(附视频教程)...
  7. 适合安装语音报警器的地方有哪些
  8. vue西瓜播放器xgplayer-vue实现视频倍速播放,自定义进度条样式
  9. iphone新旧手机数据传输已取消_OPPO 将推全新概念手机/可折叠 iPhone 已在测试生产中...
  10. python做循环嵌套_Python_循环嵌套