Vue组件继承实践:扩展分隔条(MySplitter)组件
引子
填坑之路
如何实现已有Vue组件的继承扩展?
怎么才能调用基类组件的方法呢?
计算属性究竟是怎么判断要不要重算的?
如何让计算属性手动强制重算?
如何在重载 render 方法中,往原有的虚拟节点列表中注入新的虚拟节点?
结语
组件源码
引子
刚入坑Vue不到一个月,为了开发一个能跨平台的桌面App,千挑万选之下,最终选了Quasar这套框架,觉得各方面都很适合,内置支持Electron,UI样式也很不错,于是乎就开工做了起来。
Quasar的组件库虽然已经算很成熟很全面了,但实际应用中也难免碰上一些不足之处。比如在用到分隔条(QSplitter)组件的时候,就发现它只支持针对单边区域的最大最小限制。而通常App中需要的却是对两边区域都有最小限制(比如VSCode这样,左边功能区不小于170px,右边编辑区不小于300px),最大限制倒很少用到。虽然在百分比模式(unit='%')下,若想要限制右侧区域的下限为10%,可以通过设置左侧区域的上限为90%来实现,但在像素模式(unit='px')下,就没有代替方案了。更何况通常App里我们希望限制的下限必须是像素为单位的(不然大小不确定),这就很尴尬了。
由于并不是特别赶工,本着解决问题就是最好的学习方法的思路,我开始了对QSplitter组件进行二次开发的研究。
填坑之路
由于还是个Vue新手,虽然已经啃了几周的文档,但实际操作起来还是碰到了各种问题。
碰到的第一个坑,就是
如何实现已有Vue组件的继承扩展?
网上看了好多资料都提到了三种继承方式:
- 使用
<基类>.extend(options)
直接创建继承类
这种方式网上很少深入去讲,只放个很简单的例子来说明,甚至基本上讲的都是以 Vue.extend(<基类>)
的方式来调用,而不是 <基类>.extend(options)
。结果生成的只是基类的一个拷贝,而想要加入扩展内容,只能在new实例的时候传入额外的 options 选项表来实现(还特别强调了要用 propsData 来代替 props)。那我要这个“继承”类来干嘛呢?还不如直接new一个基类的实例,不也一样可以传options么?所以网上大多数讲的都是错的,用 <基类>.extend(options)
才是正确的写法。但需要注意的是,用 extend 函数来定义组件(无论是否继承),返回的是组件的构造函数,而不是组件定义的选项表(像.vue单文件模板那样)。
- 在继承组件的定义中添加
extends: <基类>
这种方式是利用了Vue组件注册时自动实现的继承处理,而且并不要求必须用 Vue.extend(options)
的方式直接定义成组件类,而是可以和.vue单文件模板一样,只定义成选项表的形式(也就是单纯的 options 对象)。我认为这样更为统一规范一些,因此最终我选用的就是这种方法。而且这样带来的额外好处是全局注册的时候可以直接取 name 字段作为组件名,也可以很灵活的进行定制化处理(因为本身就只是个options对象,只需要用 { ...options, ... }
这样的方式就可以实现定制扩展)。
- 把基类组件放在继承类组件的模板中,并把继承类组件的属性和事件监听作为参数传给基类组件:
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. 用户需求 假设A系统有如下员工请假审批流场景: 员工请假小于等于3天,只需主管直接审批:大于3天需要主管先审批,审批通过后再由二级主管进行审批.当员工请假审批流节后后,需要通知A系统进行业务处理 ...
- 【鸿蒙 HarmonyOS】UI 组件 ( 拖动条 Slider 组件 )
文章目录 一.布局中设置拖动条 Slider 组件 二.代码中控制拖动条 Slider 组件 一.布局中设置拖动条 Slider 组件 注意该 Slider 组件与 进度条 Progressbar 组 ...
- vue 对象继承_Vue2.0中组件的继承与扩展是什么
Vue2.0中组件的继承与扩展是什么 发布时间:2020-12-07 14:04:09 来源:亿速云 阅读:100 作者:小新 小编给大家分享一下Vue2.0中组件的继承与扩展是什么,相信大部分人都还 ...
- 基于Vue的事件响应式进度条组件
写在前面 找了很多vue进度条组件,都不包含拖拽和点击事件,input range倒是原生包含input和change事件,但是直接基于input range做进度条的话,样式部分需要做大量调整和兼容 ...
- jsx怎么往js里传参数_实践Vue 3.0做JSX(TSX)风格的组件开发
作者:莫夭 转发链接:https://zhuanlan.zhihu.com/p/102668383 前言 我日常工作都是使用React来做开发,但是我对React一直不是很满意,特别是在推出React ...
- GitChat · 前端 | Vue 组件库实践和设计
来自 GitChat 作者:周志祥 更多IT技术分享,尽在微信公众号:GitChat技术杂谈 前言 现在前端的快速发展,已经让组件这个模式变的格外重要.对于市面上的组件库,虽然能满足大部分的项目,但是 ...
- Vue.js 组件复用和扩展之道
作者简介: 李中凯 八年多工作经验 前端负责人, 擅长JavaScript/Vue. 掘金文章专栏:https://juejin.im/user/57c7cb8a0a2b58006b1b8666/po ...
- [vue] vue如果想扩展某个现有的组件时,怎么做呢?
[vue] vue如果想扩展某个现有的组件时,怎么做呢? 不对原组件进行更改的:使用Vue.extend直接扩展使用Vue.mixin全局混入HOC封装 个人简介 我是歌谣,欢迎和大家一起交流前后端知 ...
- Material Design风格神框架vuetify 学习笔记(八) 基础组件4 头像 扩展面板 消息条 评分...
一. 头像 v-avatar v-avatar 组件通常用于显示循环用户个人资料图片. 此组件将允许您动态尺寸并添加响应图像.图标和文字的边框半径. <v-avatar color=" ...
最新文章
- mysql为什么使用B+树
- LeetCode—33. 搜索旋转排序数组
- 如何启动免安装版Tomcat并将Tomcat添加到服务中
- 怎样高速读懂别人的项目
- 最早将于Q3季度发布,小米12至尊版将搭载骁龙8 Plus
- liunx 加入域控_[整理篇]linux加入windows域之完美方案
- 网站日志分析工具:WebLog Expert Lite
- 有人培训设计模式,吾表示难以理解,因为根本没用
- python 矩阵点乘_Python之Numpy库基础——矩阵运算
- Java实现生产者消费者问题与读者写者问题
- 在 Visual Studio 调试器中指定符号 (.pdb) 和源文件
- 在Android studio环境下使用junit框架进行单元测试
- Android MTK 6763 User 版本默认打开usb调试
- matlab箭头梯度方向场,局部路径规划算法——人工势场法
- CSS属性—居中对齐篇
- VTN线下体验店 汇聚全球高端品牌 打造非凡购物体验
- 服务器使用笔记本网络连接外网
- 计算机重装后如何连接无线网络,电脑重装系统后怎么连接无线网络连接
- linu上传下载命令
- 光纤耦合系统的公差分析
热门文章
- [PPT][关于图片的边框效果——小清新]
- React Native 按需加载 手Q狼人杀探索之路
- 细数各种关键绩效指标KPI
- 冷水机组与多联机的比较
- 动手学PyTorch | (5) Softmax回归实验
- android 直播所需权限,最新抖音强开电脑端直播权限教程,限安卓!(附视频教程)...
- 适合安装语音报警器的地方有哪些
- vue西瓜播放器xgplayer-vue实现视频倍速播放,自定义进度条样式
- iphone新旧手机数据传输已取消_OPPO 将推全新概念手机/可折叠 iPhone 已在测试生产中...
- python做循环嵌套_Python_循环嵌套