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

xzx-chat-kit-vue2

v0.1.7

Published

Vue chat kit component for VUE 2

Readme

xzx-chat-kit

一个跨前端框架的聊天组件库,支持 Vue 2、Vue 3 和 React。

特性

  • 🚀 支持 Vue 2.6+ 和 Vue 3
  • ⚛️ 支持 React 16.8+
  • 📦 使用 TypeScript 编写
  • 🎯 零依赖核心库
  • 🔧 使用 vue-demi 实现 Vue 版本兼容
  • 🎨 样式文件可独立导入
  • 🎯 支持自定义插槽
  • 💫 支持消息状态管理
  • 🎨 支持主题定制
  • ⌨️ 内置打字机效果
  • 🗑️ 支持消息删除和清空

安装

npm install xzx-chat-kit
# 或
pnpm add xzx-chat-kit
# 或
yarn add xzx-chat-kit

Vue 2 额外依赖

如果你使用 Vue 2,还需要安装 @vue/composition-api

npm install @vue/composition-api

使用方法

自动导入样式

组件会自动导入所需的样式,无需手动导入。

手动导入样式

如果您希望手动控制样式导入,可以单独导入:

// 导入样式文件
import 'xzx-chat-kit/styles'
// 或
import 'xzx-chat-kit/dist/styles/index.css'

Vue 3

<template>
  <div>
    <ChatBox :chat-core="chatCore">
      <!-- 自定义开始区域 -->
      <template #start-here>
        <div class="start-message">
          <span>👋 开始愉快的聊天吧!</span>
        </div>
      </template>

      <!-- 自定义空状态 -->
      <template #empty>
        <div class="custom-empty-state">
          <p>还没有消息哦,快来开始聊天吧!</p>
        </div>
      </template>

      <!-- 自定义消息内容 -->
      <template #message="{ content, component, componentProps }">
        <span v-if="content?.message || content">{{
          content?.message || content
        }}</span>
        <component v-if="component" :is="component" v-bind="componentProps" />
      </template>

      <!-- 自定义输入框 -->
      <template #input="{ value, onInput, onSend, placeholder }">
        <div class="custom-input-wrapper">
          <textarea
            :value="value"
            @input="(e) => onInput(e.target.value)"
            :placeholder="placeholder"
            @keyup.enter.ctrl="onSend" />
          <button @click="onSend">发送</button>
        </div>
      </template>
    </ChatBox>
  </div>
</template>

<script setup>
import { ref } from 'vue'
import { ChatBox } from 'xzx-chat-kit/vue'
import { ChatCore, typewriterEffect } from 'xzx-chat-kit'

const messages = ref([])

// 创建 ChatCore 实例
const chatCore = new ChatCore({
  currentUser: 'user',
  placeholder: '请输入您的消息...',
  showAvatar: true,
  messages: messages.value,
  onSendMessage: async (message, history) => {
    console.log('发送消息:', message)
    console.log('历史记录:', history)

    // 模拟机器人回复
    await simulateBot(message)
  }
})

// 使用打字机效果模拟机器人回复
const simulateBot = async (userMessage) => {
  const messageContent = ref('')

  // 添加空消息
  chatCore.addMessage({
    id: Date.now(),
    content: messageContent,
    sender: 'bot',
    timestamp: Date.now(),
    type: 'text'
  })

  // 使用打字机效果
  await typewriterEffect(`你说: ${userMessage}`, messageContent, {
    speed: 50,
    delay: 500
  })
}
</script>

Vue 2

<template>
  <div>
    <ChatBox :chat-core="chatCore">
      <template #start-here>
        <div class="start-message">
          <span>👋 开始愉快的聊天吧!</span>
        </div>
      </template>

      <template #empty>
        <div class="custom-empty-state">
          <p>还没有消息哦,快来开始聊天吧!</p>
        </div>
      </template>

      <template #message="{ content, component, componentProps }">
        <span v-if="content.message || content">{{
          content.message || content
        }}</span>
        <component v-if="component" :is="component" v-bind="componentProps" />
      </template>
    </ChatBox>
  </div>
</template>

<script>
import { ref } from 'vue-demi'
import { ChatBox } from 'xzx-chat-kit/vue'
import { ChatCore, typewriterEffect } from 'xzx-chat-kit'

export default {
  components: {
    ChatBox
  },
  data() {
    const messages = ref([])

    return {
      chatCore: new ChatCore({
        currentUser: 'user',
        placeholder: '请输入您的消息...',
        showAvatar: true,
        messages: messages.value,
        onSendMessage: async (message, history) => {
          console.log('发送消息:', message)
          console.log('历史记录:', history)

          // 模拟机器人回复
          await this.simulateBot(message)
        }
      })
    }
  },
  methods: {
    async simulateBot(userMessage) {
      const messageContent = ref('')

      this.chatCore.addMessage({
        id: Date.now(),
        content: messageContent,
        sender: 'bot',
        timestamp: Date.now(),
        type: 'text'
      })

      await typewriterEffect(`你说: ${userMessage}`, messageContent, {
        speed: 50,
        delay: 500
      })
    }
  }
}
</script>

React

import React, { useRef, useState } from 'react'
import { ChatBox } from 'xzx-chat-kit/react'
import { ChatCore, typewriterEffect } from 'xzx-chat-kit'

function App() {
  const [messages] = useState([])
  const chatCoreRef = useRef(null)

  // 创建 ChatCore 实例
  if (!chatCoreRef.current) {
    chatCoreRef.current = new ChatCore({
      currentUser: 'user',
      placeholder: '请输入您的消息...',
      showAvatar: true,
      messages: messages,
      onSendMessage: async (message, history) => {
        console.log('发送消息:', message)
        console.log('历史记录:', history)

        // 模拟机器人回复
        await simulateBot(message)
      }
    })
  }

  // 使用打字机效果模拟机器人回复
  const simulateBot = async (userMessage) => {
    const messageContent = { value: '' }

    chatCoreRef.current.addMessage({
      id: Date.now(),
      content: messageContent,
      sender: 'bot',
      timestamp: Date.now(),
      type: 'text'
    })

    // 模拟打字机效果(React 版本需要手动实现响应式更新)
    const text = `你说: ${userMessage}`
    let index = 0
    const typeInterval = setInterval(() => {
      messageContent.value = text.slice(0, index + 1)
      index++
      if (index >= text.length) {
        clearInterval(typeInterval)
      }
    }, 50)
  }

  return (
    <div>
      <ChatBox
        chatCore={chatCoreRef.current}
        startHereSlot={
          <div className="start-message">
            <span>👋 开始愉快的聊天吧!</span>
          </div>
        }
        emptySlot={
          <div className="custom-empty-state">
            <p>还没有消息哦,快来开始聊天吧!</p>
          </div>
        }
        messageSlot={({ content, component, componentProps }) => (
          <>
            {content ? <span>{content}</span> : null}
            {component && <component {...componentProps} />}
          </>
        )}
        inputSlot={({ value, onChange, onSend, placeholder }) => (
          <div className="custom-input-wrapper">
            <textarea
              value={value}
              onChange={onChange}
              placeholder={placeholder}
              onKeyUp={(e) => e.ctrlKey && e.key === 'Enter' && onSend()}
            />
            <button onClick={onSend}>发送</button>
          </div>
        )}
      />
    </div>
  )
}

export default App

作为插件使用

// Vue 3
import { createApp } from 'vue'
import XzxChatKit from 'xzx-chat-kit/vue'
import App from './App.vue'

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

// Vue 2
import Vue from 'vue'
import XzxChatKit from 'xzx-chat-kit/vue'
import App from './App.vue'

Vue.use(XzxChatKit)

new Vue({
  render: (h) => h(App)
}).$mount('#app')

// 使用时仍需要创建 ChatCore 实例
// <template>
//   <ChatBox :chat-core="chatCore" />
// </template>

插槽

组件提供了以下插槽用于自定义内容:

start-here

在消息列表顶部显示的内容,通常用于显示开始聊天的提示或欢迎信息。

<template>
  <ChatBox :chat-core="chatCore">
    <template #start-here>
      <div class="welcome-message">
        <h3>👋 欢迎使用聊天助手</h3>
        <p>点击下方按钮开始对话</p>
        <button @click="startChat">开始聊天</button>
      </div>
    </template>
  </ChatBox>
</template>

empty

当消息列表为空时显示的内容。

message

自定义消息内容的渲染方式。

input

自定义输入框区域的渲染方式。

样式定制

所有的 CSS 类都以 ck- 前缀命名,您可以通过覆盖这些类来自定义样式:

/* 自定义容器样式 */
.ck-chat-box {
  background: #f0f0f0;
  border-radius: 12px;
}

/* 自定义按钮样式 */
.ck-send-button {
  background: #666666;
}

.ck-send-button:hover {
  background: #808080;
}

CSS 变量

组件使用 CSS 变量来管理主题,您可以通过覆盖这些变量来自定义主题:

:root {
  /* 主题色 */
  --ck-primary-color: #666666;
  --ck-primary-hover: #808080;
  --ck-primary-active: #4d4d4d;

  /* 背景色 */
  --ck-bg-color: #ffffff;
  --ck-bg-hover: #f5f5f5;
  --ck-bg-active: #e6e6e6;

  /* 文字颜色 */
  --ck-text-color: #666666;
  --ck-text-secondary: #808080;
  --ck-text-disabled: #999999;

  /* 边框颜色 */
  --ck-border-color: #e6e6e6;
  --ck-border-hover: #d9d9d9;

  /* 消息气泡颜色 */
  --ck-message-bg: #f5f5f5;
  --ck-message-user-bg: #e6e6e6;
  --ck-message-text: #666666;
}

API 文档

ChatCore

聊天组件的核心数据管理类。

构造函数

const chatCore = new ChatCore(options)

方法

| 方法 | 参数 | 返回值 | 描述 | | ------------------------------------- | ----------------------------------- | ----------- | ---------------- | | getState() | - | ChatState | 获取当前状态 | | getMessages() | - | Message[] | 获取消息列表 | | addMessage(message) | Message | void | 添加消息 | | sendMessage(content) | string | void | 发送消息 | | updateMessageStatus(id, status) | string \| number, MessageStatus | void | 更新消息状态 | | clearMessages() | - | void | 清空所有消息 | | deleteMessage(id) | string \| number | boolean | 删除指定消息 | | setMessagesChangeCallback(callback) | (messages: Message[]) => void | void | 设置消息变化回调 |

ChatOptions

| 属性 | 类型 | 默认值 | 描述 | | ----------------------- | -------------------------------------------------------------- | ----------------- | -------------------------- | | currentUser | string | 'user' | 当前用户标识 | | messages | Message[] | [] | 初始消息列表 | | placeholder | string | '请输入消息...' | 输入框占位符 | | showAvatar | boolean | true | 是否显示头像 | | onSendMessage | (message: string, history: ChatHistoryItem[]) => void | - | 发送消息回调,包含历史记录 | | onMessageStatusChange | (messageId: string \| number, status: MessageStatus) => void | - | 消息状态变化回调 |

ChatHistoryItem

聊天历史记录项,用于 onSendMessage 回调的第二个参数。

| 属性 | 类型 | 描述 | | ----------- | --------- | ------------ | | message | any | 消息内容 | | isUser | boolean | 是否用户消息 | | timestamp | number | 时间戳 |

Message

| 属性 | 类型 | 描述 | | ---------------- | -------------------------------------------- | ---------------------- | | id | string \| number | 消息唯一标识 | | content | string \| Ref<string> | 消息内容(支持响应式) | | sender | string | 发送者 | | isUser | boolean | 是否为用户消息 | | timestamp | number | 发送时间戳 | | type | 'text' \| 'image' \| 'file' \| 'component' | 消息类型 | | status | 'sending' \| 'sent' \| 'read' \| 'failed' | 消息状态 | | avatar | string | 头像 URL | | component | Component | 自定义组件 | | componentProps | any | 组件属性 |

版本兼容性

| 框架 | 版本要求 | | ----- | --------- | | Vue 2 | >= 2.6.0 | | Vue 3 | >= 3.0.0 | | React | >= 16.8.0 |

开发

# 安装依赖
pnpm install

# 构建
pnpm build

# 构建单独的包
pnpm build:core    # 核心库
pnpm build:vue     # Vue 组件 (支持 Vue 2 & 3)
pnpm build:react   # React 组件
pnpm build:styles  # 复制样式文件

打字机效果

组件库内置了打字机效果功能,可以让文本逐字显示。

基本用法

import { typewriterEffect, createTypewriter } from 'xzx-chat-kit'
import { ref } from 'vue' // 或 'vue-demi'

// 方式1: 简单的 Promise 方式
const messageContent = ref('')
await typewriterEffect('Hello, World!', messageContent, {
  speed: 50, // 每个字符显示间隔(毫秒)
  delay: 500, // 开始前延迟(毫秒)
  onProgress: (currentText, progress) => {
    console.log(`进度: ${Math.round(progress * 100)}%`)
  },
  onComplete: () => {
    console.log('打字完成!')
  }
})

// 方式2: 更强的控制方式
const { displayText, controller } = createTypewriter('Hello, World!', {
  speed: 50,
  delay: 500
})

// 控制打字机
controller.start() // 开始
controller.pause() // 暂停
controller.resume() // 继续
controller.stop() // 停止
controller.reset() // 重置

// 检查状态
console.log(controller.isRunning()) // 是否正在运行
console.log(controller.isPaused()) // 是否已暂停

配置选项

| 选项 | 类型 | 默认值 | 描述 | | ------------ | ------------------------------------------ | ------ | -------------- | | speed | number | 50 | 每字符间隔(ms) | | delay | number | 0 | 开始前延迟(ms) | | onProgress | (text: string, progress: number) => void | - | 进度回调 | | onComplete | () => void | - | 完成回调 |

许可证

MIT