Vue:extends继承组件复用性
提到extends继承,最先想到的可能是ES6中的class、TS中的interface、面向对象编程语言中中的类和接口概念等等,但是我们今天的关注点在于:如何在Vue中使用extends继承特性。
目录
Vue:创建Vue实例的方式
构造函数方式:new Vue
Vue.extend方式
Vue.component方式
render渲染函数方式
对象方式
Vue:extends继承特性
Vue:创建Vue实例的方式
再开始探讨Vue继承相关的内容之前,有必要回顾一下创建Vue组件实例的几种方式,个人总结如下,
构造函数方式:new Vue
这种方式是较为常见的,在Vue-cli脚手架构建的前端项目中,经常看到如下所示的代码段,
new Vue({router,store,render: h => h(App)
}).$mount('#app')
这就是在以Vue构造函数的方式创建实例,然后将其挂载到id选择器为app的DOM元素上。
Vue.extend方式
Vue.js开发库提供了Vue.extend()API,用于创建一个组件。

Vue.extend()方法的源码如下,内部主要是创建了一个Vue组件对象,并通过外部配置项,将其props、computed、mixin等选项设置为可用,最终将对象返回,
/*** Class inheritance*/Vue.extend = function (extendOptions) {extendOptions = extendOptions || {};//外部配置项-即:Vue组件的选项配置console.log(extendOptions)var Super = this;//指向Vue自身实例的引用var SuperId = Super.cid;var cachedCtors = extendOptions._Ctor || (extendOptions._Ctor = {});if (cachedCtors[SuperId]) {return cachedCtors[SuperId];}var name = getComponentName(extendOptions) || getComponentName(Super.options);if (name) {validateComponentName(name);}var Sub = function VueComponent(options) {this._init(options);};Sub.prototype = Object.create(Super.prototype);Sub.prototype.constructor = Sub;Sub.cid = cid++;Sub.options = mergeOptions(Super.options, extendOptions);Sub['super'] = Super;// For props and computed properties, we define the proxy getters on// the Vue instances at extension time, on the extended prototype. This// avoids Object.defineProperty calls for each instance created.if (Sub.options.props) {initProps(Sub);}if (Sub.options.computed) {initComputed(Sub);}// allow further extension/mixin/plugin usageSub.extend = Super.extend;Sub.mixin = Super.mixin;Sub.use = Super.use;// create asset registers, so extended classes// can have their private assets too.ASSET_TYPES.forEach(function (type) {Sub[type] = Super[type];});// enable recursive self-lookupif (name) {Sub.options.components[name] = Sub;}// keep a reference to the super options at extension time.// later at instantiation we can check if Super's options have// been updated.Sub.superOptions = Super.options;Sub.extendOptions = extendOptions;Sub.sealedOptions = extend({}, Sub.options);// cache constructorcachedCtors[SuperId] = Sub;return Sub;}
通过查看Vue.extend()方法的源码,我们会发现,它内部是在调用Vue原型对象上面的_init()方法来完成组件初始化,通过如下图所示的一些核心配置,使其成为一个名副其实的Vue组件实例,

那么我们自己如何调用Vue.extend()方法创建组件呢?示例代码如下,
/*** 方式1-Vue.extend-使用基础 Vue 构造器,创建一个组件* PS:此种方式中,data必须为函数* */const IButton = Vue.extend({name: "IButton",template: `<button class="btn" @click="clickBtnHandler($event)">Click</button>`,methods: {clickBtnHandler(e) {console.log(e.target.dataset)}},})Vue.component('i-button', IButton);//Vue.component用途之一:将组件注册到全局环境
Vue.component方式

Vue.component()方法有两个作用,其①:将组件注册全局可用的组件;其②:以给定的id,创建一个全局范围内可用的组件。使用此接口创建一个Vue组件的示例代码如下,
/*** 方式2-Vue.component-间接调用Vue.extend,创建一个组件* PS:此种方式中,data必须为函数* */const IList = Vue.component('i-list', {template: `<div><p>列表</p><ul><li v-for="n in number">{{n}}</li></ul></div>`,data: function () {return {number: 5}}})// Vue.component('i-list', IList);//Vue.component创建的组件无需再注册
render渲染函数方式

也可以通过Vue.js提供的render()渲染函数创建一个Vue组件,如下示例代码,通过render函数的函数,根据props参数level来创建了一个级别为level的h标签,并提供插槽供开发者对其进行拓展。
//方式3:基于渲染函数构造函数式组件-[基于slot插槽方式提供组件内容1]const ITitle = Vue.component("i-title",{render: function (createElement) {return createElement('h' + this.level, // 标签名称this.$slots.default // 子节点数组)},props: {level: {type: Number,required: true}}});
对象方式

通过对象的形式定义组件-这也是我们在Vue前端应用开发中最常使用的方式,然后通过export default导出。示例代码如下,
//方式4-通过对象的形式定义组件-这也是我们在Vue前端应用开发中最常使用的方式,然后通过export default导出const InfoBox = {name: "InfoBox",template: `<div class="box" :style="styleObject">{{content}}</div>`,data() {return {content: '消息内容',styleObject: {boxSizing: "border-box",padding: "25px",width: '300px',height: '200px',backgroundColor: 'rgba(0,0,0,0.3)'}}}}Vue.component('info-box', InfoBox);//Vue.component用途之一:将组件注册到全局环境
Vue:extends继承特性
第一部分只介绍了如何创建一个组件,并没有介绍如何去提高一个组件的复用性。既然谈到复用性,可行的方法有很多,例如:slot插槽、mixix混入、Vue.directive自定义一个可复用的指令、通过Install方法开发一个可复用的插件、通过Vue.filter定义一个可复用的过滤器等。关于如上内容,Vue官网都有详细的介绍。
而接下来要讨论的就是Vue官网里面介绍比较含蓄的一种方法:借助extends实现组件的继承。

那么具体如何操作呢?我们先来定义一个基础列表组件IList,并以事件委托的方式为每一个列表元素注册点击事件,示例代码如下,
<!--* @Description: IList列表组件,基于事件委托机制对列表事件回调做了优化处理* @Author: Xwd* @Date: 2023-02-16 00:21:49* @LastEditors: Xwd* @LastEditTime: 2023-02-19 17:03:25* @Attention: 此列表组件的clickHandler()点击事件默认基于index下标来选择性的返回item的值,在一些场景下存在风险-->
<template><div class="i-list"><p v-if="!!title" class="i-title">{{ title }}</p><!-- <div class="split-horizon"></div> --><div v-if="(list || []).length > 0" class="i-content" @click="clickHandler($event)"><div class="i-item" v-for="(item, index) in list" :key="index"><img class="i-item-icon" :src="item.image || noImage" /><div class="i-item-body"><div class="i-item-title">{{ item.title }}<span class="iconfont" title="地图定位" :data-id="item.id":data-index="index"></span></div><div class="i-item-desc" :title="item.desc">{{ item.desc }}</div></div></div></div></div>
</template>
<script>
import noImage from '@/assets/images/no.png';
export default {name: "IList",props: {title: {type: String,required: false,default: "",},list: {type: Array,required: false,default: () => [],}},mounted() { },methods: {/*** 列表元素点击事件-回调函数* @param {*} event */clickHandler(event) {const index = event.target.dataset.index;if (typeof index !== "undefined" && index !== null) {this.$emit("click", this.list[Number(index)], Number(index));}}}
}
</script>
<style lang="less" scoped></style>
而由于我们存在一些不确定因素,例如:props中的list是否具有唯一id、点击回调函数中的具体逻辑是什么?所以我们可以将次组件作为一个基组件,在后续使用过程中,在子组件TownList.vue中通过extends的选项,来继承IList组件,实现复用。示例代码如下,
<!--* @Description: * @Author: Xwd* @Date: 2023-02-19 16:50:16* @LastEditors: Xwd* @LastEditTime: 2023-02-19 16:56:57
-->
<script>
import IList from '@/components/layout/IList.vue';
export default {name:"TownList",extends:IList,methods:{/*** 列表元素点击事件-回调函数,覆写父组件方法,基于元素id值重定义处理逻辑* @param {*} event 事件对象*/clickHandler(event) {const id = event.target.dataset.id;console.log(`id=${id}`)if (typeof id !== "undefined" && id !== null) {const dataIndex = this.list.findIndex(item => item.id == id);dataIndex !== -1 & this.$emit("click", this.list[dataIndex], dataIndex)}}}
}
</script>
此处我们通过id来区分每一个元素,并覆写了父组件中的clickHandler——点击事件回调方法。最终效果如下,

此种方式的不足之处在于:无法在子组件中添加template节点,否则会直接覆盖掉原有的template模板。
相关文章:
Vue:extends继承组件复用性
提到extends继承,最先想到的可能是ES6中的class、TS中的interface、面向对象编程语言中中的类和接口概念等等,但是我们今天的关注点在于:如何在Vue中使用extends继承特性。 目录 Vue:创建Vue实例的方式 构造函数方式࿱…...
ChatGPT 的一些思考
最近 ChatGPT3.5 在全世界范围内掀起了一次 AI 的潮流,ChatGPT1.0/ChatGPT2.0 当时也是比较火爆,但是那个当时感觉还是比较初级的应用,相当于是一个进阶版的微软小冰,给人的感觉是有一点智能,但不多。其实从早期版本开…...
GEE学习笔记 六十九:【GEE之Python版教程三】Python基础编程一
环境配置完成后,那么可以开始正式讲解编程知识。之前我在文章中也讲过,GEE的python版接口它是依赖python语言的。目前很多小伙伴是刚开始学习GEE编程,之前或者没有编程基础,或者是没有学习过python。为了照顾这批小伙伴࿰…...
大数据全系安装
内容版本号CentOS7.6.1810ZooKeeper3.4.6Hadoop2.9.1HBase1.2.0MySQL5.6.51HIVE2.3.7Sqoop1.4.6flume1.9.0kafka2.8.1scala2.12davinci3.0.1spark2.4.8flink1.13.5 1. 下载CentOS 7镜像 CentOS官网 2. 安装CentOS 7系统——采用虚拟机方式 2.1 新建虚拟机 2.2.1 [依次选择]-&…...
stable-diffusion-webui 安装使用
文章目录1.github 下载,按教程运行2.安装python 忘记勾选加入环境变量,自行加入(重启生效)3.环境变量添加后,清理tmp ,venv重新运行4.运行报错,无法升级pip,无法下载包,5…...
3D点云处理:点云聚类--FEC: Fast Euclidean Clustering for Point Cloud Segmentation
文章目录 聚类结果一、论文内容1.1 Ground Surface Removal1.2 Fast Euclidean Clustering题外:欧几里得聚类Fast Euclidean Clustering二、参考聚类结果 原始代码中采用的是pcl中的搜索方式,替换为另外第三方库,速度得到进一步提升。 一、论文内容 论文中给出的结论:该…...
华为OD机试题 - 射击比赛(JavaScript)| 代码+思路+重要知识点
最近更新的博客 华为OD机试题 - 括号检查(JavaScript) 华为OD机试题 - 最小施肥机能效(JavaScript) 华为OD机试题 - 子序列长度(JavaScript) 华为OD机试题 - 众数和中位数(JavaScript) 华为OD机试题 - 服务依赖(JavaScript) 华为OD机试题 - 字符串加密(JavaScript)…...
流程引擎之Flowable简介
背景Flowable 是一个流行的轻量级的采用 Java 开发的业务流程引擎,通过 Flowable 流程引擎,我们可以部署遵循 BPMN2.0 协议的流程定义(一般为XML文件)文件,并能创建流程实例,查询和访问流程相关的实例与数据…...
AcWing:4861. 构造数列、4862. 浇花(C++)
目录 4861. 构造数列 问题描述: 实现代码: 4862. 浇花 问题描述: 实现代码: 4861. 构造数列 问题描述: 我们规定如果一个正整数满足除最高位外其它所有数位均为 00,则称该正整数为圆数。 例如&…...
进程的概念
进程的概念 程序的概念 这里说的是一个可执行文件,passive的意思可以理解为我们这个执行文件需要我们进行双击才会被被执行。 双击后,程序入口地址读入寄存器,程序加载入主存,成为一个进程 进程是主动去获取想要的资源࿰…...
自动化测试5年经验,分享一些心得
自动化测试介绍 自动化测试(Automated Testing),是指把以人为驱动的测试行为转化为机器执行的过程。实际上自动化测试往往通过一些测试工具或框架,编写自动化测试用例,来模拟手工测试过程。比如说,在项目迭代过程中,持…...
independentsoft.de/MSG .NET Framework Crack
MSG .NET 是用于 .NET Framework / .NET Core 的 Microsoft Outlook .msg 文件 API。API 允许您轻松创建/读取/解析/转换 .msg 文件等。API 不需要在机器上安装 Microsoft Outlook 或任何其他第三方应用程序或库即可工作。 以下示例向您展示了如何打开现有文件并显示消息的某些…...
基于Transformer的NLP处理管线
HuggingFace transformers 是一个整合了跨语言、视觉、音频和多模式模态与最先进的预训练模型并且提供用户友好的 API 的AI开发库。 它由 170 多个预训练模型组成,支持 PyTorch、TensorFlow 和 JAX 等框架,能够在代码之间进行互操作。 这个库还易于部署&…...
二叉树OJ(一)二叉树的最大深度 二叉搜索树与双向链表 对称的二叉树
二叉树的最大深度 二叉树中和为某一值的路径(一) 二叉搜索树与双向链表 对称的二叉树 二叉树的最大深度 描述 求给定二叉树的最大深度, 深度是指树的根节点到任一叶子节点路径上节点的数量。 最大深度是所有叶子节点的深度的最大值。 (注:…...
使用Fairseq进行Bart预训练
文章目录前言环境流程介绍数据部分分词部分预处理部分训练部分遇到的问题问题1可能遇到的问题问题1问题2前言 本文是使用 fairseq 做 Bart 预训练任务的踩坑记录huggingface没有提供 Bart 预训练的代码 facebookresearch/fairseq: Facebook AI Research Sequence-to-Sequence…...
n阶数字回转方阵 ← 模拟法
【问题描述】 请编程输出如下数字回旋方阵。 【算法代码】 #include <bits/stdc.h> using namespace std;const int maxn100; int z[maxn][maxn];void matrix(int n) {int num2;z[0][0]1;int i0,j1;while(i<n && j<n) {while(i<j) z[i][j]num;while(j&…...
【人工智能AI】二、NoSQL 基础知识《NoSQL 企业级基础入门与进阶实战》
写一篇介绍 NoSQL 基础知识的技术文章,分5个章节,每个章节细分到3级目录,重点介绍一下NoSQL 数据模型,NoSQL 数据库架构,NoSQL 数据库特性等,不少于2000字。 NoSQL 基础知识 NoSQL(Not Only SQ…...
Camera Rolling Shutter和Global Shutter的区别
卷帘快门(Rolling Shutter)与全局快门(Global Shutter)的区别 什么是快门 快门是照相机用来控制感光片有效曝光时间的机构。 快门是照相机的一个重要组成部分,它的结构、形式及功能是衡量照相机档次的一个重要因素。 …...
模版之AnyType
title: 模版之AnyType date: 2023-02-19 21:49:53 permalink: /pages/54a0bf/ categories: 通用领域编程语言C tags:C元编程 author: name: zhengzhibing link: https://azmddy.top/pages/54a0bf/ 模版之AnyType 在研究C的编译期反射时,发现了AnyType很有意思。 首…...
【汇编】一、环境搭建(一只 Assember 的成长史)
嗨~你好呀! 我是一名初二学生,热爱计算机,码龄两年。最近开始学习汇编,希望通过 Blog 的形式记录下自己的学习过程,也和更多人分享。 这篇文章主要讲述汇编环境的搭建过程。 话不多说~我们开始吧! 系统环…...
【kafka】Golang实现分布式Masscan任务调度系统
要求: 输出两个程序,一个命令行程序(命令行参数用flag)和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽,然后将消息推送到kafka里面。 服务端程序: 从kafka消费者接收…...
DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径
目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...
k8s从入门到放弃之Ingress七层负载
k8s从入门到放弃之Ingress七层负载 在Kubernetes(简称K8s)中,Ingress是一个API对象,它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress,你可…...
spring:实例工厂方法获取bean
spring处理使用静态工厂方法获取bean实例,也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下: 定义实例工厂类(Java代码),定义实例工厂(xml),定义调用实例工厂ÿ…...
【单片机期末】单片机系统设计
主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...
OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 在 GPU 上对图像执行 均值漂移滤波(Mean Shift Filtering),用于图像分割或平滑处理。 该函数将输入图像中的…...
以光量子为例,详解量子获取方式
光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学(silicon photonics)的光波导(optical waveguide)芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中,光既是波又是粒子。光子本…...
iview框架主题色的应用
1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题,无需引入,直接可…...
【把数组变成一棵树】有序数组秒变平衡BST,原来可以这么优雅!
【把数组变成一棵树】有序数组秒变平衡BST,原来可以这么优雅! 🌱 前言:一棵树的浪漫,从数组开始说起 程序员的世界里,数组是最常见的基本结构之一,几乎每种语言、每种算法都少不了它。可你有没有想过,一组看似“线性排列”的有序数组,竟然可以**“长”成一棵平衡的二…...
对象回调初步研究
_OBJECT_TYPE结构分析 在介绍什么是对象回调前,首先要熟悉下结构 以我们上篇线程回调介绍过的导出的PsProcessType 结构为例,用_OBJECT_TYPE这个结构来解析它,0x80处就是今天要介绍的回调链表,但是先不着急,先把目光…...
