🎄Hi~ 大家好,我是小鑫同学,一位长期从事前端开发的编程爱好者,我将使用更为实用的案例输出更多的编程知识,同时我信奉分享是成长的唯一捷径,在这里也希望我的每一篇文章都能成为你技术落地的参考~
最近两年一直在迭代一套由 MicroApp 搭建的微前端的项目,整个项目由一套 Angualr8.x 的主项目 和 两套 Vue3.0 的子项目组成,虽然三套项目均采用了 Ant Design 组件库,但目前主流的组件库大多都严重依赖技术框架及技术框架的不同版本,在微前端项目中极容易造成页面或组件的开发和维护工作量翻倍,而且还极容易造成全局样式的污染。
在最近的一次技术大会上接触到了由 **哈啰技术团队 **带来的 Quarkc 和 Quarkd。Quarkc 是由哈啰平台前端团队开发的一套面向未来的 无框架 组件构建工具!底层基于浏览器原生 API: Web components。纯利用 Web components API 开发组件存在以下几个痛点:
大量的 DOM 操作;
处理版本和浏览器兼容;
没有代码高亮提示;
样式自适应;
。。。
正如哈啰技术团队的徐顺发老师讲的 陌生的 API + 原生的写法 增加了学习成本、导致未知问题的出现、还会存在性能问题。所以选择合适的框架来开发 Web components 组件尤为重要,从框架的学习成本、维护积极性、开发体验等因素考虑 Quarkc 可能更加符合这些条件。
我在 1024code 平台准备好了由 quarkc 创建的 quark-component-template 模板项目,你可以 Fork 此项目在线体验 Quarkc 开发组件。
下图是 Github Discussions 的常驻公告栏卡片,接下来就使用quarkc 来开发跨平台的公告栏卡片组件。
认识 Quark-Component:
目录结构:
quark-component-template├── sec│ ├── index.less // 组件样式│ ├── index.tsx // 组件源码│ └── vite-env.d.ts├── index.html├── index.vue.html ├── package.json├── README.md├── tsconfig.json├── vite.config.build.ts└── vite.config.ts
复制代码
在目录中主要关注 src/index.tsx文件,在该文件中定义的组件类需要继承自 QuarkElement对象并重写 render 函数来实现组件的结构, 使用 @customElement定义组件的 tag及引用的 style。
import { QuarkElement, property, customElement } from 'quarkc';import style from './index.less?inline';
declare global { interface HTMLElementTagNameMap { 'discussion-spotlight-container': DiscussionSpotlightContainer;}}
@customElement({ tag: 'discussion-spotlight-container', style })class DiscussionSpotlightContainer extends QuarkElement {
render() { return ( <> DiscussionSpotlightContainer </> ); }}
export default DiscussionSpotlightContainer;
复制代码
开发常驻公告栏卡片:
通过分析卡片的构成,它主要包含了动态的头像、标题和通知三部分,那么给出了下面这段 tsx 结构代码。
<> <div className="discussion-wapper"> <div className="discussion-container"> <img className="avatar" src={this.avatarUrl} /> <h3 className="title">{this.title}</h3> <div className="notice"> <span>{this.notice}</span> <span>·</span> <span>xsf0105</span> </div> </div> </div></>
复制代码
期间三个动态的内容需要组件在被使用时,有使用者决定传入的内容,也就是要接收一些属性,这里会用到 @property装饰器,完善后的代码如下。
@customElement({ tag: 'discussion-spotlight-container', style })class DiscussionSpotlightContainer extends QuarkElement { @property({ type: String }) avatarUrl = '';
@property({ type: String }) title = '';
@property({ type: String }) notice = '';
render() { return ( <> <div className="discussion-wapper"> <div className="discussion-container"> <img className="avatar" src={this.avatarUrl} /> <h3 className="title">{this.title}</h3> <div className="notice"> <span>{this.notice}</span> <span>·</span> <span>xsf0105</span> </div> </div> </div> </> ); }}
复制代码
还有样式的部分代码:
.discussion-wapper { height: 150px; overflow: hidden; cursor: pointer; background-image: linear-gradient(to right, #58a6ff, #56d364); border-radius: 6px; border: 1px solid #d0d7de;}
.discussion-container { margin-top: 32px; padding: 0 16px; height: 100%; background-color: #fff;}
.avatar { height: 32px; aspect-ratio: auto 32 / 32; width: 32px; border: 1px solid #d0d7de; border-radius: 50%; margin-top: calc(-24px); border-color: #fff; border-width: 3px;}
.title { margin-bottom: 8px; font-size: 20px; font-weight: 600;}
.notice span { max-width: fit-content; min-width: 1ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;}
.notice span:first-child { font-weight: 600; color: #57606A;}
.notice span:nth-child(2) { margin-left: 0.25rem;}
.notice span:nth-child(3) { margin-left: 0.25rem; color: #57606A;}
复制代码
至此这个公告栏卡片组件就已经开发完成了,它将可以使用在普通的 HTML 网页,也可以使用在 Vue、React、Angular 技术框架的任何项目中,使用的方式同样要比目前常用的组件库使用方式要简单,我们接着往下看。
预览常驻公告栏卡片:
在执行 npm run dev会启动组件的测试页面,对应的文件是 index.html,是一个不包含任何框架的纯 HTML 文件,仅通过导入组件文件(./src/index.tsx)就可以使用。
<!DOCTYPE html><html lang="en"> <head> <meta charset="UTF-8" /> <title>Hello Quark</title> <script type="module" src="./src/index.tsx"></script> </head> <body> <discussion-spotlight-container avatarUrl="https://avatars.githubusercontent.com/u/14307551?s=32&v=4" title="Next quark design 邀您共建 🚀" notice="📣 Announcements" ></discussion-spotlight-container> </body></html>
复制代码
另外在根目录下的 index.vue.html 文件还提供了一份在 Vuejs 中使用组件的方式,同样是仅仅导入组件文件(import './src/index.tsx';)就可以使用。
<!DOCTYPE html><html lang="en"> <head> <meta charset="UTF-8" /> <title>Test in Vue.js</title> </head> <body> <div id="app"> <discussion-spotlight-container :avatarUrl="avatarUrl" :title="title" :notice="notice" ></discussion-spotlight-container> </div> </body> <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script> <script type="module"> import './src/index.tsx'; const { createApp } = Vue; createApp({ data() { return { avatarUrl: 'https://avatars.githubusercontent.com/u/14307551?s=32&v=4', title: 'Next quark design 邀您共建 🚀', notice: '📣 Announcements', }; }, }).mount('#app'); </script></html>
复制代码
这是预览的效果:
PS:https://1024code.com/codecubes/dx5axr8 《DiscussionSpotlightCard》,请点击链接或复制链接到浏览器打开,在线查看和运行
打包 & 再次测试组件:
执行 npm run build 命令来打包组件产物将在lib目录中获得下面的内容,组件产物暂时不考虑发布 NPM,所以在 1024code 中在项目右上角的选择导出文件。
lib├── types| └── index.d.ts├── index.js└── index.umd.js
复制代码
为了再次测试组件,我们依旧可以选择在 1024code 平台,新建 Vuejs 模板项目并随意选择版本并创建代码空间:
接着创建 webcomponents 目录并上传打包的组件产物,此 Vuejs 项目在构建时应排除此目录。
执行 npm i quarkc安装唯一的依赖模块后就可以开始使用组件了:
<template> <img alt="Vue logo" src="./assets/logo.png" /> <discussion-spotlight-container :avatarUrl="data.avatarUrl" :title="data.title" :notice="data.notice" ></discussion-spotlight-container></template>
复制代码
<script setup> // 导入组件文件 import './webcomponents/discussion-spotlight-container/index';
// 定义组件属性数据 const data = { avatarUrl: 'https://avatars.githubusercontent.com/u/14307551?s=32&v=4', title: 'Next quark design 邀您共建 🚀', notice: '📣 Announcements', };</script>
复制代码
总结:
QuarkC 使用面向 Class 并配合装饰器的来提供组件开发的方式,对于习惯 Angualr 和 React 开发风格的前端更加的友好,在案例中仅仅使用了定义组件的装饰器 @customElement 和 对外提供属性的 @property,在 QuarkC 中还提供了内部状态@state、自定义事件 $emit、插槽 slot以及生命周期等。Quarkd 就是哈啰技术团队基于 Web Components 的跨框架 UI 组件库。
分久必合,可能 Web Components 的跨框架 UI 组件库就是下一代的前端组件,在后面的微前端项目迭代中将有必要考虑使用 QuarkC 构建跨平台的业务组件。你觉得 QuarkC 怎么样?
评论