封装组件库-通知菜单

2023, Feb 26    

实现通知菜单的封装

基于Element-plus框架的Badge徽章、Popover弹出框、Tabs标签页,封装为通知菜单组件。

初始配置

  • 注册路由组件notification,配置为Container组件的子路由组件
  • 采用路由懒加载,箭头函数异步引入组件。
  • 注册通用组件notification,为路由组件的子组件,以便组件间通信。
  • 将通用组件notification注册为全局组件

icon+badge实现点击前样式

  • 子组件 value控制消息个数,max最大值,is-dot显示为圆点
  <el-badge style="cursor: pointer" :value="value" :max="max" :is-dot="isDot">
    <component :is="`qt-icon-${toLine(icon)}`"></component>
  </el-badge>
  • 父组件 示例:
  <my-notification :value='50' :max='30' isDot icon="ChatRound"></my-notification>

Popover弹出框配置详情页

  • 子组件
  <el-popover
    placement="bottom"
    :width="300"
    trigger="click"
    //content可显示弹出框内容,官方文档同时提供插槽的方式
    <!--content="this is content, this is content, this is content" -->
    >
    <template #default>
      <!-- 放父组件传值的插槽 -->
      <!-- 此处放置插槽,配置弹出框的内容页 -->
      <slot></slot>
    </template>
    //reference插槽表示触发 Popover 显示的 HTML 元素
    <template #reference>
      <el-badge style="cursor: pointer" :value="value" :max="max" :is-dot="isDot">
        <component :is="`qt-icon-${toLine(icon)}`"></component>
      </el-badge>
    </template>
  </el-popover>
  • 父组件
<my-notification :value="50">
  <template #default> 
  <!--  此处注册list组件实现详情页    -->
  </template>  
</my-notification>

Tabs标签页实现通知菜单详情页

  • 全局注册list组件,定义接口泛型,路径:src/components/list/src/types.ts 详情页包含多列表和操作选项,用到的组件包括:Tabs、Avatar、Tag、Scrollbar

  • 列表每一项

  export interface ListItem{
      //头像
      avatar?: string,
      //标题
      title?: string,
      //描述
      desc?: string
      //时间
      time?: string,
      //标签
      tag?: string,
      tagType?: '' | 'success' | 'info' | 'warning' | 'danger'
  }
  • 列表
  export interface ListOptions {
      title: string,
      content: ListItem[]
  }
  • 操作选项
  export interface ActionOptions {
      text: string,
      icon?: string
  }
  • list组件
  let props = defineProps({
    //列表的内容
    list:{
      type: Array as PropType<ListOptions[]>,
      required: true
    },
    //操作的内容
    actions:{
      type: Array as PropType<ActionOptions[]>,
      default: ()=>[]
    }
  })
  • 父组件
  <template #default> 
    <my-list  :list="list" :actions="actions"></my-list>
  </template> 
  //data为编写的json数据
  import { list,actions } from './data'

处理list组件数据

  • list组件
  //list-tabs-item为命名空间,处理样式问题
  <div class="list-tabs-item">
    //tabs组件
    <el-tabs >
      //子标签,遍历list
      <el-tab-pane 
      v-for="(item,index) in props.list" 
      :key="index"
      :label="item.title"
      >
        //scrollbar设置高度
        <el-scrollbar max-height="300px">
          //listItem内容
          <div class="container" v-for="(item1,index1) in item.content" :key="index1">
            //头像
            <div class="avatar" v-if="item1.avatar">
              <el-avatar size="small" :src="item1.avatar" />
            </div>
            //右侧内容区
            <div class="content">
              //标题和tag一起封装
              <div v-if="item1.title" class="title">
                <div></div>
                <el-tag :type="item1.tagType" size="mini" v-if="item1.tag"></el-tag>
              </div>
              //描述段
              <div v-if="item1.desc" class="timer"></div>
              //时间
              <div v-if="item1.time" class="timer"></div>
            </div>
          </div>
          //操作选项内容
          <div class="actions">
            //遍历actions
            <div class="a-item" :class="{'border':index!==actions.length}"  v-for="(item,index) in actions" :key="index">
            //左侧图标
            <div class="a-icon" v-if="item.icon">
              <component :is="`qt-icon-${toLine(item.icon)}`"></component>
            </div>
            //右侧操作项
            <div class="a-text"></div>
            </div>
          </div>
        </el-scrollbar>
      </el-tab-pane>
    </el-tabs>
  </div>