Skip to content

组件 (基础组件)

编写组件时的相关思考,遇到问题的解决方法等

Button - 按钮

需求分析

Button 组件大部分关注样式,没有其他交互。可在其上自行绑定事件

根据分析,暂得以下具体属性列表:(button.type.ts)

  • type 样式
  • plain
  • round
  • circle
  • disabled
  • icon
  • loading

确定项目文件结构

  • 从简单入手
  • 没有必要过度设计
  • Button(components) 后续组件都参照这个文件结构来
    • Button.vue
    • style.css
    • types.ts
    • Button.test.ts

其他问题及思考

不能导入外部文件类型

https://cn.vuejs.org/guide/typescript/composition-api.html#typing-component-props

组件属性需要单独写一个 script

html
<script setup>
  defineOptions({
    name: 'MyButton',
  })
</script>

Collapse - 折叠面板

简易的折叠面板

需求分析

  • 静态展示
  • 提供简单交互
  • 多种解决方案
  • 涉及一些新的知识点
    • Provide / Inject
    • v-model 实现
    • slots
    • Transition

了解功能

  • 展示多个 item,有标题和内容两部分
  • 点击标题可以关闭和展示内容
  • 可选手风琴模式

注意

当使用 defineOptions,设置inheritAttrs: false时,要配对使用 v-bind="$attrs" 这样不会丢一些透传属性

Message - 消息

可直接用于展示,或用 API 操作新建实例展示

将组件 Render 到 DOM 节点上

使用 createApp 的弊端

  • 该方法过于"重",它返回了一个应用的实例,而我们需另辟更轻量级的解决路径

综上,采用 render 函数

js
// 一个vue内部的神奇函数,文档中没有特别说明
// 它负责将一个vnode渲染到DOM节点上
// 是一个轻量级的解决方案
import { render } from 'vue'

render(Vnode, DOM节点)

组件开发

使用函数式的方式创建组件

js
const container = document.createElement('div')
const vnode = h(MessageConstructor, props)

render(vnode, container)
document.body.appendChild(container.firstElementChild!)

销毁组件实例

js
render(null, container)

组件动态构造并且传入属性

js
const newProps = {
  ...props,
  onDestory: destory,
}
const vnode = h(MessageConstructor, newProps)

其他方式

  • 使用一个数组保存组件实例信息,并且添加对应的函数对数组进行处理
  • 计算偏移量
    • top: lastBottomOffset(上一个实例留下的底部位置的偏移) + offset
    • 为下一个实例预留 bottomOffset: top + height
    • messageRef.value!.getBoundingClientRect().height
    • 使用 defineExpose 暴露对应的属性或方法
  • 在函数中获取偏移量

Tooltip - 提示

功能分析

  • 基本功能,两块区域
    • 触发区域
    • 展示区域
  • 触发方式
    • 点击
    • hover
    • 手动

重点就是触发区,发生特定事件时,展示区的内容将隐藏

开发

  • 基础功能实现 (使用 popper.js 来完成位置的展示
  • 支持 click / hover 两种触发方式
  • 支持 clickoutside 时的隐藏
  • 支持手动触发
  • 支持 popper 参数
  • 过渡效果
  • 支持延迟显示
  • 其他样式处理