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

@blueking/bk-user-selector

v0.1.6

Published

蓝鲸用户选择器

Readme

蓝鲸多租户人员选择器组件

npm version License Vue2 Vue3

蓝鲸多租户人员选择器(BkUserSelector)是一个用于在蓝鲸系统中选择用户的组件,支持单选和多选模式,具备搜索、跨租户查询等功能。

✨ 特性

| 特性 | 说明 | | ----------------- | ------------------------------------ | | 🎯 双版本支持 | 同时支持 Vue2 和 Vue3 | | 🔄 单选/多选 | 灵活切换单选和多选模式 | | 🔍 智能搜索 | 支持用户名、登录名、全名等多字段搜索 | | 🏢 跨租户 | 支持多租户场景下的用户选择和显示 | | 🎨 可拖拽 | 多选模式下支持拖拽排序 | | ⚡ 快捷操作 | 支持快速选择当前用户("我") | | 👥 用户组 | 支持用户组/角色分组显示 | | ✏️ 自定义输入 | 支持创建自定义用户和自由粘贴 | | 🎭 自定义渲染 | 支持自定义标签和列表项渲染 | | 📝 多行输入 | 支持 textarea 模式,完整展示所有标签 | | ⌨️ 键盘导航 | 支持上下键切换选项、Enter 快速选中 | | 🎯 焦点控制 | 支持自动聚焦和手动 focus/blur 方法 |

📦 安装

# npm
npm install @blueking/bk-user-selector

# yarn
yarn add @blueking/bk-user-selector

# pnpm
pnpm add @blueking/bk-user-selector

🚀 快速开始

在 Vue3 中使用

import BkUserSelector from '@blueking/bk-user-selector';
import '@blueking/bk-user-selector/vue3/vue3.css';

export default {
  components: {
    BkUserSelector,
  },
};

在 Vue2 中使用

import BkUserSelector from '@blueking/bk-user-selector/vue2';
import '@blueking/bk-user-selector/vue2/vue2.css';

export default {
  components: {
    BkUserSelector,
  },
};

📖 使用示例

基本用法

<template>
  <!-- 单选模式 -->
  <BkUserSelector
    v-model="selectedUser"
    :api-base-url="apiBaseUrl"
    :tenant-id="tenantId"
    :current-user-id="currentUserId"
    @change="handleUserChange"
  />

  <!-- 多选模式 -->
  <BkUserSelector
    v-model="selectedUsers"
    :api-base-url="apiBaseUrl"
    :tenant-id="tenantId"
    :current-user-id="currentUserId"
    :multiple="true"
    :draggable="true"
    @change="handleUsersChange"
  />
</template>

<script setup>
  import { ref } from 'vue';

  const apiBaseUrl = ref('https://api.example.com');
  const tenantId = ref('default');
  const currentUserId = ref('admin');

  // 单选选中值
  const selectedUser = ref('');
  // 多选选中值
  const selectedUsers = ref([]);

  const handleUserChange = user => {
    console.log('Selected user:', user);
  };

  const handleUsersChange = users => {
    console.log('Selected users:', users);
  };
</script>

用户组/角色模式

当需要在下拉列表中展示用户组(如角色、部门等)时:

<template>
  <BkUserSelector
    v-model="selectedUsers"
    :api-base-url="apiBaseUrl"
    :tenant-id="tenantId"
    :multiple="true"
    :user-group="userGroup"
    :user-group-name="userGroupName"
    @change="handleChange"
  />
</template>

<script setup>
  import { ref } from 'vue';

  const apiBaseUrl = ref('https://api.example.com');
  const tenantId = ref('default');
  const selectedUsers = ref([]);

  // 用户组配置
  const userGroup = ref([
    {
      id: '1',
      name: '运维人员',
      hidden: true, // hidden 为 true 时,不会展示在下拉列表里,但回显时会展示
    },
    {
      id: '2',
      name: '产品人员',
    },
  ]);
  const userGroupName = ref('角色');

  const handleChange = users => {
    console.log('Selected:', users);
  };
</script>

自定义渲染

支持自定义标签和列表项的渲染:

<template>
  <BkUserSelector
    v-model="selectedUsers"
    :api-base-url="apiBaseUrl"
    :tenant-id="tenantId"
    :multiple="true"
    :render-tag="renderTag"
    :render-list-item="renderListItem"
  />
</template>

<script setup>
  import { ref, h } from 'vue';

  const apiBaseUrl = ref('https://api.example.com');
  const tenantId = ref('default');
  const selectedUsers = ref([]);

  // 自定义标签渲染
  const renderTag = (createElement, userInfo) => {
    return createElement('span', { class: 'custom-tag' }, [
      createElement('img', { src: userInfo.logo, class: 'avatar' }),
      userInfo.display_name,
    ]);
  };

  // 自定义列表项渲染
  const renderListItem = (createElement, userInfo) => {
    return createElement('div', { class: 'custom-item' }, [
      createElement('img', { src: userInfo.logo, class: 'avatar' }),
      createElement('div', { class: 'info' }, [
        createElement('span', { class: 'name' }, userInfo.display_name),
        createElement('span', { class: 'username' }, `@${userInfo.username}`),
      ]),
    ]);
  };
</script>

自定义输入

当 API 无法覆盖所有用户时,允许用户自定义输入:

<template>
  <BkUserSelector
    v-model="selectedUsers"
    :api-base-url="apiBaseUrl"
    :tenant-id="tenantId"
    :multiple="true"
    :allow-create="true"
    :free-paste="true"
    placeholder="输入用户名,按 Enter 确认"
    @change="handleChange"
  />
</template>

<script setup>
  import { ref } from 'vue';

  const apiBaseUrl = ref('https://api.example.com');
  const tenantId = ref('default');
  const selectedUsers = ref([]);

  const handleChange = users => {
    // 自定义输入的用户 id 为输入的文本
    console.log('Selected:', users);
  };
</script>

多行输入模式(Textarea)

当需要展示大量已选用户时,可使用 textarea 模式完整展示所有标签:

<template>
  <BkUserSelector
    v-model="selectedUsers"
    :api-base-url="apiBaseUrl"
    :tenant-id="tenantId"
    :multiple="true"
    type="textarea"
    :rows="4"
    :resize="true"
    @change="handleChange"
  />
</template>

<script setup>
  import { ref } from 'vue';

  const apiBaseUrl = ref('https://api.example.com');
  const tenantId = ref('default');
  const selectedUsers = ref([]);

  const handleChange = users => {
    console.log('Selected:', users);
  };
</script>

排除指定用户

从下拉列表中排除特定用户:

<template>
  <BkUserSelector
    v-model="selectedUser"
    :api-base-url="apiBaseUrl"
    :tenant-id="tenantId"
    :exclude-user-ids="excludeUserIds"
  />
</template>

<script setup>
  import { ref } from 'vue';

  const apiBaseUrl = ref('https://api.example.com');
  const tenantId = ref('default');
  const selectedUser = ref('');

  // 排除这些用户,不会出现在搜索结果中
  const excludeUserIds = ref(['user1', 'user2', 'user3']);
</script>

📋 API 文档

Props 属性

| 参数 | 说明 | 类型 | 默认值 | 必填 | | --------------------- | -------------------------------------------- | ------------------------------------------------ | ---------------------- | ---- | | modelValue / v-model | 绑定值,单选为字符串,多选为数组 | string / string[] | '' / [] | 是 | | apiBaseUrl | API 基础 URL | string | '' | 是 | | tenantId | 租户 ID | string | 'default' | 否 | | hasAvatar | 是否显示头像 | boolean | false | 否 | | avatarBaseUrl | 头像基础 URL | string | `` | 否 | | label | 文本标签 | string | '人员选择' | 否 | | placeholder | 占位文本 | string | '请输入人员名称搜索' | 否 | | multiple | 是否多选 | boolean | false | 否 | | draggable | 是否可拖拽排序(仅多选模式有效) | boolean | false | 否 | | exactSearchKey | 精确查找 key | 'bk_username' / 'login_name' / 'full_name' | 'bk_username' | 否 | | currentUserId | 当前用户 ID(用于快速选择"我") | string | '' | 否 | | userGroup | 用户组列表 | UserGroupItem[] | [] | 否 | | userGroupName | 用户组分类名称 | string | '用户群组' | 否 | | emptyText | 无匹配人员时的提示文本 | string | '无匹配人员' | 否 | | disabled | 是否禁用 | boolean | false | 否 | | renderTag | 自定义标签渲染函数 | (h, userInfo) => VNode | - | 否 | | renderListItem | 自定义列表项渲染函数 | (h, userInfo) => VNode | - | 否 | | excludeUserIds | 排除的用户 ID 列表 | string[] | [] | 否 | | enableMultiTenantMode | 是否启用多租户模式 | boolean | true | 否 | | allowCreate | 是否允许自定义输入,按 Enter 确认 | boolean | false | 否 | | freePaste | 是否允许粘贴任意文本 | boolean | false | 否 | | maxCount | 最大可选数量(0 表示不限制) | number | 0 | 否 | | type | 输入框类型 | 'input' / 'textarea' | 'input' | 否 | | rows | 默认行数(仅 textarea 模式生效) | number | 4 | 否 | | resize | 是否允许拖拽调整高度(仅 textarea 模式生效) | boolean | true | 否 | | autoFocus | 是否自动聚焦 | boolean | false | 否 |

exactSearchKey 说明

支持多个字段组合搜索,以逗号分隔:

| 值 | 说明 | | ----------------------- | ---------------------- | | bk_username | 按蓝鲸用户名搜索 | | login_name | 按登录名搜索 | | full_name | 按全名搜索 | | bk_username,full_name | 同时按用户名和全名搜索 |

Events 事件

| 事件名称 | 说明 | 回调参数 | | ----------------- | -------------------- | ------------------------------------ | | update:modelValue | 绑定值变化时触发 | (value: string \| string[]) | | change | 选中值变化时触发 | (userInfo: UserInfo \| UserInfo[]) | | focus | 输入框获得焦点时触发 | - | | blur | 输入框失去焦点时触发 | - |

Methods 方法

通过模板 ref 调用组件方法:

| 方法名 | 说明 | 参数 | | ------ | ---------- | ---- | | focus | 使组件聚焦 | - | | blur | 使组件失焦 | - |

<template>
  <BkUserSelector
    ref="selectorRef"
    v-model="value"
    :api-base-url="apiBaseUrl"
  />
  <button @click="selectorRef?.focus()">聚焦</button>
  <button @click="selectorRef?.blur()">失焦</button>
</template>

<script setup>
  import { ref } from 'vue';
  const selectorRef = ref(null);
  const value = ref('');
  const apiBaseUrl = 'https://api.example.com';
</script>

类型定义

// 用户信息
interface UserInfo {
  id: string; // 用户 ID
  username: string; // 用户名
  display_name: string; // 显示名称
  logo?: string; // 头像 URL
  tenant_id?: string; // 租户 ID
  // ... 其他字段
}

// 用户组项
interface UserGroupItem {
  id: string; // 用户组 ID
  name: string; // 用户组名称
  hidden?: boolean; // 是否隐藏(不在下拉列表显示,但会在回显时展示)
}

// 自定义渲染函数
type RenderFunction = (
  h: CreateElement, // Vue createElement 函数
  userInfo: UserInfo, // 用户信息
) => VNode;

💡 功能说明

快速选择"我"

当设置了 currentUserId 属性后,组件会在输入框右侧显示一个"我"的标签:

  • 单选模式:点击"我"直接选中当前用户
  • 多选模式:点击"我"将当前用户添加到已选列表
  • 状态反馈:当前用户已被选中时,"我"标签显示为灰色且不可点击

用户组显示

当设置了 userGroup 属性后:

  • 用户组会显示在下拉列表的独立分组中(默认名称为"用户群组")
  • 用户组数据优先展示在列表顶部
  • 聚焦时会自动展示下拉框
  • 设置 hidden: true 的用户组不会在下拉列表中显示,但选中后会正常回显

多租户模式

通过 enableMultiTenantMode 控制:

  • 开启(默认):使用多租户用户管理接口查询,支持跨租户显示
  • 关闭:使用原有用户管理接口查询

多行输入模式(Textarea)

通过 type="textarea" 启用多行模式:

  • 完整展示:未聚焦时不折叠标签,完整展示所有已选用户
  • 高度可配:通过 rows 设置默认行数,每行约 32px
  • 可拖拽调整:默认允许拖拽调整容器高度,可通过 resize=false 禁用
  • 自动滚动:内容超出容器高度时自动出现滚动条
  • 聚焦同步:切换聚焦/失焦状态时自动同步容器高度

拖拽排序

在多选模式下启用 draggable

  • 支持拖拽调整已选用户的顺序
  • 拖拽时会有视觉反馈
  • 拖拽完成后会触发 change 事件

键盘导航

组件支持完整的键盘操作:

| 按键 | 功能 | | ----------- | --------------------------------------------------------- | | / | 在下拉列表中切换高亮选项 | | Enter | 选中当前高亮的选项(allowCreate=true 时创建自定义用户) | | / | 在已选标签之间移动光标 | | Backspace | 删除光标前的已选用户 |

  • 输入搜索内容后,第一个选项会自动高亮
  • 高亮选项会自动滚动到可视区域
  • 支持用户组、普通用户、虚拟账号的键盘选择

⚠️ 注意事项

  1. API 配置:使用前必须正确配置 apiBaseUrltenantId
  2. CSS 引入:记得引入对应版本的样式文件
  3. v-model 类型
    • 单选模式:v-model 应为 string 类型
    • 多选模式:v-model 应为 string[] 类型
  4. 跨租户显示:跨租户用户会在名称旁显示租户标识
  5. 自定义输入:启用 allowCreate 后,用户输入的内容会作为 id

❓ FAQ

Q: 组件没有样式怎么办?

A: 请确保引入了对应版本的 CSS 文件:

// Vue3
import '@blueking/bk-user-selector/vue3/vue3.css';

// Vue2
import '@blueking/bk-user-selector/vue2/vue2.css';

Q: 如何禁止选择某些用户?

A: 使用 excludeUserIds 属性传入需要排除的用户 ID 数组。

Q: 如何获取完整的用户信息?

A: 通过 change 事件获取,它会返回完整的用户信息对象,而不仅仅是 ID。

Q: 多选模式下如何限制选择数量?

A: 使用 maxCount 属性设置最大可选数量,0 表示不限制。

Q: 搜索没有结果怎么办?

A: 检查以下几点:

  1. apiBaseUrltenantId 是否正确配置
  2. 网络请求是否正常
  3. 搜索关键词是否匹配 exactSearchKey 配置的字段

🛠️ 开发

# 安装依赖
pnpm install

# 开发模式
pnpm run dev

# 构建
pnpm run build

# 类型检查
pnpm run type-check

📄 许可证

MIT © 蓝鲸智云