当前位置: 首页 > news >正文

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">&#xe75d;</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继承&#xff0c;最先想到的可能是ES6中的class、TS中的interface、面向对象编程语言中中的类和接口概念等等&#xff0c;但是我们今天的关注点在于&#xff1a;如何在Vue中使用extends继承特性。 目录 Vue&#xff1a;创建Vue实例的方式 构造函数方式&#xff1…...

ChatGPT 的一些思考

最近 ChatGPT3.5 在全世界范围内掀起了一次 AI 的潮流&#xff0c;ChatGPT1.0/ChatGPT2.0 当时也是比较火爆&#xff0c;但是那个当时感觉还是比较初级的应用&#xff0c;相当于是一个进阶版的微软小冰&#xff0c;给人的感觉是有一点智能&#xff0c;但不多。其实从早期版本开…...

GEE学习笔记 六十九:【GEE之Python版教程三】Python基础编程一

环境配置完成后&#xff0c;那么可以开始正式讲解编程知识。之前我在文章中也讲过&#xff0c;GEE的python版接口它是依赖python语言的。目前很多小伙伴是刚开始学习GEE编程&#xff0c;之前或者没有编程基础&#xff0c;或者是没有学习过python。为了照顾这批小伙伴&#xff0…...

大数据全系安装

内容版本号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 下载&#xff0c;按教程运行2.安装python 忘记勾选加入环境变量&#xff0c;自行加入&#xff08;重启生效&#xff09;3.环境变量添加后&#xff0c;清理tmp &#xff0c;venv重新运行4.运行报错&#xff0c;无法升级pip&#xff0c;无法下载包&#xff0c;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 开发的业务流程引擎&#xff0c;通过 Flowable 流程引擎&#xff0c;我们可以部署遵循 BPMN2.0 协议的流程定义&#xff08;一般为XML文件&#xff09;文件&#xff0c;并能创建流程实例&#xff0c;查询和访问流程相关的实例与数据…...

AcWing:4861. 构造数列、4862. 浇花(C++)

目录 4861. 构造数列 问题描述&#xff1a; 实现代码&#xff1a; 4862. 浇花 问题描述&#xff1a; 实现代码&#xff1a; 4861. 构造数列 问题描述&#xff1a; 我们规定如果一个正整数满足除最高位外其它所有数位均为 00&#xff0c;则称该正整数为圆数。 例如&…...

进程的概念

进程的概念 程序的概念 这里说的是一个可执行文件&#xff0c;passive的意思可以理解为我们这个执行文件需要我们进行双击才会被被执行。 双击后&#xff0c;程序入口地址读入寄存器&#xff0c;程序加载入主存&#xff0c;成为一个进程 进程是主动去获取想要的资源&#xff0…...

自动化测试5年经验,分享一些心得

自动化测试介绍 自动化测试(Automated Testing)&#xff0c;是指把以人为驱动的测试行为转化为机器执行的过程。实际上自动化测试往往通过一些测试工具或框架&#xff0c;编写自动化测试用例&#xff0c;来模拟手工测试过程。比如说&#xff0c;在项目迭代过程中&#xff0c;持…...

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 多个预训练模型组成&#xff0c;支持 PyTorch、TensorFlow 和 JAX 等框架&#xff0c;能够在代码之间进行互操作。 这个库还易于部署&…...

二叉树OJ(一)二叉树的最大深度 二叉搜索树与双向链表 对称的二叉树

二叉树的最大深度 二叉树中和为某一值的路径(一) 二叉搜索树与双向链表 对称的二叉树 二叉树的最大深度 描述 求给定二叉树的最大深度&#xff0c; 深度是指树的根节点到任一叶子节点路径上节点的数量。 最大深度是所有叶子节点的深度的最大值。 &#xff08;注&#xff1a;…...

使用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 基础知识的技术文章&#xff0c;分5个章节&#xff0c;每个章节细分到3级目录&#xff0c;重点介绍一下NoSQL 数据模型&#xff0c;NoSQL 数据库架构&#xff0c;NoSQL 数据库特性等&#xff0c;不少于2000字。 NoSQL 基础知识 NoSQL&#xff08;Not Only SQ…...

Camera Rolling Shutter和Global Shutter的区别

卷帘快门&#xff08;Rolling Shutter&#xff09;与全局快门&#xff08;Global Shutter&#xff09;的区别 什么是快门 快门是照相机用来控制感光片有效曝光时间的机构。 快门是照相机的一个重要组成部分&#xff0c;它的结构、形式及功能是衡量照相机档次的一个重要因素。 …...

模版之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的编译期反射时&#xff0c;发现了AnyType很有意思。 首…...

【汇编】一、环境搭建(一只 Assember 的成长史)

嗨~你好呀&#xff01; 我是一名初二学生&#xff0c;热爱计算机&#xff0c;码龄两年。最近开始学习汇编&#xff0c;希望通过 Blog 的形式记录下自己的学习过程&#xff0c;也和更多人分享。 这篇文章主要讲述汇编环境的搭建过程。 话不多说~我们开始吧&#xff01; 系统环…...

浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)

✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义&#xff08;Task Definition&…...

生成xcframework

打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式&#xff0c;可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

内存分配函数malloc kmalloc vmalloc

内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...

TDengine 快速体验(Docker 镜像方式)

简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能&#xff0c;本节首先介绍如何通过 Docker 快速体验 TDengine&#xff0c;然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker&#xff0c;请使用 安装包的方式快…...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级

在互联网的快速发展中&#xff0c;高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司&#xff0c;近期做出了一个重大技术决策&#xff1a;弃用长期使用的 Nginx&#xff0c;转而采用其内部开发…...

解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错

出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上&#xff0c;所以报错&#xff0c;到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本&#xff0c;cu、torch、cp 的版本一定要对…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)

Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败&#xff0c;具体原因是客户端发送了密码认证请求&#xff0c;但Redis服务器未设置密码 1.为Redis设置密码&#xff08;匹配客户端配置&#xff09; 步骤&#xff1a; 1&#xff09;.修…...

Bean 作用域有哪些?如何答出技术深度?

导语&#xff1a; Spring 面试绕不开 Bean 的作用域问题&#xff0c;这是面试官考察候选人对 Spring 框架理解深度的常见方式。本文将围绕“Spring 中的 Bean 作用域”展开&#xff0c;结合典型面试题及实战场景&#xff0c;帮你厘清重点&#xff0c;打破模板式回答&#xff0c…...

基于开源AI智能名片链动2 + 1模式S2B2C商城小程序的沉浸式体验营销研究

摘要&#xff1a;在消费市场竞争日益激烈的当下&#xff0c;传统体验营销方式存在诸多局限。本文聚焦开源AI智能名片链动2 1模式S2B2C商城小程序&#xff0c;探讨其在沉浸式体验营销中的应用。通过对比传统品鉴、工厂参观等初级体验方式&#xff0c;分析沉浸式体验的优势与价值…...

云原生安全实战:API网关Envoy的鉴权与限流详解

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关 作为微服务架构的统一入口&#xff0c;负责路由转发、安全控制、流量管理等核心功能。 2. Envoy 由Lyft开源的高性能云原生…...