npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

zan-layer

v1.0.8

Published

A powerful layer component for Vue 3

Readme

zan-layer

Vue 3 弹层组件库,提供函数式弹层 API 和组件能力,适合中后台常见的消息、确认框、页面层、抽屉、通知、图片预览和输入层。

适用范围

  • 通用确认框、消息、加载层
  • 需要承载 Vue 组件内容的页面层 / 抽屉
  • 图片预览、通知消息、输入弹层
  • 希望用统一 API 管理打开、关闭、最大化、最小化、恢复等动作

安装

npm install zan-layer

样式需要显式引入:

import 'zan-layer/lib/index.css'

快速开始

全局安装

import { createApp } from 'vue'
import ZanLayer from 'zan-layer'
import 'zan-layer/lib/index.css'

const app = createApp(App)
app.use(ZanLayer)
app.mount('#app')

安装后:

  • 注册组件:<ZanLayer />
  • 挂载全局方法:app.config.globalProperties.$layer
  • 可直接导入函数式 API:import { layer, zanLayer } from 'zan-layer'

直接使用函数式 API

import { layer } from 'zan-layer'

layer.msg('操作成功')

layer.confirm('确定要删除吗?', {
  yes: (id: string) => {
    console.log('confirmed')
    layer.close(id)
  }
})

导出内容

包对外提供:

  • 默认导出:ZanLayerPlugin
  • 命名导出:layer
  • 命名导出:zanLayer,与 layer 等价
  • 命名导出:ZanLayer
  • 类型导出:LayerPropsBtnTypeImgListType

常用方法

layer.open(options)

通用页面层入口,几乎所有复杂弹层场景都从这里开始。

const id = layer.open({
  type: 'page',
  title: '编辑商品',
  content: '这里可以放字符串、VNode 或返回 VNode 的函数',
  area: ['720px', '560px'],
  shadeClose: false,
  maxmin: true,
  resize: true
})

layer.msg(message, options?)

layer.msg('保存成功', {
  icon: 1,
  time: 2000
})

layer.confirm(message, options?)

layer.confirm('确定提交吗?', {
  yes: (id: string) => {
    submit()
    layer.close(id)
  }
})

layer.load(type?, options?)

const loadingId = layer.load(0, {
  shade: true,
  shadeOpacity: '0.3'
})

setTimeout(() => {
  layer.close(loadingId)
}, 1500)

layer.drawer(options)

layer.drawer({
  title: '筛选条件',
  content: '这里是抽屉内容',
  offset: 'r',
  area: ['420px', '100%']
})

layer.notify(options)

layer.notify({
  title: '新消息',
  content: '订单已完成支付',
  icon: 1,
  offset: 'rt',
  time: 3000
})

layer.photos(options)

layer.photos({
  imgList: [
    { src: '/img/1.jpg', alt: '图片1' },
    { src: '/img/2.jpg', alt: '图片2' }
  ],
  startIndex: 0
})

layer.prompt(options)

layer.prompt({
  title: '请输入备注',
  formType: 'textarea',
  value: '默认内容',
  maxLength: 100,
  yes: (id: string, value: string) => {
    console.log(value)
    layer.close(id)
  }
})

LayerProps 核心字段

最常用字段如下:

| 字段 | 说明 | | --- | --- | | type | 弹层类型,支持数字和字符串别名 | | title | 标题,可传字符串、VNode、返回 VNode 的函数,传 false 可隐藏 | | footer | 底部区域内容 | | content | 主体内容,支持字符串、VNode、函数 | | area | 宽高,如 '560px'['720px', '560px'] | | width | 单独指定宽度,会覆盖 area[0] | | height | 单独指定高度,会覆盖 area[1] | | minWidth | 最小宽度,支持数字或 CSS 尺寸字符串 | | maxWidth | 最大宽度,支持数字或 CSS 尺寸字符串 | | minHeight | 最小高度,支持数字或 CSS 尺寸字符串 | | maxHeight | 最大高度,支持数字或 CSS 尺寸字符串 | | offset | 位置,如 'r''rt''auto' 或坐标数组 | | shade | 是否显示遮罩 | | shadeClose | 点击遮罩是否关闭 | | shadeOpacity | 遮罩透明度 | | move | 是否允许拖拽 | | resize | 是否允许右下角拉伸 | | maxmin | 是否显示最大化/最小化按钮 | | closeBtn | 是否显示关闭按钮 | | btn | 自定义底部按钮 | | btnAlign | 底部按钮对齐方式 | | anim | 入场动画 | | isOutAnim | 是否启用退场动画 | | icon | 消息/通知图标 | | time | 自动关闭时间,毫秒 | | zIndex | 层级 | | appContext | 函数式渲染时复用宿主 Vue app 上下文 |

弹层类型

type 支持数字和字符串两套写法:

  • 0 / 'dialog'
  • 1 / 'page'
  • 2 / 'iframe'
  • 3 / 'loading'
  • 4 / 'drawer'
  • 5 / 'photos'
  • 6 / 'notify'
  • 7 / 'prompt'

在 Vue 组件中承载真实组件内容

这是中后台里最常见的用法。content 推荐直接传 VNode,且把 appContext 一起带上,避免丢失注入、全局组件或 UI 库上下文。

import { getCurrentInstance, h } from 'vue'
import { layer } from 'zan-layer'
import EditForm from './EditForm.vue'

const instance = getCurrentInstance()

layer.open({
  type: 'page',
  title: '编辑商品',
  area: ['880px', '620px'],
  resize: true,
  maxmin: true,
  appContext: instance?.appContext,
  content: h(EditForm, {
    productId: 1001
  })
})

如果你需要在关闭时拿到实例 ID,推荐先接住 open() 返回值:

const layerId = layer.open({
  title: '详情',
  appContext: instance?.appContext,
  content: h(DetailPanel, {
    onClose: () => layer.close(layerId)
  })
})

自定义按钮

layer.open({
  title: '批量操作',
  content: '确认执行吗?',
  btnAlign: 'r',
  btn: [
    {
      text: '取消',
      callback: id => layer.close(id)
    },
    {
      text: '确认',
      type: 'primary',
      callback: id => {
        runAction()
        layer.close(id)
      }
    }
  ]
})

BtnType 支持:

  • text
  • type
  • style
  • class
  • disabled
  • callback

生命周期和交互回调

常用业务回调

  • success
  • end
  • yes
  • beforeClose
  • close

拖拽 / 缩放回调

  • moveStart
  • moving
  • moveEnd
  • resizeStart
  • resizing
  • resizeEnd

示例:

layer.open({
  title: '可拖拽窗口',
  content: '拖动后记录位置',
  width: 720,
  height: 520,
  minWidth: 480,
  minHeight: 320,
  maxWidth: '90vw',
  maxHeight: '90vh',
  move: true,
  resize: true,
  moveEnd: (id, options) => {
    console.log(id, options.left, options.top)
  },
  resizeEnd: (id, options) => {
    console.log(id, options.width, options.height)
  }
})

控制方法

打开后可通过实例 ID 做控制:

  • layer.close(id)
  • layer.closeAll()
  • layer.reset(id)
  • layer.min(id)
  • layer.full(id)
  • layer.revert(id)
  • layer.resize(id, { width, height })

示例:

const layerId = layer.open({
  title: '尺寸可控窗口',
  content: '支持程序化改大小',
  width: 640,
  height: 420,
  minWidth: 420,
  minHeight: 260,
  resize: true
})

layer.resize(layerId, {
  width: '80vw',
  height: '70vh'
})

安装选项

插件安装时支持传入自定义 zIndex

app.use(ZanLayer, {
  zIndex: 3000
})

使用建议

  • 页面层、抽屉、复杂表单弹层优先走 layer.open() / layer.drawer()
  • 函数式打开 Vue 组件时,优先传 appContext
  • 通知和消息属于短生命周期,不要把复杂交互塞进 notify / msg
  • 如果你有统一视觉规范,建议在宿主项目里覆盖 layerClassescontentClass

边界与限制

  • 当前主打浏览器端函数式弹层,不是 SSR 优先组件
  • content 是字符串时只做内容渲染,不会自动编译成 Vue 模板
  • 需要复杂表单、表格、图表内容时,推荐传真实 VNode,而不是大段 HTML 字符串

开发命令

npm run dev
npm run build
npm run acceptance:smoke