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

cc1-vue3

v1.1.3

Published

我来助你-vue3工具库

Readme

vue3 工具

CRouter 复杂示例

import System from '@/utils/System'
import { createRouter, createWebHashHistory } from 'vue-router'
import CRouter from './CRouter'

/**
 * 默认主题
 */
const themeList = ['light', 'dark'] as any[]
const defaultTheme = 'light' as any
const diffTheme = 'dark' as any

/**
 * 路由目录/src/views/light/home/index.vue、/src/views/dark/home/index.vue
 */
export const initRouter = () => {
  let _modules = import.meta.glob([
    '@/views/**/*.vue',
    '!@/views/**/*-com/**/*.vue',
    '!@/views/**/com/**/*.vue',
    '!@/views/**/components/**/*.vue'
  ])

  const _defaultModules = {} as any
  const _diffModules = {} as any
  Object.keys(_modules).forEach((key) => {
    themeList.forEach((item) => {
      if (defaultTheme != item) {
        if (!new RegExp(`^/src/views/${item}`).test(key)) {
          _defaultModules[key] = _modules[key]
        }
        if (diffTheme != defaultTheme && new RegExp(`^/src/views/${diffTheme}`).test(key)) {
          _diffModules[key] = _modules[key]
        }
      }
    })
  })

  const pathHook = (path: string) => {
    return path
      .replace(/\/index$/, '')
      .replace(new RegExp(`/${defaultTheme}/`), '/')
      .replace(new RegExp(`/${diffTheme}/`), '/')
  }

  const _routes = CRouter.init({
    modules: _defaultModules,
    diffModules: _diffModules,

    children: [
      {
        path: '/layout',
        component: '/layout',
        childrenReg: ['^/pages']
      }
    ],
    setInfoHook(item) {
      item.meta = {
        title: item.path
      }
    },
    mapKeyPathHook(path) {
      return pathHook(path)
    },
    pathHook(path) {
      return pathHook(path).replace(/^\/pages/, '')
    }
  })

  const router = createRouter({
    history: createWebHashHistory(),
    routes: [
      ..._routes.array,
      {
        path: '/',
        redirect: '/home'
      }
    ]
  })

  System.router = router

  return router
}

Timer / Event 生命周期管理(1.1.3)

依赖先加载的全局 cc1-js 1.0.11;调度与事件逻辑统一由 JS 库实现,本库只连接 Vue 生命周期。 原有 Scope.Timer().on/once/un/clear、Scope.Event().on/once/off/clear 调用保持兼容。 使用前在浏览器入口调用 Scope.activity.connect();原生容器可自行桥接可见状态,调用 Scope.activity.update(isActive, online)。同一宿主只选择一种桥接方式。

const timer = Scope.Timer()
const event = Scope.Event()
const endTime = Date.now() + 60000

timer.on(() => {
    conf.seconds = Math.max(0, Math.ceil((endTime - Date.now()) / 1000))
}, 1000, true)

// 返回 Promise 后,上一轮未结束时不会启动下一轮。
timer.on(() => refreshList(), 10000)
event.on('refresh-list', refreshList)
event.listen(window, 'resize', handleResize)
  • 组件/effectScope 销毁时主动取消计时任务、总线订阅和 DOM 监听。
  • 定时器默认在后台及 KeepAlive 停用时暂停;回到前台后,每个过期任务最多补执行一次。
  • clock: 'remaining' 用于需要暂停时长的动画;默认 elapsed 用真实经过时间判断截止点。
  • immediateOnResume: true 用于即使尚未到周期也要在恢复时补刷一次的轮询。
  • 倒计时应使用截止时间计算。暂停/恢复调度器不能纠正业务代码中的 seconds--。
  • 异步回调须返回 Promise 才能防重入;失败交给 onError,默认记录到控制台。
  • once 完成后立即删除任务;事件 once 在执行回调前移除,避免递归触发。
  • 同一事件管理器重复注册同一 key 和 callback 返回同一 id;off 不影响其他管理器。
  • 总线事件默认在后台及 KeepAlive 停用时继续处理,保证 HTTP 完成、登录失效等协议事件不丢失。 UI 状态通知可显式使用 { background: 'latest', deactivated: 'latest' },恢复时只补发最新状态。
  • timer.setTimeout/setInterval/clearTimeout/clearInterval 提供浏览器风格的数字句柄,便于迁移; 不能混用原生 clearTimeout/clearInterval 清理这些句柄。
  • clear() 清空当前任务/监听后仍可重新注册;dispose() 彻底释放管理器并拒绝后续注册。
  • timer.delay() 在 clear/dispose 时以 AbortError 结束等待。调用方应捕获取消异常。 请求超时、SDK 就绪检查及用于完成 Promise 的计时不应随页面暂停,可保留原生计时器, 或显式使用 { scope: false, background: 'continue' } 并管理其释放。

共享服务与应用资源

在 setup、生命周期钩子或 Minxins 同步工厂中直接调用全局 Timer / CEvent,也会自动捕获所有者; 无需逐页替换为 Scope。异步回调中首次注册无法自动确定所属组件,应提前创建 Scope 管理器并复用。

Minxins.get(key, factory) 中创建的 Scope 资源及同步注册的全局资源归共享服务所有,最后一个组件释放后才清理; 第一个组件离开不会误停其他组件正在使用的轮询。服务的响应式 effectScope 同时清理。 组件外可以访问已存在的服务;组件外首次创建的服务为应用级。可用第三个参数 true 显式声明 应用级服务,并用 Minxins.dispose(key) 释放。旧版第三参数传组件实例的方式仍支持。

应用级独立资源用 Scope.Timer({ scope: false }) / Scope.Event({ scope: false }) 创建, 退出应用时调用 dispose。Scope.onResume(callback) 自动跟随组件或共享服务的生命周期释放。 不要覆盖全局 window.setTimeout 或 CEvent;网络协议和第三方 SDK 保持各自的截止与取消语义。