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 🙏

© 2024 – Pkg Stats / Ryan Hefner

@lirl-cn/v2c

v0.1.5

Published

基于 vue2 与 element UI 低仿 antd-pro-table 如果之前你用过 react 及 antd-pro-table,那么这个 vue 组件对你来说会很简单 v2c 内置了依赖了 element-ui 组件,即所有的 element UI 组件你都可以正常使用

Downloads

17

Readme

v2c

基于 vue2 与 element UI 低仿 antd-pro-table
如果之前你用过 react 及 antd-pro-table,那么这个 vue 组件对你来说会很简单
v2c 内置了依赖了 element-ui 组件,即所有的 element UI 组件你都可以正常使用

安装

npm install @lirl-cn/v2c
-------------------------
yarn add @lirl-cn/v2c

使用

main.ts

import CnV2C from "@lirl-cn/v2c";
import request from "@/utils/request"; // 你自己的request方法 (url, options) => ({data: any[], total: number, success?: boolean})
import "@lirl-cn/v2c/es/styles.css"; // 引入样式
Vue.use(CnV2C, {
  table: {
    // 挂载全局一些公共方法,可以避免每个页面使用时配置,全部非必传
    request: async (url, options) => {
      const response = await request({ url, ...options });
      if (response.code === 200) {
        return {
          data: response?.rows,
          total: response.total,
          success: true,
        };
      } else {
        return {
          data: [],
          total: 0,
        };
      }
    }, // 当定义了request后,cn-table可以直接仅传action字段,内部会调用该方法去获取数据
    current: {
      key: "page", // 项目里列表接口当前页参数名, 默认是current
      format: (current: number) => current - 1, // 是否要进行格式化,默认从1开始
    },
    pageSize: {
      key: "size", // 项目里列表接口页数参数名, 默认是pageSize
      // format: (pageSize: number) => pageSize - 1, // 同current,非必传
    },
    search: {
      dateRangeExtraPlacement: "start", // 表格搜索日期区间dateRangeExtra字段添加位置
      dateRangeExtra: ["begin", "end"], // 表格搜索日期区间额外拼接的字符串
      /**? 如:表格 dataIndex为Time, 以上配置将得到 beginTime: yyyy-mm-dd HH:mm:ss, endTime: yyyy-mm-dd HH:mm:ss */
    },
  },
});
如需修改主题色或其他定制样式,需要项目自身用了 scss
# miain.ts
- import '@lirl-cn/v2c/es/styles.css'; // 去除原样式
+ import '@/styles/element-variables.scss'; // 引入自己定义的样式文件
// @/styles/element-variables.scss

/* 改变主题色变量 */
$--color-primary: #21b28e;
// 支持的可修改变量名列表 https://github.com/ElemeFE/element/blob/dev/packages/theme-chalk/src/common/var.scss

// vite项目引入该文件
@import "@lirl-cn/v2c/packages/styles/index.scss";

// webpack项目引入该文件
@import "~@lirl-cn/v2c/packages/styles/index.webpack";

查看所有 scss 变量

核心组件

cn-form

属性

| 参数 | 说明 | 类型 | 默认值 | | -------------------- | --------------------------------------------------------------------------------- | ----------------------------------- | -------- | | data | 表单数据源 | FormDataType[] | - | | layout | 表单布局 | 'grid' | 'inline' | 'block' | 'grid' | | columns | 表单布局为'grid'时生效,列数 | number | 3 | | disabled | 是否禁用该表单内的所有组件。若设置为 true,则表单内组件上的 disabled 属性不再生效 | boolean | - | | hideRequiredAsterisk | 是否隐藏必填字段的标签旁边的红色星号 | boolean | false | | labelSuffix | 表单域标签的后缀 | string | - | | labelWidth | 表单域标签的宽度 | number | 120 |

FormDataType

| 参数 | 说明 | 类型 | 默认值 | | -------------- | ----------------------------------------- | ------------------------------------------------------ | ------ | | name | 表单唯一值,亦是返回数据的 key | string | - | | title | 显示文案 | string | - | | type | 表单类型 | FormItemType | - | | placeholder | placeholder | string | - | | formItemProps | 透传给表单域的 attrs | HTMLAttributes & any | - | | fieldItemProps | 透传给表单组件的 attrs | HTMLAttributes & any | - | | options | 选择性组件的数据源,如selectradio等 | { label: string, value: string, [k: string]: any }[] | - | | rules | 表单验证规则, element ui form rules | object | - |

FormItemType 内置的 form 组件类型
type FormItemType =
  | "switch"
  | "slider"
  | "datetime"
  | "datetimerange"
  | "date"
  | "dates"
  | "week"
  | "month"
  | "year"
  | "daterange"
  | "monthrange"
  | "tags-checkbox"
  | "tags-radio"
  | "select"
  | "radio"
  | "checkbox"
  | "cascader"
  | "transfer"
  | "color"
  | "rate"
  | "input"
  | "textarea"
  | "number"
  | "upload"
  | "custom";
// custom 为自定义form组件,需要传人slot `${name}CustomFormComponent`

方法

ref 获取

| 名称 | 说明 | 类型 | | -------------- | ------------------- | ------------------------------------ | | validateFields | 检验并获取所有值 | <T=any>(fields:string[]):T | | getFieldsValue | 获取所有值 | () => object | | getFieldValue | 基于 key 获取单个值 | (key:string) => any | | setFieldValue | 基于 key 设置单个值 | (key:string, value:any) => void | | setFieldsValue | 设置表单的值 | (fields:{[k:string]: any}) => void | | resetFields | 重置表单 | () => void |

插槽

如内置 form 组件不满足业务需求也可以自定义 form 组件,示例如下

<cn-form>
  <!-- `${name}CustomFormComponent` 格式必须是这样,自行绑定value值和change方法,不支持v-modal -->
  <template #customCustomFormComponent="{value, onChange}">
    <you-custom-component
      :value="value"
      @change="onChange"
    ></you-custom-component>
  </template>
  <template #customInputCustomFormComponent="{value, onChange}">
    <el-input :value="value" @input="onChange"></el-input>
  </template>
</cn-form>

额外的 FormItem 内容

<cn-form>
  <!-- `${name}FormExtra` 格式必须是这样 -->
  <template #selectFormExtra>
    <el-link to="/other-list">点击查看更多</el-link>
  </template>
</cn-form>

默认插槽

<cn-form>
  <!-- #default 可省略 -->
  <template #default>
    <div style="text-align: center;">
      <el-button @click="onCancel">取消</el-button>
      <el-button type="primary" @click="onSubmit">提交</el-button>
    </div>
  </template>
</cn-form>

cn-table

属性

import type { HTMLAttributes, StyleValue } from "vue/types/jsx";
import type { FormItemType } from "./cn-form";
import { ElementUIComponent } from "./component";

type ParamsType = {
  current: number; // 当前页
  pageSize: number; // 一页显示多少条
  [k: string]: any;
};
type ResponseDataType = {
  success?: boolean; // 是否成功
  data: any[]; // 数据源
  total: number; // 一共多少数据
};
type SearchType = {
  type?: "inline" | "grid" | "block"; // 搜索排列样式
  columns?: number; // 几列
  resetText?: string | false; // 重置文案
  searchText?: string | false; // 搜索文案
  rangeExtra?: [string, string]; // 区间选择额外增加的字段
  rangeExtraPlacement?: "start" | "end"; // 区间选择额外增加字段的位置
};
type StatusType = "success" | "error" | "default" | "processing" | "warning";
type ValueEnumType = {
  [k: string]: {
    text: string; // 文案
    status?: StatusType; // 状态
  };
};
type ColumnType = {
  dataIndex: string; // 表单唯一值,该列基于哪个字段显示,支持a.b.c但不建议
  title: string; // 单元格名称文案
  searchTitle?: string; // 搜索框显示的文案。若为空默认显示title
  searchStyle?: StyleValue; // 搜索框样式
  name?: string; //
  key?: string;
  searchName?: string; // 搜索时传参名称,若为空默认显示dataIndex
  status?: StatusType; // 状态
  valueType?: FormItemType; // 搜索框类型
  valueEnum?: ValueEnumType; // 枚举
  valueOptions?: { label?: string; value?: string; [k: string]: any }[]; // 选择性组件数据源
  fetchOptions?():
    | ValueEnumType
    | { label?: string; value?: string; [k: string]: any }[]
    | Promise<{ label?: string; value?: string; [k: string]: any }[]>
    | Promise<ValueEnumType>; // 方法的方式获取valueEnum | valueOptions
  formItemProps?: HTMLAttributes & any; // object 绑定给el-form-item的attrs
  fieldItemProps?: HTMLAttributes & any; // object 绑定给 表单组件 的attrs
  hideInTable?: boolean; // 在表格中隐藏
  hideInSearch?: boolean; // 在搜索中隐藏
  ellipsis?: boolean; // 超出隐藏
  width?: number; // 宽度
  scopedSlots?: { customRender?: string; [k: string]: any };
};
type PaginationType = {
  defaultPageSize?: number;
  pageSizeOptions?: number[];
};
type SelectedRowsResponse = {
  selectedRows: any[];
};
type ActionRefType = {
  onSearch: () => void; // 搜索
  onReset: () => void; // 重置
  onReload: () => void; // 重新加载
  getSearchParams<T = ParamsType>(): T; // 获取所以搜索参数
  setSearchFieldsValue<T = any>(fieldsValue: T): void; // 设置搜索参数
  getSelectedRows: () => SelectedRowsResponse; // 获取选择的数据
};

type RowSelectionType = {
  selectText?: string; // 已选中 文案
  itemText?: string; // 项 文案
  cancelSelectText?: string; // 取消选择 文案
  batchDeleteText?: string; // 批量删除文案
  batchDownloadText?: string; // 批量导出文案
  onBatchDelete?: (selectedRows: SelectedRowsResponse["selectedRows"]) => void; // 批量删除调用的方法
  onBatchDownload?: (
    selectedRows: SelectedRowsResponse["selectedRows"]
  ) => void; // 批量导出调用的方法
  onChange?: (selectedRows: SelectedRowsResponse["selectedRows"]) => void; // 当选择行变化时调用
};

type SettingType = "reload" | "fullScreen";
type othersTextEnumKeys = 'setting-reload' | 'setting-fullScreen' | 'table-index'

class CnTable extends ElementUIComponent {
  columns: ColumnType[]; // 表格列数据
  title?: string; // 表格标题
  resetText?: string;
  searchText?: string;
  openText?: string,
  closeText?: string,
  othersTextEnum?: {[k:string]: string},
  rowKey?: string; // 行唯一,需要选择时必传
  searchType?: SearchType["type"];
  searchColumns?: number;
  scroll?: { y?: string | number };
  action?: string; // 若在main.js中传人了request方式,内部会将action地址传入方法中获取数据,当前组件request权重高
  request?: (params: ParamsType) => ResponseDataType; // 获取数据的方法
  onloadAutoRequest?: boolean; // 是否自动加载
  showIndex?:
    | boolean
    | ((params: {
        index: number;
        current: number;
        pageSize: number;
        text: string | number;
      }) => string); // 显示序号
  method?: "GET" | "POST"; // action存在时有效,获取数据时调用方式
  pagination?: false | PaginationType; // 是否显示分页信息
  search?: false | SearchType;
  data?: any; // 调用接口额外的参数
  actionRef?: (node: ActionRefType) => void; // 获取表格的方法
  beforeSearchSubmit?<T = ParamsType>(params: ParamsType): T; // 获取数据前调用
  formatResponse?<T = any>(response: T): ResponseDataType; // 拿到数据后格式化调用
  catchFetchDataError?: (error: Error) => ResponseDataType | void; // 监听action方式的报错
  watchReset?: () => void; // 监听重置方法的调用
  loading?: boolean; // 是否加载中
  autoCalcWidth?: false | number; // 自动计算宽度
  rowSelection?: RowSelectionType;
  setting?: false | SettingType[];
}

示例

cn-form

表格生成

import { defineComponent, ref } from "vue";

export default defineComponent({
  setup() {
    const formRef = ref();
    const formDataSource = [
      // 输入框
      {
        title: "input",
        type: "input",
        name: "input",
      },
      // 下拉选
      {
        title: "select",
        type: "select",
        name: "select",
        options: [
          // 下拉列表
          {
            label: "2222",
            value: 2222,
          },
          {
            label: "3333",
            value: 3333,
          },
          {
            label: "4444",
            value: 4444,
          },
        ],
        rules: [{ required: true, message: "请输入邮箱地址" }],
      },
      // 单选
      {
        title: "radio",
        type: "radio",
        name: "radio",
        options: [
          {
            label: "2222",
            value: 2222,
          },
          {
            label: "3333",
            value: 3333,
          },
          {
            label: "4444",
            value: 4444,
          },
        ],
      },
      // 多选
      {
        title: "checkbox",
        type: "checkbox",
        name: "checkbox",
        options: [
          {
            label: "qqqqq",
            value: 2222,
          },
          {
            label: "wwwww",
            value: 3333,
          },
          {
            label: "eeeee",
            value: 4444,
          },
          {
            label: "eeeee1",
            value: 44441,
          },
          {
            label: "eeeee2",
            value: 44442,
          },
          {
            label: "eeeee3",
            value: 4444232,
          },
          {
            label: "eeeee33",
            value: 444423,
          },
        ],
      },
      // 日期
      {
        title: "date",
        type: "date",
        name: "date",
      },
      // 多选日期
      {
        title: "dates",
        type: "dates",
        name: "dates",
      },
      // 评分
      {
        title: "rate",
        type: "rate",
        name: "rate",
      },
      // 颜色
      {
        title: "color",
        type: "color",
        name: "color",
      },
      // 日期时间区间
      {
        title: "datetimerange",
        type: "datetimerange",
        name: "datetimerange",
      },
      // 日期时间
      {
        title: "datetime",
        type: "datetime",
        name: "datetime",
      },
      // 月份区间
      {
        title: "monthrange",
        type: "monthrange",
        name: "monthrange",
      },
      // 月份
      {
        title: "date-month",
        type: "datemonth",
        name: "date-month",
      },
      // 数字
      {
        title: "number",
        type: "number",
        name: "number",
        fieldItemProps: {
          // 数字输入框额外的参数
          step: 2,
          "step-strictly": true,
        },
      },
      // 开关
      {
        title: "switch",
        type: "switch",
        name: "switch",
      },
      // 滑块
      {
        title: "slider",
        type: "slider",
        name: "slider",
        fieldItemProps: {
          range: true,
        },
      },
      // 联级
      {
        title: "cascader",
        type: "cascader",
        name: "cascader",
        options: [
          {
            label: "qqqqq",
            value: 2222,
          },
          {
            label: "wwwww",
            value: 3333,
          },
          {
            label: "eeeee",
            value: 4444,
          },
        ],
      },
      // 穿梭框
      {
        title: "transfer",
        type: "transfer",
        name: "transfer",
        options: [
          {
            label: "qqqqq",
            key: 2222,
          },
          {
            label: "wwwww",
            key: 3333,
          },
          {
            label: "eeeee",
            key: 4444,
          },
        ],
        formItemProps: {
          style: { "grid-column": "span 2" },
        },
      },
      // 文本域
      {
        title: "textarea",
        type: "textarea",
        name: "textarea",
      },
      // 自定义
      {
        title: "custom",
        type: "custom",
        name: "custom",
        initialValue: "2222", // 默认值
        rules: [{ required: true, message: "请输入邮箱地址" }],
      },
      // 上传
      {
        title: "upload",
        type: "upload",
        name: "upload",
        fieldItemProps: {
          action: "",
        },
      },
    ];
    const onSubmit = async () => {
      // validateFields 检验表单并返回所有数据
      console.log(await formRef.value.validateFields());
    };
    return () => {
      return (
        <div>
          <el-divider>cn-form 生成表单</el-divider>
          <cn-form
            ref={formRef} // 获取form表单
            columns={3} // 3列显示
            data={formDataSource} // 数据源
            scopedSlots={{
              // slot 插槽
              // 自定义form组件 `${name}CustomFormComponent`
              customCustomFormComponent: ({ onChange, value }: any) => {
                return <el-input value={value} onInput={onChange}></el-input>;
              },
              // form-item 额外显示的内容 `${name}FormExtra`
              customFormExtra: () => {
                return "customFormExtra";
              },
            }}
          ></cn-form>
          <el-button onClick={onSubmit}>提交</el-button>
        </div>
      );
    };
  },
});

cn-table

表格生成

import { defineComponent, ref } from "vue";

export default defineComponent({
  setup() {
    const tableColumns = [
      {
        title: "姓名",
        dataIndex: "name",
        valueType: "select",
        valueOptions: [
          {
            label: "海洋",
            value: "海洋",
          },
          {
            label: "大陆",
            value: "大陆",
          },
        ],
      },
      {
        title: "民族",
        dataIndex: "id",
        hideInTable: true, // 在表格中隐藏
      },
      {
        title: "年龄",
        dataIndex: "id",
      },
      {
        title: "性别",
        dataIndex: "jump",
      },
      {
        title: "描述",
        dataIndex: "description",
        hideInSearch: true, // 在搜索条件中隐藏
      },
    ];
    // request 方法,必须返回 data和total success可选,为false代表失败
    const fetchData = async (data: {
      current: number;
      pageSize: number;
      [k: string]: any;
    }) => {
      console.log(data);
      if (data.current === 1) {
        return {
          success: true,
          data: Array(20)
            .fill({})
            .map((item, index) => ({
              ...item,
              name: index + "姓名",
              id: index,
            })),
          total: 37,
        };
      } else {
        return {
          success: true,
          data: Array(17)
            .fill({})
            .map((item, index) => ({
              ...item,
              name: index + "姓名",
              id: index + data.pageSize,
            })),
          total: 37,
        };
      }
    };
    return () => {
      return (
        <div>
          <el-divider>cn-table 生成表格</el-divider>
          <cn-table
            request={fetchData}
            columns={tableColumns}
            showIndex
            scopedSlots={{
              // 插槽
              headOperation: () => (
                // 表格操作
                <el-button size="small" type="warning">
                  新增
                </el-button>
              ),
            }}
            searchType="grid" // 搜索默认
            rowSelection={{
              onBatchDelete: (rows: any) => {
                console.log("onBatchDelete", rows);
              },
              onBatchDownload: (rows: any) => {
                console.log("onBatchDownload", rows);
              },
            }}
          ></cn-table>
        </div>
      );
    };
  },
});

特别鸣谢: element UIant design ProTable