前端组件库造轮子——Message组件开发教程

前端组件库造轮子——Message组件开发教程

前言

本系列旨在记录前端组件库开发经验,我们的组件库项目目前已在Github开源,下面是项目的部分组件。文章会详细介绍一些造组件库轮子的技巧并且最后会给出完整的演示demo。

image.png

文章旨在总结经验,开源分享,有问题的话也希望路过的大佬指正。

组件开发流程

样式和动画

首先我们来考虑样式,对于message的调用我们下面再讲。

样式的话,无非就是实现一个这样消息弹出框,同时加上弹出时的动画,这里借助vuetransition来实现。

image.png

这些都是简单的内容,代码量很少我就直接贴在这里了。

<transition name="message-fade">
<div class="message">
  <p class="message-content"></p>
</div>
</transition>

.message {
  position: fixed;
  top: 20px;
  left: 50%;
  z-index: 50;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  padding: 15px 15px 15px 20px;
  overflow: hidden;
  background-color: #f0f9eb;
  border: 1px solid #ebeef5;
  border-radius: 5px;
  transition: opacity 0.3s, transform 0.4s, top 0.4s;
  transform: translateX(-50%);
}
.message-fade-enter-active,
.message-fade-leave-active {
  opacity: 0;
  transform: translate(-50%, -100%);
}

.message-content {
  color: #67c23a;
  font-size: 14px;
  margin: 0;
}

当然现在这个message是只有空壳一样的内容,我们需要实现的效果是,有一个message函数接口,我们可以调用这个接口后弹出这个消息框。这其实就是和其它一些组件不太一样的地方,他的实现更倾向于一个接口函数一样。

写一个函数当然不是问题,问题是怎么实现调用函数后渲染我们的消息框出来。

这里就需要了解一下vue中渲染DOM的知识点了。

h函数和render函数

vue中,很多文件的开发都是在.vue文件的,这种文件开发是分为三大块来写,可以像类似写HTML时的感觉,这也是vue的卖点之一,让新手更易于上手。

但是我们要知道,.vue实际上也是需要通过一些打包工具来编译成js代码才能执行。

h函数就是把.vue中的代码编辑成一个虚拟DOM,最终会把template解析为render函数返回虚拟DOM,这点可以在Vue Dev Tools中看到:
image.png

也就是说,h函数是负责创建虚拟DOMrender是负责把这个虚拟DOM返回出去

接口函数

通过上面的介绍,大概不难猜出这个接口函数应该如何实现了,其实就是创建一个虚拟DOM出来包裹住我们的message组件,在利用render函数渲染出来即可。

import element from "./message.vue";
import { createVNode, render } from "vue";

export default function message(options) {
  if (typeof options === "string") {
    options = {
      message: options as string,
    };
  }
  const params = {
    ...options,
  };
  
  // vue2 的写法
  // new Vue(render:() => createVNode(element)).mount();
  
  const div = document.createElement("div"); // 创建一个div
  const vnode = createVNode(element, params);  // 创建一个message组件的虚拟DOM
  render(vnode, div); // 渲染虚拟DOM
  document.body.appendChild(div.firstElementChild); // 加入到body中
}

那我们既然可以调用message接口函数了,那么在message组件中还有一些逻辑需要实现——在执行结束后关闭掉弹出来的消息框。

这里就是利用v-show控制开关消息框,用定时器回调来解决关闭,我们可以利用props接收存在时间duration,这样我们的基本功能就算完成了,但是message组件还存在很多细节可以补充。

// message.vue
<transition name="message-fade">
    <div class="message" v-show="visible">
        <p class="message-content">{{ message }}</p>
    </div>
</transition>
  
const visible = ref(false);
let timer = null;
const start = () => {
  visible.value = true;
  if (timer !== null) {
    clearTimeout(timer);
  }
  if (props.duration > 0) {
    timer = setTimeout(() => {
      visible.value = false;
    }, props.duration);
  }
};

onMounted(() => {
  start();
});

onUnmounted(() => {
  if (timer !== null) {
    clearTimeout(timer);
  }
});

回调删除节点的性能优化

在刚刚上面完成的组件中,会发现当我们多次触发了message后,哪怕duration过了,节点也依然存在在body中,这些节点只是被隐藏了,并没有随着持续时间结束后删除掉。

image.png

这样显然是不太合理的,并且操作多了会存在一些性能问题,因此我们需要在这个组件在持续时间结束后可以被删除掉。

这里我们可以在动画结束后,派发出一个destroy事件

 <transition name="message-fade" @after-leave="$emit('destroy')"> // 派发删除操作
    <div class="message" v-show="visible">
      <p class="message-content">{{ message }}</p>
    </div>
 </transition>

这个$emit('destroy')会调用我们传进来的props中的onDestroy函数

// message.ts

const div = document.createElement("div");
const vnode = createVNode(element, params);
+ vnode.props.onDestroy = () => { // 在参数props中挂载销毁函数
+    render(null, div); // 利用render移除div节点
+ };
render(vnode, div);
document.body.appendChild(div.firstElementChild);

连续多次弹出的用户体验优化

当我们连续触发多次message时,会弹出多个消息,对于这多个消息,我们不希望会重叠在一起发生覆盖的情况,我们希望的是可以像下面这样。

image.png

那我们如何实现上面的效果呢?

我们可以在props中加一个offset属性,该属性为message组件的离视屏顶部的距离。

然后我们还需要知道上个节点的距离是多少,因此我们需要把连续点出的节点都记录起来,具体来说就是用一个数组把他们存起来,数组中的值按上一节点的offset基础上加合适的距离即可。

// message.ts

+ const instances: VNode[] = [];
export default function message(options) {
  ...

+  let offset = options.offset || 20;

+  instances.forEach((vnode: VNode) => {
+    offset += vnode.el.offsetHeight + 20;
+  });

  const params = {
    ...options,
+    offset,
  };
  const div = document.createElement("div");
  const vnode = createVNode(element, params);
  vnode.props.onDestroy = () => {
    render(null, div); // render会移除dom,注意:此方法在vue2中无法使用
+   instances.pop();
  };
  render(vnode, div);
  document.body.appendChild(div.firstElementChild);
+  instances.push(vnode);
}

同时,我们需要在渲染出message组件中,加上新的offset位置。

// message.vue

<transition name="message-fade" @after-leave="$emit('destroy')">
    <div class="message" v-show="visible" :style="topStyle"> // 更改top位置
      <p class="message-content">{{ message }}</p>
    </div>
</transition>
  
const topStyle = computed(() => {
  return {
    top: `${props.offset}px`,
  };
});

演示demo

完整项目demo

结语

Message组件的核心开发功能就是上面这些,其他更多的详细功能开发可以参考Hview-ui项目源码

如果想要了解更多的组件轮子开发,或者组件库开发流程,更多详细的组件开发过程更新在GitHub项目源码,最后觉得我们项目or文章不错可以点个star,点点小手支持一下,也欢迎各路大佬为我们的开源项目添砖加瓦。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 大屏可视化UI设计是一项技术与艺术相结合的工作,需要设计师具备一定的美学素养和技术能力。为了更加高效和便捷地进行UI设计,设计师可以使用Photoshop组件库。 Photoshop组件库是一个预设的工具包,可以包含一系列UI组件,如按钮、滑块、文本框、图表等。使用组件库可以快速绘制UI界面,减少设计师的工作量和时间。对于大屏可视化UI设计,组件库更为重要,因为它可以提供更多的元素和组件,从而让设计师可以更加精准地调整UI界面。 不仅如此,Photoshop组件库还支持自定义元素。这就意味着,设计师可以根据实际需求,向现有的组件库中添加新的元素和组件。这样,就可以更好地满足大屏可视化的UI设计要求,增强UI界面的可视性和实用性。 总之,Photoshop组件库是大屏可视化UI设计中的一项重要工具,它能够提高设计效率和品质,减少不必要的重复工作。因此,设计师应该熟悉组件库的使用,不断掌握和学习新的技术和工具,从而不断提升自己的设计水平。 ### 回答2: 大屏可视化UI设计Photoshop组件库是一种设计工具,可以帮助设计师更加高效地完成UI界面的设计。该组件库包含各种各样的UI元素,如图标、按钮、输入框、滑块等,设计师可以根据需要选择相应的元素进行拼合,从而快速地创建出符合需求的界面。 这个组件库的优势在于它能够提高设计效率。组件库中的各种元素都是经过专业设计师打的,都符合行业标准,从而可以避免设计师重复轮子,提高生产效率。此外,该组件库还能够让设计师更加关注于界面的整体布局和美感,更加专注于核心设计工作。 当然,该组件库也有一些需要注意的地方。设计师使用该组件库时,应当注意保持界面的一致性和风格统一性,避免出现界面错乱或者不协调的情况。此外,由于该组件库只是提供一些常见的UI元素,对于一些特殊需求,设计师还需要进行自己的创新和设计。 综上所述,大屏可视化UI设计Photoshop组件库是设计师日常工作中常用的工具,它能够提高设计效率,减少反复设计的过程,但也需要设计师注意细节,保障界面的一致性和美观度。 ### 回答3: 大屏可视化UI设计Photoshop组件库是指针对大屏幕的可视化UI设计所开发的一套组件库,它能够帮助设计师更加高效地设计大屏幕的可视化UI。设计师可以通过该组件库轻松地创建各种大屏幕的可视化UI元素,如图表、表格、悬浮面板等,并且这些元素都已经被优化和预先设计,使得设计师可以轻松构建他们的大屏幕可视化UI。 这个组件库基于Photoshop软件开发,具有很强的可拓展性,能够适应多种不同的UI设计需求。通过该组件库,设计师可以节省大量的时间和精力,而且能够得到更加一致和美观的设计效果。此外,该组件库还提供了丰富的文档和使用说明,让设计师可以轻松上手,快速应用组件库进行设计工作。 总之,大屏可视化UI设计Photoshop组件库是一款非常实用的工具,它能够帮助设计师更加高效地完成大屏幕可视化UI设计工作,为用户提供更加直观和易于理解的数据展示方式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老帅比阿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值