stencilJs学习之构建 Drawer 组件

这篇具有很好参考价值的文章主要介绍了stencilJs学习之构建 Drawer 组件。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

在之前的学习中,我们已经掌握了 stencilJs 中的一些核心概念和基础知识,如装饰器 PropStateEventListenMethodComponent 以及生命周期方法。这些知识是构建复杂组件和应用的基础,而抽屉组件是一个很好的示例,能够综合运用这些知识,让我们更深入地理解它们的作用和用法。

为什么选择抽屉组件

为什么选择抽屉组件作为综合练习呢?因为抽屉组件是现代 Web 应用中常见的 UI 元素,具有以下特点:

  1. 交互性强:抽屉组件允许用户在不离开当前页面的情况下进行额外操作,因此它需要响应用户的交互行为,如打开、关闭等。
  2. 多状态管理:抽屉可以有多种状态,比如打开、关闭、正在拖拽等,这就需要使用 State 装饰器来管理和控制组件内部的状态。
  3. 属性传递:抽屉可能需要一些用户自定义的属性,如标题、内容、位置等。这就需要使用 Prop 装饰器来接收外部传递的数据。
  4. 自定义事件:抽屉的打开和关闭需要触发自定义事件,以便其他组件或应用能够响应状态变化。
  5. 方法调用:用户可能需要通过调用方法来控制抽屉的行为,例如通过点击按钮来打开或关闭抽屉,这就需要使用 Method 装饰器来定义公开方法。
  6. 生命周期方法:抽屉在不同的生命周期阶段可能需要执行特定的逻辑,例如组件初始化、渲染、卸载等。这就需要使用生命周期方法来实现这些逻辑。
  7. 可复用性:抽屉是一个通用的 UI 元素,在不同的场景中都可能被使用,因此需要设计良好的组件结构和接口,以实现高度的可复用性。

通过实际构建一个抽屉组件,我们能够在综合应用的背景下,更深入地理解这些概念的作用和相互关系。同时,这也为我们未来在实际项目中构建更复杂的组件和应用奠定了坚实的基础。抽屉组件的案例将帮助我们更好地运用 stencilJs 的知识,从而成为更有信心和能力的前端开发者。

实现抽屉组件

创建一个项目

使用以下的命令创建一个 Stencil 项目

#使用 npm
npm init stencil
#使用 yarn
yarn create stencil
#使用 pnpm
pnpm create stencil

创建成功,终端显示如下
stencilJs学习之构建 Drawer 组件,StencilJS,webComponent,web component,stencilJs,html,tsx

创建一个组件

Stencil 项目内置一个生成组件命令 generate,使用下面的命令生成一个组件

#使用 npm
npm run generate
#使用 yarn
yarn generate
#使用 pnpm
pnpm run generate

执行之后会让用户输入一个组件的名字(以-作为连字符),输入之后按回车键会让用户选择要生成的文件,选择之后按回车就能生成一个组件了。你可以在 src/components 目录下看到 ce-drawer, 如下图

stencilJs学习之构建 Drawer 组件,StencilJS,webComponent,web component,stencilJs,html,tsx

实现组件

首先,创建组件的 HTML 结构:

import { Host, h } from '@stencil/core';

@Component({
  tag: 'ce-drawer',
  styleUrl: 'ce-drawer.css',
  shadow: true,
})
export class CeDrawer {

  renderHeader() {
    if (this.showHeader) {
      return (
        <div class="ivy-drawer-header">
          <slot name="header">{this.header}</slot>
        </div>
      );
    } else {
      return null;
    }
  }

  render() {
    return (
      <Host>
        <div class="ivy-mask"></div>
        <div class="ivy-drawer">
          {this.renderHeader()}
          <div class="ivy-drawer-body">
            <slot></slot>
          </div>
        </div>
      </Host>
    );
  }
}

接下来,声明 prop


import { Component, Event, EventEmitter, Host, Method, Prop, Watch, h } from '@stencil/core';

@Component({
  tag: 'ce-drawer',
  styleUrl: 'ce-drawer.css',
  shadow: true,
})
export class CeDrawer {
    @Prop({
      attribute: 'show',
      mutable: true,
      reflect: true,
    })
    visible: Boolean = false;
    @Prop() width: string = '36%';

    @Prop({
        attribute: 'show-header',
        mutable: true,
        reflect: true,
    })
    showHeader: boolean = false;

    @Prop({
        attribute: 'header',
    })
    header: string = '';

    @Prop({
        attribute: 'mask-closable',
        mutable: true,
        reflect: true,
    })
    maskClosable: boolean = true;

    @Prop({
        attribute: 'placement',
        mutable: true,
        reflect: true,
    })
    placement: string = 'right';

    /**监听传入的 placement 是否符合要求*/
    @Watch('placement')
    validateName(val: string) {
        const flag = ['left', 'right', 'top', 'bottom'].includes(val);
        if (!flag) {
          throw new Error('placement 必须是 left/right/top/bottom 其中之一');
        }
    }

    renderHeader() {
        if (this.showHeader) {
          return (
            <div class="ivy-drawer-header">
              <slot name="header">{this.header}</slot>
            </div>
          );
        } else {
          return null;
        }
    }

    render() {
        return (
          <Host show={this.visible}>
            <div class="ivy-mask" onClick={this.maskClose.bind(this)}></div>
            <div
                class="ivy-drawer"
                style={{ width: ['left', 'right'].includes(this.placement) ? this.width : '100%', height: ['top', 'bottom'].includes(this.placement) ? this.width : '100%' }}
            >
                {this.renderHeader()}

                <div class="ivy-drawer-body">
                    <slot></slot>
                </div>
            </div>
          </Host>
        );
    }
}

接着,声明自定义事件和遮罩层点击事件:

// ...
maskClose() {
    if (this.maskClosable) {
      this.visible = false;
    }
}

@Event() closed: EventEmitter;
closeHandler() {
    this.closed.emit();
}

最后,声明外部可用的辅助方法,例如显示/关闭 Drawer 组件:

// ...

@Method()
async open() {
    this.visible = true;
}
@Method()
async close() {
    this.closeHandler();
    this.visible = false;
}

源码

完整代码文章来源地址https://www.toymoban.com/news/detail-699166.html

到了这里,关于stencilJs学习之构建 Drawer 组件的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Vue项目element-ui弹窗组件el-dialog、el-drawer,阻止点击遮罩层关闭

    效果图: 我们只需要设置这两个 属性 append-to-body :close-on-click-modal=“false” 注意 : 这里的close-on-click-modal属性前需要写入 :

    2024年02月12日
    浏览(60)
  • element-ui 抽屉组件(el-drawer ) 二次封装 增加resize拖曳改变宽度大小,配合表格实现快捷方式打开抽屉展示详情及操作

    可配合自定义表格进行操作数据,点击表格某一行进行抽屉展示,可上下页切换查看及功能操作,1.快捷键esc关闭抽屉,// 快捷键控制上下翻页  shiftKey+上键 上一页    shiftKey加下键 下一页  shiftKey加左键 开启弹框展示第一条数据   shiftKey加右键关闭弹框   上代码

    2024年02月12日
    浏览(48)
  • 十年了,您还不认识 WebComponent 吗?!

    🧑‍💼 个人简介:一个不甘平庸的平凡人🍬 🖥️ Node专栏:Node.js从入门到精通 🖥️ TS知识总结:十万字TS知识点总结 👉 你的一键三连是我更新的最大动力❤️! 📢 欢迎私信博主加入前端交流群🌹 MDN:Web Component 是一套不同的技术,允许你创建可重用的定制元素(它

    2024年02月12日
    浏览(29)
  • OpenHarmony源码学习之编译构建

    云将东游,过扶摇之枝,而适遭鸿蒙。—《庄子·在宥》 OpenHarmony是由开放原子开源基金会(OpenAtom Foundation)孵化及运营的开源项目,目标是面向全场景、全连接、全智能时代、基于开源的方式,搭建一个智能终端设备操作系统的框架和平台,促进万物互联产业的繁荣发展。

    2024年02月04日
    浏览(45)
  • 【docker基础学习之】镜像构建

    下面是在工作过遇到的一些实际例子,谨以此作为笔记参考 部署(迁移)项目时发现,项目的excel导出功能报错,错误如下: 问题原因:我们这个项目依赖的镜像上的jdk缺少某种字体程序导致! 或者含 FontConfiguration 的报错 或者我们服务器上镜像的jdk版本是jdk8,而我们的项

    2024年03月15日
    浏览(34)
  • Docker学习之构建Base Image

    目标是构建一个类似官方Hello world的镜像,需要配置好Docker运行环境。 创建并进入docker目录。 hello.c文件的内容如下: 编译hello.c源文件,生成可执行程序hello Dockerfile内容如下: 编译Dockerfile生成镜像,同时指定镜像的名称为myhelloworld 通过下面的命令运行容器,会输出hello w

    2024年02月13日
    浏览(31)
  • elementui-drawer模板

    1、效果图 2、上代码

    2024年02月15日
    浏览(24)
  • flask web学习之模板(二)

    一、模板结构组织 1.1 局部模板 当多个独立模板中都会使用同一块HTML代码时,我们可以把这部分代码抽离出来,存储到局部模板中。这样,既可以避免重复,也可以方便统一管理。 1.2 宏 宏是Jinja2提供的一个非常有用的特性,它类似Python的函数。使用宏可以把一部分代码封装

    2024年01月15日
    浏览(35)
  • 【第五章 flutter学习之flutter进阶组件-上篇】

    children可以复制多个组成列表 设置纵向列表方向 Flutter动态列表可以通过ListView.builder或ListView.separated来实现。 如下例 Filutter 是一个开源的 JavaScript 库,用于创建和管理可过滤和可排序的数据表。FridView 是 Filutter 库中的一个组件,用于在数据表中显示数据行。FridView 组件具有

    2024年02月14日
    浏览(38)
  • 【第五章 flutter学习之flutter进阶组件-下篇】

    Flutter Scaffold 是一个用于构建基本用户界面的布局组件。它提供了许多属性,使得开发者能够轻松地创建一个完整的屏幕布局。以下是 Flutter Scaffold 的一些主要属性: appBar:定义应用的顶部导航栏。通常,它包含标题、返回按钮和其他导航控件。 body:应用程序的主要内容区

    2024年02月14日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包