Web Components之继承

news2024/11/15 19:49:09

我们在使用Web Components自定义组件的时候,我们需要继承HTMLElement这个浏览器内置对象,但是如果我要一些高级封装,给组件内置一些方法的话。我们就需要使用继承的方式,在父类中实现基本功能的封装。

1 父类的封装

以下是我的继承封装:

import Emitter from "./index.js";
import { loadHtmlFile } from "./index.js";
export default class PageElement extends HTMLElement {
    constructor() {
        super();
        this.emits = Emitter.emits;
        this.loadHtml = this.loadHtml;
        this.appendHTML = this.appendHTML;
    }
    loadHtml(path) {
       
    }
    appendHTML(html) {

    }

    bindEvent() {

       
    }
    beforeMounted() {  
    }
    mounted() {
    }
    beforeDestroy() {

    }
    destroyed() {

    }
}

父类中完成了一些基本方法的配置。我这个父类中利用HTMLElement自身的一些特性,实现对组件生命周期的重新封装。以及一些基础方法。以及绑定事件的处理。

1 loadHTML方法

这个方法是我具体是去实现加载html的方法,即我的组件是由三部分组层的html,css,js三部分完成。css上期我们已经讲过了使用link标签完成加载。

html我们使用fetch方法去加载,然后将fetch封装成为一个异步方法,这样我们就可以去加载html.

最后由这个js去完成组件功能的封装。

加载html我的封装方法如下:

export function loadHtmlFile(url) {
    return new Promise((resolve, reject) => {
        fetch(url)
            .then((response) => {
                if (response.ok) {
                    return response.text();
                }
            })
            .then((htmlContent) => {
                resolve(htmlContent);
            })
            .catch((error) => {
                reject(error);
            });
    });
}
constructor() {
        super();
        this.emits = Emitter.emits;
        this.loadHtml = this.loadHtml;
        this.appendHTML = this.appendHTML;
    }
    loadHtml(path) {
        return new Promise((resolve, inject) => {
            loadHtmlFile(path).then((html) => {
                resolve(html);
                this.beforeMounted();
            }).catch((error) => {
                console.warn("html加载失败", error.toString());
            })
        })
    }

这样我们就可以在加载完成html之后,去触发我们自己定义的beforeMounted方法。

2 appendHTML方法

appendChild方法,触发我们真实的加载完成方法。mounted。这里必须要讲一下,组件自身带的connectedCallback这个勾子函数是不符合我的使用场景的,因为虽然标签已经注册到页面上,并且也调用了对应的标签,但是这个时候我的html并没有加载完成。所以我自己的mounted生命周期才是真正的组件内部html代码全部加载完成。

下面我们看一个具体定义组件的例子:

export class pageError extends PageElement {
    constructor() {
        super();
        if (!this.shadowRoot) {
            this.attachShadow({ mode: "open" });
        }
        const style = document.createElement("link");
        style.setAttribute("rel", "stylesheet");
        style.setAttribute("href", "./src/page/error/index.css");
        this.shadowRoot.appendChild(style);

        this.loadHtml("./src/page/error/index.html").then((html) => {
            const template = document.createElement("div");
            template.innerHTML = html;
            this.setAttribute("class", "page-error");
            this.appendHTML(template);
        });
    }
    mounted() {
        console.log("loaded");
    }
    backHome() {
        this.app.router.push("/");
    }
}

这是我做的一个404页面组件。

继承了PageElement,并且使用了父类中的loadHTML方法和appendHTML方法。

这个地方之所以用父类的方法,是因为父类需要在这两个方法里面去做一些特殊处理。上面已经演示了具体做了什么。

2 页面组件的组成:

下面演示一下我的组件三部分组成:

通过以上方法的封装,我们讲一个组件拆分成为三部分。

3 路由:

那么我们怎么根据路由变化,来加载不同的页面了。我这里封装了路由,通过拦截路由我们来完成页面加载。具体的做法我们后面再讲。

这里需要用html4 history对象的history.pushState方法以及,popstate的监听事件。当然我们这里默认指的时history模式,而不是hash模式。而且这个popstate事件,并不是用来做跳转监听的,想要实现对路由的拦截,是需要重新写着一部分逻辑的。后面我们继续分享这一块的知识。

这里还有一个特殊处理,就是事件绑定处理。

4 事件绑定处理

我们实现了类似vue的事件绑定方式:

 <div class="desc">
      <div class="desc-text">非常抱歉,当前页面无法访问,可能原因:</div>
      <div class="desc-content">
        1、您输入了错误的网页地址 <br />
        2、原网页已经删除或下线
      </div>
      <div class="desc-btn" @click="backHome">返回网站首页</div>
    </div>

注意看这里@click="backHome"

 <div class="menu" @click="() => this.skip(2)">
            <div class="icon">
                <custom-icon src="./src/assets/svg/api.svg" />
            </div>
            <div class="text">新html5 API</div>
        </div>

注意看这里@click="() => this.skip(2)"

这种时间绑定的处理方法,我们都是在页面加载环节,在appHTML方法里面完成的属性解析以及对当前属性的节点进行事件监听方法的绑定处理。

同样,我们再看404页面中我们绑定方法backHome方法,我们实践代码如下:

 backHome() {
        this.app.router.push("/");
    }

 this.app.router.push("/"),这里我们就完成了跳转页面,而这里则就是我们给页面组件中注入了路由对象,然后通过路由的方法完成跳转。

这里的路由对象的封装,我们后续继续分享。

当然,我的个人基于webComponents框架,已经即将封装完成。后续和大家见面和分享这里面的技术知识点。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2155998.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一文搞懂UEFI

Hi&#xff01;早哦。今天又是宠读者的一天&#xff0c;应允聊聊UEFI。 文章目录 前言UEFI是什么&#xff1f;传统BIOSBIOS作为标准BIOS作为实现BIOS的工作原理传统BIOS的局限性传统BIOS启动过程 BIOS VS UEFIUEFI&#xff1f;UEFI概念EFI 系统分区EFI 变量EFI 的启动过程EFI 变…

【高分系列卫星简介——高分三号卫星(GF-3)】

高分三号卫星&#xff08;GF-3&#xff09; 高分三号&#xff08;GF-3&#xff09;是我国首颗高分辨率、C频段、多极化合成孔径雷达&#xff08;SAR&#xff09;卫星&#xff0c;由中国空间技术研究院北京空间飞行器总部设计部研制&#xff0c;并于2016年8月10日成功发射。该卫…

thop计算模型复杂度(params,flops)

thop安装 -pip install thop在线安装失败 -离线安装 github网址&#xff1a; pytorch-OpCounter:Count the MACs / FLOPs of your PyTorch model. - GitCode python setup.py install 测试&#xff1a; from options import config as c import os os.environ["CUD…

【Flink实战】flink消费http数据并将数组展开多行

文章目录 一. 需求描述二. 方案思路1. 解决思路2. flink json 解析2.1. 通过json path解析非array数据2.2. 通过json path解析array数据 3. CROSS JOIN逻辑 三. 方案实现1. http json数据样例2. flink sql 说明 一. 需求描述 flink消费http接口的数据&#xff0c;将json中的数…

【JavaEE初阶】多线程7(面试要点)

欢迎关注个人主页&#xff1a;逸狼 创造不易&#xff0c;可以点点赞吗~ 如有错误&#xff0c;欢迎指出~ 目录 常见的锁策略 乐观锁vs悲观锁 重量级锁vs轻量级锁 挂起等待锁vs自旋锁 公平锁vs非公平锁 可重入锁vs不可重入锁 读写锁 synchronized的加锁过程 锁升级的过程 偏向锁 …

博途TIA v18下载时,需要重启才能安装下载路径是灰色改不了

一、需要重启才能安装 删除下面注册表P开头的文件&#xff1a; 二、下载路径是灰色改不了 注册表HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion里找到C:\Program Files或者C:\Program Files&#xff08;x86&#xff09;&#xff0c;具体哪个看安装的时候对应…

【面向对象】设计原则

单一职责&#xff1a;低耦合&#xff0c;高内聚。一个类不要负责太多的功能&#xff0c;否则会导致类内部耦合度高&#xff0c;不利于扩展&#xff1b;开闭原则&#xff1a;对扩展开放&#xff0c;对修改关闭。扩展新功能时&#xff0c;不建议修改原有的代码&#xff0c;建议通…

【CSS】样式

文本color 颜色font-size 大小font-family 字体font-style 样式font-weight 加粗text-decoration 下划线text-shadow 阴影text-transform 大小写变换text-indent 缩进text-align 水平对齐 、vertical-align垂直对齐text-overflow 溢出word-wrap 换行 、word-break 截断 、white…

GAMES101(15节)

Irradiance辐射度量学 辐射度量学在渲染领域&#xff0c;可以帮助理解基于物理的光照模型 radiant energy辐射能量Q&#xff0c;累计总能量&#xff08;单位J joule焦耳&#xff09;&#xff0c;就像太阳能板&#xff0c;光照时间越长接收能量越多&#xff0c;收到的能量总和…

Vue点击按钮生成pdf文件/Vue点击按钮生成png图片

本次案例是vue的点击生成pdf文件和png格式的图片 一、生成pdf文件案例 看代码之前&#xff0c;我们肯定得需要看看&#xff0c;效果图是什么的啦&#xff0c;这样子才能先看看自己想要实现的效果是不是这样子的&#xff01;上效果图嘿嘿嘿~ A、实现的效果图 这是页面&#…

【M-LOAM学习】

M-LOAM(INITIALIZATION) Article Analysis Scan-Based Motion Estimation 通过在consecutive frame (each LiDAR)&#xff08;因为omp parallel&#xff09;中寻找correspondences然后通过最小化所有考虑feature之间residual error的transformation between frame to frame 针…

java(3)数组的定义与使用

目录 1.前言 2.正文 2.1数组的概念 2.2数组的创建与初始化 2.2.1数组的创建 2.2.1数组的静态初始化 2.2.2数组的动态初始化 2.3数组是引用类型 2.3.1引用类型与基本类型区别 2.3.2认识NULL 2.4二维数组 2.5数组的基本运用 2.5.1数组的遍历 2.5.2数组转字符串 2.…

ETCD学习使用

一、介绍 etcd&#xff08;分布式键值存储&#xff09;是一个开源的分布式系统工具&#xff0c;用于可靠地存储和提供键值对数据。etcd 通常通过 HTTP 或 gRPC 提供 API&#xff0c;允许应用程序通过简单的接口与其交互。由于其可靠性和稳定性&#xff0c;etcd 在构建可扩展、分…

基于springboot的在线视频点播系统

文未可获取一份本项目的java源码和数据库参考。 国外研究现状&#xff1a; 与传统媒体不同的是&#xff0c;新媒体在理念和应用上都采用了新颖的媒介或媒体。新媒体是指应用在数字技术、在传统媒体基础上改造、或者更新换代而来的媒介或媒体。新兴媒体与传统媒体在理念和应用…

UML——统一建模语言

序言&#xff1a; 是统一建模语言的简称&#xff0c;它是一种由一整套图表组成的标准化建模语言。UML用于帮助系统开发人员阐明&#xff0c;展示&#xff0c;构建和记录软件系统的产出。UML代表了一系列在大型而复杂系统建模中被证明是成功的做法&#xff0c;是开发面向对象软件…

ModbusTCP通讯错误的排查

Modbus是一种由MODICON公司开发的工业现场总线协议标准&#xff0c;是一项应用层报文传输协议。该协议用于传输数字和模拟变量[1]。有关该协议的报文具体格式&#xff0c;以及一些基本概念&#xff0c;见[1]。 本文以一个例子&#xff0c;阐述当ModbusTCP通讯出现错误的时候&a…

文件上传、重定向、Gin路由

文件上传 单个文件上传 index.html 文件上传前端页面代码&#xff1a; <!DOCTYPE html> <html lang"zh-CN"> <head><title>index</title> </head> <body> <form action"/upload" method"post"…

MySQL学习(索引)

文章目录 基本概念单列索引普通索引&#xff08;index&#xff09;唯一索引&#xff08;unique&#xff09;主键索引 组合索引全文索引&#xff08;fulltext&#xff09;空间索引&#xff08;spatial&#xff09;MySQL存储引擎 基本概念 通过某种算法&#xff0c;构建数据模型&…

云手机的海外原生IP有什么用?

在全球数字化进程不断加快的背景下&#xff0c;企业对网络的依赖程度日益加深。云手机作为一项创新的工具&#xff0c;正逐步成为企业优化网络结构和全球业务拓展的必备。尤其是云手机所具备的海外原生IP功能&#xff0c;为企业进入国际市场提供了独特的竞争优势。 什么是海外原…

高等数学——微分学

1. 一元函数微分学 1.1. 导数概念 1.2. 导数运算 1.3. 导数与几何 2. 多元函数微分学 2.1. 多元函数的极限 2.1.1. 计算 直接代入法 无穷小乘有界 有理化型 等价无穷小型 ……总结 2.1.2. 是否存在 考试中,判断极限是否存在的问题,答案一般都是不存在。因为,证明一个…