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

@lytjs/component

v6.4.0

Published

LytJS component system - component instances, props, emits, slots, and lifecycle

Readme

@lytjs/component

LytJS 组件系统,提供组件实例管理、Props/Emits/Slots、生命周期钩子、错误边界和内置组件

安装

npm install @lytjs/component

核心 API

defineComponent

定义组件选项对象

import { defineComponent } from '@lytjs/component';

const MyComponent = defineComponent({
  name: 'MyComponent',
  props: {
    title: String,
    count: { type: Number, default: 0 },
  },
  emits: ['update:count'],
  setup(props, { emit, slots }) {
    return () => h('div', props.title);
  },
});

defineFunctionalComponent

定义函数式组件

import { defineFunctionalComponent } from '@lytjs/component';

const FunctionalButton = defineFunctionalComponent((props, ctx) => {
  return h('button', props.text);
});

createComponentInstance / setupComponent

创建和初始化组件实例

import { createComponentInstance, setupComponent } from '@lytjs/component';

const instance = createComponentInstance(vnode, parent);
setupComponent(instance);

provide / inject

依赖注入

import { provide, inject } from '@lytjs/component';

// 父组件提供
provide('theme', 'dark');

// 子组件注入
const theme = inject('theme', 'light'); // 默认值 'light'

生命周期钩子

注册钩子

import {
  onBeforeMount,
  onMounted,
  onBeforeUpdate,
  onUpdated,
  onBeforeUnmount,
  onUnmounted,
  onErrorCaptured,
  onActivated,
  onDeactivated,
  onRenderTracked,
  onRenderTriggered,
} from '@lytjs/component';

export default defineComponent({
  setup() {
    onBeforeMount(() => {
      console.log('Before mount');
    });

    onMounted(() => {
      console.log('Mounted');
    });

    onBeforeUpdate(() => {
      console.log('Before update');
    });

    onUpdated(() => {
      console.log('Updated');
    });

    onBeforeUnmount(() => {
      console.log('Before unmount');
    });

    onUnmounted(() => {
      console.log('Unmounted');
    });

    onErrorCaptured((err, instance, info) => {
      console.error('Error captured:', err);
      return false; // 阻止错误继续传播
    });

    // KeepAlive 激活/停用
    onActivated(() => {
      console.log('Activated');
    });

    onDeactivated(() => {
      console.log('Deactivated');
    });

    // 调试钩子
    onRenderTracked((e) => {
      console.log('Render tracked:', e);
    });

    onRenderTriggered((e) => {
      console.log('Render triggered:', e);
    });
  },
});

内部钩子调用

import {
  callLifecycleHook,
  callCreatedHook,
  callMountedHook,
  callUpdatedHook,
  callUnmountedHook,
  handleError,
} from '@lytjs/component';

// 手动调用生命周期钩子(内部使用)
callMountedHook(instance);

// 错误处理
handleError(err, instance, 'hook');

错误边界

ErrorBoundary 组件用于捕获子组件的渲染错误

基本用法

import { ErrorBoundary } from '@lytjs/component';

const App = defineComponent({
  components: { ErrorBoundary },
  template: `
    <ErrorBoundary 
      :on-error="handleError"
      :fallback="FallbackComponent"
    >
      <MyComponent />
    </ErrorBoundary>
  `,
  methods: {
    handleError(err: Error, info: string) {
      console.error('Error:', err, 'Info:', info);
    },
  },
});

Props

interface ErrorBoundaryProps {
  /** 错误回调 */
  onError?: (error: Error, info: string) => void;
  /** 回退组件 */
  fallback?: ComponentOptions;
  /** 是否捕获异步 Promise 错误 */
  capturePromiseRejections?: boolean;
}

插槽用法

<ErrorBoundary>
  <template #default>
    <MyComponent />
  </template>
  <template #fallback="{ error }">
    <div>Something went wrong: {{ error?.message }}</div>
  </template>
</ErrorBoundary>

异步错误捕获

<ErrorBoundary :capture-promise-rejections="true">
  <AsyncComponent />
</ErrorBoundary>

KeepAlive

内置缓存组件,用于缓存非活动组件实例

import { KeepAlive } from '@lytjs/component';

// 基本用法
<KeepAlive>
  <component :is="currentComponent" />
</KeepAlive>

// 带 include/exclude
<KeepAlive include="ComponentA,ComponentB">
  <component :is="currentComponent" />
</KeepAlive>

<KeepAlive :exclude="/^Admin/">
  <component :is="currentComponent" />
</KeepAlive>

// 最大缓存数
<KeepAlive :max="10">
  <component :is="currentComponent" />
</KeepAlive>

KeepAlive API

import {
  KeepAlive,
  createKeepAliveInstance,
  matchesPattern,
  getCacheKey,
  cacheInstance,
  getCachedInstance,
  removeCachedInstance,
  activateInstance,
  deactivateInstance,
} from '@lytjs/component';

// 手动管理缓存
const key = getCacheKey(vnode);
cacheInstance(key, instance);
const cached = getCachedInstance(key);
removeCachedInstance(key);

// 激活/停用
activateInstance(instance);
deactivateInstance(instance);

Suspense

异步组件边界,用于处理异步依赖

import { Suspense } from '@lytjs/component';

<Suspense>
  <template #default>
    <AsyncComponent />
  </template>
  <template #fallback>
    <div>Loading...</div>
  </template>
</Suspense>

Suspense API

import {
  Suspense,
  createSuspenseInstance,
  createSuspenseBoundary,
  registerAsyncChild,
  isSuspensePending,
  getSuspenseError,
  resolveSuspense,
  abortSuspense,
  linkSuspenseBoundary,
} from '@lytjs/component';

// 手动管理 Suspense
const suspense = createSuspenseBoundary();
registerAsyncChild(suspense, asyncComponent);

if (isSuspensePending(suspense)) {
  // 等待中
}

resolveSuspense(suspense);
abortSuspense(suspense);

Transition / TransitionGroup

过渡动画组件

import { Transition, TransitionGroup } from '@lytjs/component';

// 单元素过渡
<Transition name="fade" mode="out-in">
  <div :key="current">Content</div>
</Transition>

// 列表过渡
<TransitionGroup name="list" tag="ul">
  <li v-for="item in items" :key="item.id">{{ item.text }}</li>
</TransitionGroup>

Teleport

传送门组件,将内容渲染到指定位置

import { Teleport } from '@lytjs/component';

<Teleport to="body">
  <div class="modal">Modal content</div>
</Teleport>

<Teleport to="#modals" :disabled="isMobile">
  <div>Conditional teleport</div>
</Teleport>

异步组件

defineAsyncComponent

定义异步加载的组件

import { defineAsyncComponent } from '@lytjs/component';

const AsyncComponent = defineAsyncComponent({
  loader: () => import('./HeavyComponent.vue'),
  loadingComponent: LoadingSpinner,
  errorComponent: ErrorDisplay,
  delay: 200,
  timeout: 10000,
  onError(error, retry, fail) {
    if (error.name === 'ChunkError') {
      retry();
    } else {
      fail();
    }
  },
});

预加载

import {
  preloadComponents,
  preloadComponent,
  isComponentPreloaded,
  clearPreloadCache,
} from '@lytjs/component';

// 预加载单个组件
await preloadComponent(AsyncComponent);

// 预加载多个组件
await preloadComponents([ComponentA, ComponentB]);

// 检查是否已预加载
if (isComponentPreloaded(AsyncComponent)) {
  // 已预加载
}

// 清除预加载缓存
clearPreloadCache();

Props / Emits / Slots

Props

import { normalizePropsOptions, resolvePropValue, validateType } from '@lytjs/component';

// 规范化 props 选项
const normalized = normalizePropsOptions(componentOptions.props);

// 解析 prop 值
const value = resolvePropValue(propOptions, rawValue);

// 类型验证
if (validateType(String, value)) {
  // 类型正确
}

Emits

import { emit, normalizeEmitsOptions, isEmitValid } from '@lytjs/component';

// 发射事件
emit(instance, 'update:modelValue', newValue);

// 规范化 emits 选项
const normalized = normalizeEmitsOptions(componentOptions.emits);

// 检查事件是否有效
if (isEmitValid(instance, 'click')) {
  // 事件有效
}

Slots

import { initSlots, normalizeSlotValue } from '@lytjs/component';

// 初始化插槽
initSlots(instance, children);

// 规范化插槽值
const normalized = normalizeSlotValue(slotValue);

Signal State 适配器

使 Signal 可以与组件协作

import { createSignalState, createComputedState } from '@lytjs/component';

// 创建 Signal 状态
const state = createSignalState(signal(0));

// 创建计算状态
const computed = createComputedState(() => props.count * 2);

递归深度限制

组件系统内置递归深度限制,防止无限递归导致的栈溢出:

  • 组件渲染递归深度限制
  • KeepAlive 缓存递归深度限制
  • Suspense 边界嵌套深度限制

当超过限制时,会输出警告并停止递归。

类型定义

import type {
  ComponentOptions,
  ComponentInternalInstance,
  ComponentPublicInstance,
  ComponentIdentity,
  ComponentLifecycleState,
  ComponentRenderState,
  ComponentContextState,
  ComponentParentState,
  SetupContext,
  InternalSlots,
  AppContext,
  PropOptions,
  RenderFunction,
  SlotFunction,
  KeepAliveProps,
  SuspenseProps,
  SuspenseAsyncState,
  TeleportProps,
  ErrorBoundaryProps,
  TransitionComponentProps,
  TransitionGroupComponentProps,
  AsyncComponentLoader,
  AsyncComponentOptions,
  AsyncComponentState,
} from '@lytjs/component';

相关包