0.0.89 • Published 8 months ago

slb_public_components v0.0.89

Weekly downloads
-
License
ISC
Repository
-
Last release
8 months ago

slb_public_components

介绍

Vue3 +ts+ELement-Plus 公用组件库

依赖的库有 vue3,ELement-Plus,windicss,wangeditor,请在系统中自行安装

配置文件(.env.xxxxx),依赖vite

需要在环境变量配置中配置以下字段

VITE_APP_CONFIG = {
    // 翻页器配置
    "page":{
        "current":1,
        "size":10
    },
    // 页码
    "pageSizes": [5,10, 20, 30, 40, 50],
    // 七牛云上传配置
    "qiniuyun":{
        // 图床地址
        "url":"https://xxx.xx.com",
        "token": {
             // 后端token校验请求头字段映射
            "requestTokenName":"token",
            // 前端获取本地token的请求头字段映射
            "getTokenName": "token"
        },
        // 获取七牛云上传token接口请求地址
        "reqUrl":"/xxxxx/xxxx/get",
        // 请求方法,默认为POST
        "method":"POST",
        // 请求参数
        "body":{},
        // 自定义请求头配置
        "headers":{
            "service":"/xxx/xx/get"
        }
    },
    // 是否滚动加载,不写就是正常分页
    "scrollRequest":{
        // 是否滚动加载
        "isScroll": false, 
        // 滚动加载获取list最后一条数据的翻页参数名称, 如果没有则使用page 的页码翻页
        "endParameterName": "id",
        // 后端接受最后一条数据的参数名称 
        "requestParameterName": "lastId"
    },
    // 分页组件位置
    'paginationPosition': '' // 'start' | 'center' | 'end'
    // 是否隐藏单页不显示分页
    "hideOnSinglePage": true,
    // 是否使用首页total作为总条数/因后端大数据量时每页返回totle也很耗时故配合增加此配置
    "isHomePageTotal": true,
    // PublicTable组件type为 money 时转换比例和保留位数
    "amountConversion": {
        "proportion": 100000, //结果为: 转换比例 1 / 100000 默认为1
        "toFixed": 3 // 保留位数 // 默认为2
    }
}

MergeFormTable 组件参数及用法

用于带有搜索和表格的页面,是 PublicTable 组件和 SearchForm 组件的包装组件

<MergeFormTable
    :table-data="tablData" // form搜索菜单的配置
    :form-data="formData"  // table表格的配置
    :call-back="getList"  // 获取列表的方法
    v-model="reqParams" // 必填,搜索栏绑定的mode
    :exportExcelApi="apixxx" // 选填,页面会多一个导出Excel的按钮,
    @exportExce="exportFn" // 导出Excel按钮的返回事件,返回值为exportExcelApi请求的结果
    @selectionChange="selectionChange" //表格多选:当选择项发生变化时会触发该事件
>
    <template #customBtn> // customBtn插槽插入到搜索栏下方的自定义内容
        <el-button type="primary" @click="$router.push('/system/version/add')">添加版本类型</el-button>
    </template>
     <template #exportExcelBtn> //与导出Excel按钮同级,用于添加按钮权限
        <el-button type="success">导出Excel</el-button>
    </template>
    <template #control="{ row }">
        <el-button 
            type="primary" 
            @click="$router.push({ path: '/system/version/add', query: { id: row.id } })"
        >
            编辑版本
        </el-button>
    </template>
</MergeFormTable>
//一般情况下可以搭配获取列表的hook一起使用,下方代码就能创建一个只有显示,搜索功能的表格页面
import { useGetList } from 'slb_public_components';

// 见下方SearchForm配置
const formData: ISearchFormConfig = [
   ...
];
// 见下方PublicTable配置,如果没有特殊显示需求只用配置config
// 其余配置也可以添加,但是会覆盖hook中默认的配置
const tableConfig: ItableDataConfigProps = {
    config: [
        ...
    ]
};
const getListParam = {
    requestFn:  getRecommendGoodsList // 获取列表的api
    tableConfig: tableConfig, //table的配置
    obtainField: 'records',//返回结果参数获取字段,默认"$$$data",获取后端返回全部数据
    immediately: false,//是否立即执行函数
    //自定义回调方法,常用于处理后端返回特殊数据
    //如果涉及多层级数据应当返回 { list: AnyObject[];total: number }
    resultProcessing(v:AnyObject){
        // 只有一层时,直接返回数组
        // return v.records

        // 指定数据列表和分页数据
        return {
            list: v.page.records,
            total: v.page.total
        };
    },
    // 翻页字段顺序不变依次为:当前页数,显示条目个数,总条目数 默认从环境变量VITE_APP_CONFIG读取
    page:{
        "current": 1,
        "size": 10,
        "total":0
    },
    /**
     * 请求参数初始值,通常用于设置时间搜索默认值
     * ```ts
     * // 列子:
     *  const example:ISearchFormConfig = {
            type: 'dateTime',
            prop: 'delivery',
            label: '发货时间',
            placeholder: ['发货开始时间', '发货结束时间'],
            config: ['deliveryStartTime', 'deliveryEndTime']
        };

        const { getList, queryParams, tableData } = useGetList({
            queryParamsAdditional:{
                deliveryStartTime:"2024-12-15 08:12:56",
                deliveryEndTime:"2024-12-15 08:12:56",
            }
        });
     * 
     * ```
     */
    queryParamsAdditional:{} 

};
/**获取列表hook,注意hook内部已进行onBeforeMount初始化请求过一次列表了,具体使用方法使用时查看useGetList()函数注释*/
const { getList, queryParams, tableData } = useGetList(getListParam);

使用 MergeFormTable 组件时是否使用 useGetList 这个 hook 看实际项目中的情况并不是必须的只是为了减少代码量 主要差别在于:

  1. 需要将 tableConfig 配置书写完整
  2. 需要自定义 queryParams 对象属性
  3. 需要自定义获取列表函数

PublicTable 组件参数及用法

    <PublicTable
        :tableData="tableData"
        @handlePageChange="handlePageChange" //点击分页回调
        @SelectionChange="SelectionChange" //表格多选结果回调
    >

        <template #name="{ row, column, $index }">
            <el-button>{{ row.name }}</el-button>
        </template>
    </PublicTable>
    const tableData:ItableDataProps = {
        loading: false, //加载动画
        attrs: {} // table 属性方法,
        defaultConfig: {
            //是否开启多选
            selection: true,
            //是否开启数字展示
            index: true 
            // 表头和内容都居中展示
            allAlignCenter: true; 
            // 自动计算表头宽度
            isAutoHeaderWidth: true; 
            // 返回值用来决定这一行的 CheckBox 是否可以勾选
            selectable: (row: AnyObject, index: number) => boolean; 
        },
        config: [
            {
                prop: 'name', //表格对应字段,如果type为slot时也是插槽名
                label: '日期', //表格对应字段中文描述
                width: '130', //表格单个格子宽度
                type: 'slot' // 插槽类型,在html标签中自定义样式
                ShowFn: () => false // 是否显示该列
            },
            {
                prop: 'status',
                label: '活动状态',
                type: 'switch', // 使用开关
                options: {
                    activeValue: 0, //自定义参数值 打开状态
                    inactiveValue: 1 //自定义参数值 关闭状态
                },
                //开关切换回调方法
                callBack(v: any) {
                    console.log(v);
                }
            },
            {
                prop: 'address',
                label: '地址',
                // 用于表格的回显
                formatter(val: any) {
                    return val.province + val.city + val.district + val.address;
                }
            },
            // 排序
            {
                type: 'money',
                prop: 'money',
                sort: {
                    method: (a, b) => a.money - b.money
                },
                label: '金额'
            },
            {
                prop: 'url',
                label: '图片',
                type: 'img' //使用图片
            },
            {
                prop: 'time',
                label: '开始时间',
                type: 'time' // 自动处理显示时间为YYYY-MM-DD HH:mm:ss
            },
            {
                prop: 'money',
                label: '现金',
                type: 'money' // 后端返回金额单位为分,处理数据为元进行显示
            },
            {
                prop: 'id',
                label: 'id', // 不做任何处理直接显示后端返回数据
            },
            // 多级表头
            {
                type: 'column',
                label: '伙人',
                children: [
                    {
                        label: '钱',
                        type: 'column',
                        children: [
                            {
                                prop: 'address',
                                label: '分',
                                type: 'slot'
                            },
                            {
                                prop: 'name',
                                label: '源'
                            },
                            {
                                type: 'column',
                                label: '金额',
                                children: [
                                    {
                                        type: 'img',
                                        prop: 'url',
                                        label: '开盘价'
                                    },
                                    {
                                        type: 'money',
                                        prop: 'money',
                                        label: '价'
                                    },
                                    {
                                        type: 'slot',
                                        prop: 'name',
                                        label: '源来的'
                                    }
                                ]
                            }
                        ]
                    },
                    {
                        prop: 'city',
                        label: '动态'
                    }

                ]
            }
        ],
        // 为table树形结构时才设置tree
        tree:{
                defaultExpandAll: true, // 是否默认展开
                treeProps: { children: 'children', hasChildren: 'hasChildren' }, // 字段设置
                lazy: false, // 是否异步展开子级
                rowKey:"id", // key的键
                load: ()=> {}, // 异步方法
        },
        page: {
            page_index: 1, //当前分页页码
            page_size: 10, //当前分页展示条数
            total: 0 //总数
        },
        //后端返回的数据
        data: []
    };

SearchForm 组件参数及用法

    <SearchForm :form-data="data" :v-model=defaultValue>

        <template #d>
            <el-button>{{ 11111 }}</el-button>
        </template>
    </SearchForm>
    // 表单mode用于请求的对象,这里面的默值对应dateTime中的config的字段名就行能实现默认时间
    const defaultValue = ref({createStartTime: '时间',createEndTime: '时间'}) 
    const data:ISearchFormConfig = [
        /** input输入框 */
        {
            prop: 'ab', //对应mode中字段
            label: '兴趣:', //表单label,标题
            type: 'ipt', //组件类型
            placeholder: '请输入兴趣',// 支持placeholder的el组件
            labelWidth:80 //label宽度
        },
        /** 条件显示 */
        {
            prop: 'abc',
            label: '兴趣:',
            type: 'ipt',
            placeholder: '请输入兴趣',
            labelWidth:80,
            showFn: (v: any) => {  // 条件显示这个组件v其实就是defaultValue
                return v.ab ? false : true
            }
        },
        /** 日期范围选择器 */
        // dateTime类型比较特殊
        // 1,如果后端接受的数据为一个字段时:数据格式['时间xx','时间xx']可以直接填入prop,此时prop就能直接使用,用于后端请求数据
        // 2,如果后端需要接受的参数是两个属性,就需要在config中填入两个属性名第一个是开始时间,第二个为结束时间,
        {
            prop: 'e',
            label: '日期:',
            type: 'dateTime',
            placeholder: ['开始日期', '结束日期'] //自定义placeholder
            config: ['createStartTime','createEndTime'] // 当需要将数组解析为两个字段时的参数
        },
        /** 日期选择器 */
        {
            prop: 'eqq',
            label: '日期:',
            type: 'date',
            placeholder: '选择日期'
        },
        /** 级连选择器 */
        {
            prop: 'eerr',
            label: '日期:',
            type: 'cascader',
            placeholder: '选择日期',
            cascaderData: treeData,
            cascaderOptions: {
                showAllLevels: false, //仅显示最后一级,false为显示
                multiple: false, //开启多选
                checkStrictly: true, //选择任意一级选项
                emitPath: false, //选择是否为数组格式
                value: "val", //自定义对象的某个属性值
                label: "name", //自定义对象的某个字段
                children: "chilieMenu" //自定义对象子级名称
            }
        },
        /** 下拉框用法一 */
        {
            prop: 'c',
            label: '选择:',
            type: 'select',
            placeholder: '请选择',
            /**下拉框参数,{自定义:自定义} 需要自己设置,需要添加到下面config与数组中保持一致 */
            options: [
                {
                    val: '1',
                    name: 'Option1'
                },
                {
                    val: '2',
                    name: 'Option2'
                },
                {
                    val: '3',
                    name: 'Option3'
                },
                {
                    val: '4',
                    name: 'Option4'
                }
            ],
            config: ['val', 'name']
        },
        /** 下拉框用法二 */
        {
            prop: 'c',
            label: '选择:',
            type: 'select',
            placeholder: '请选择',
            /** 返回一个异步函数  */
            options:async ()=>([]),
            /**下拉框参数,{自定义:自定义} 需要自己设置,需要添加到下面config与数组中保持一致 */
            config: ['val', 'name']
        },
        /** 级联选择器 */
        {
            type: 'cascader',
            prop: 'deliveryType3',
            label: '配送方式3',
            placeholder: '请选择配送方式',
            options: async ()=>([]) || [{id:123, name: '张三',children:[id:23, name: '张三',]}],
            cascaderOptions: {
                showAllLevels: true, // 输入框中是否显示选中值的完整路径
                multiple: true, // 开启多选
                checkStrictly: true, // 选择任意一级选项
                emitPath: true, // 选择是否为数组格式
                value: 'id', // 自定义对象的某个属性值
                label: 'name', // 自定义对象的某个字段
                children: 'children' // 自定义对象子级名称
            }
        },
        /**自定义组件 */
        {
            prop: 'd',
            label: 'xx'
            type: 'slot' // 为插槽时prop就是插槽名,可以自定义样式
        },
        //icon组件名称,可自定义(参考:https://element-plus.org/zh-CN/component/icon.html#icon-collection)
        {
            type: 'search',
            icon: 'Search',
            /** 参数值为整个f/orm表单输入值 */
            event: (v) => {
                console.log(v);
            }
        },
        {
            type: 'reset',
            icon: 'Refresh',
            event: (v) => {}
        }
    ];

SForm 组件参数及用法

<SForm ref="formRef" :options="options" label-width="100px" v-mode="formData">
    <template #slot>
        <el-button size="small" type="primary">上传</el-button>
    </template>
</SForm>
    // 组件配置
    Attributes: {
        options: [] //菜单配置必传
        allTextNullReplace: string // 默认为空字符串,当为text组件时值为空时,组件会自动将所有空值替换为空字符串,
        modelValue: []// form组件的mode,必传
        isDetails: false //是否在详情页展示为true时,可通过h插槽定义标题,f插槽定义底部按钮
        formWidth: 100% // 控制整个表单宽度
        resetSaveFormItemValue: false // 重置表单时是否保留mode的初始值,
        EliminateUnnecessaryParameter: false // 提交时是否剔除掉和options配置中prop无关的属性,为true只保留options中配置的prop属性
        isDeepCopy: false // 是否开启深拷贝,为true时,mode的初始值会进行深拷贝,防止mode被修改
        isDynamicChildren: false // // 是否根据modelValue改变时重新渲染子元素
        // 注意: el-from本身拥有的属性也可直接配置参考https://element-plus.gitee.io/zh-CN/component/form.html#form-attributes
    }
// 内置有默认的七牛云上传方法,如果项目里不是七牛云或者通过后端上传的请自定义方法
import { useQiniuUpload } from 'slb_public_components';
const formData = ref<AnyObject>({});
// 注意: 当涉及到动态修改配置时请使用ref或者计算属性
let options: ISFormConfig = [
    // 正常组件使用
  {
    type: 'input', // 组件根据element-plus组件去掉el
    label: '用户名', // lable名称
    prop: 'username', // 组件双向绑定的值,输入后在formData中获取值
    textNullReplace: '--' // text组件时候为空时的显示内容
    rules: [ // 校验方法
      { required: true, message: '用户名不能为空', trigger: 'blur' },
      { min: 2, max: 6, message: '用户名长度为2-6位', trigger: 'blur' },
    ],
    attrs: { // 这里可以配置element-plus中所有对应组件的Attributes
      clearable: true
    },
    showFn(val: any) { // 传入方法通过条件进行显隐
        return val.role ? false : true
    }
  },
  // select组件使用方法1
  {
    type: 'select',
    placeholder: '请选择',
    label: '职位',
    prop: 'role',
    attrs: {
      style: {
        width: '100%',
      },
    },
    rules: [
      { required: true, message: '职位不能为空', trigger: 'change' }
    ],
    childrenConfig: {
        type: 'option',
        props: {
            label: 'label',
            value: 'value';
        }
    }
    children: [
      {
        label: '经理',
        value: '1'
      },
      {
        label: '总裁',
        value: '2'
      },
      {
        label: 'CEO',
        value: '3'
      },
    ]
  },
  // select组件使用方法2
  {
    type: 'select',
    placeholder: '请选择',
    label: '职位',
    prop: 'role',
    attrs: {
      style: {
        width: '100%',
      },
    },
    rules: [
      { required: true, message: '职位不能为空', trigger: 'change' }
    ],
    children: [
      {
        type: 'option',
        label: '经理',
        value: '1'
      },
      {
        type: 'option',
        label: '总裁',
        value: '2'
      },
      {
        type: 'option',
        label: 'CEO',
        value: '3'
      },
    ]
  },
  // select组件使用方法3
   {
    type: 'select',
    placeholder: '请选择',
    label: '职位',
    prop: 'role',
    attrs: {
      style: {
        width: '100%',
      },
    },
    rules: [
      { required: true, message: '职位不能为空', trigger: 'change' }
    ],
    childrenConfig: {
        type: 'option',
        props: {
            label: 'label',
            value: 'value';
        }
    }
    children: async ()=>([]) //返回一个异步函数
  },
  // checkbox-group
  {
    type: 'checkbox-group',
    value: [],
    prop: 'like',
    label: '爱好',
    rules: [
      { required: true, message: '爱好不能为空', trigger: 'change' }
    ],
    children: [
      {
        type: 'checkbox',
        label: '篮球',
        value: '1',
      },
      {
        type: 'checkbox',
        label: '足球',
        value: '2',
      },
    ]
  },
  // radio-group
    {
        type: 'radio-group',
        prop: 'terminalType',
        label: '终端类型:',
        children: [
            {
                type: 'radio',
                value: 'ANDROID',
                label: '安卓'
            },
            {
                type: 'radio',
                value: 'IOS',
                label: '苹果'
            }
        ],
        rules: [{ required: true, message: '请选择终端类型', trigger: 'change' }]
    },
    // upload 自定义的uploadImage组件attrs配置见uploadImage组件
  {
    type: 'upload',
    label: '上传',
    prop: 'avatar',
    rules: [
      { required: true, message: '图片不能为空', trigger: 'change' }
    ],
    attrs: {
      ...
    },
    uploadFn: useQiniuUpload().qiniuUplaod // 上传图片组件必须传入上传方法
  },
  // 文字显示
  {
    type: 'text',
    label: '文字显示',
    prop: 'text',
  }
  // 富文本
  {
    type: 'editor',
    label: '富文本',
    prop: 'editor',
    attrs: { // 这里是设置包裹富文本盒子的样式,当前主要是为了处理有时富文本层级过高的问题,默认是99999
        boxStyle: {
            zIndex: 999
        },
    }
    uploadFn: useQiniuUpload().qiniuUplaod // 富文本组件必须传入上传方法
  }
  // 自定义组件,当使用特殊样式和该组件不支持的组件时使用插槽插入
  {
    type: 'slot',
    label: '自定义组件',
    prop: 'slot',
  }
]
// 通过ref 可以获取到表单的resetFields: 重置方法和validate()返回拷贝后的值: 校验方法然后进行后续操作
const formRef = ref<SFomInstance>();

ImageUpload 组件

<ImageUpload v-model="formData.url" :limit="1" :uploadFn: useQiniuUpload().qiniuUplaod ></ImageUpload>
// 内置有默认的七牛云上传方法,如果项目里不是七牛云或者通过后端上传的请自定义方法
import { useQiniuUpload } from 'slb_public_components'; 

// 组件配置
Attributes: {
    uploadFn: useQiniuUpload().qiniuUplaod; // 必传,或者自定义方法
    modelValue: xx; //接受上传图片返回的值,必传
    multiple: false; // 是否多选,也就是一次性选取多张同时上传
    limit: 1; //数量限制,当为0时只用作图片预览
    fileSize: 5; // 图片大小
    fileType: ['png', 'jpg', 'jpeg']; // 可接收的文件格式
    isShowTip: true; // 是否显示下方提示信息
    targetRatio: [1, 1]; // 上传图片的宽高比
}
// emit 事件
const emit = defineEmits({
    'update:modelValue': (v: string[] | string) => typeof v === 'string' || Array.isArray(v),
    'uploadSuccess': null,
    'removeIndex': (index: number) => typeof index === 'number'
});
0.0.84

10 months ago

0.0.85

10 months ago

0.0.86

9 months ago

0.0.87

9 months ago

0.0.88

8 months ago

0.0.89

8 months ago

0.0.80

11 months ago

0.0.81

11 months ago

0.0.82

11 months ago

0.0.83

10 months ago

0.0.73

1 year ago

0.0.74

12 months ago

0.0.75

12 months ago

0.0.76

12 months ago

0.0.77

12 months ago

0.0.78

12 months ago

0.0.79

12 months ago

0.0.70

1 year ago

0.0.71

1 year ago

0.0.72

1 year ago

0.0.62

1 year ago

0.0.63

1 year ago

0.0.64

1 year ago

0.0.65

1 year ago

0.0.66

1 year ago

0.0.67

1 year ago

0.0.68

1 year ago

0.0.69

1 year ago

0.0.60

1 year ago

0.0.61

1 year ago

0.0.59

1 year ago

0.0.54

1 year ago

0.0.55

1 year ago

0.0.56

1 year ago

0.0.57

1 year ago

0.0.58

1 year ago

0.0.40

1 year ago

0.0.41

1 year ago

0.0.42

1 year ago

0.0.43

1 year ago

0.0.44

1 year ago

0.0.45

1 year ago

0.0.46

1 year ago

0.0.47

1 year ago

0.0.37

1 year ago

0.0.38

1 year ago

0.0.39

1 year ago

0.0.35

1 year ago

0.0.36

1 year ago

0.0.51

1 year ago

0.0.52

1 year ago

0.0.53

1 year ago

0.0.50

1 year ago

0.0.48

1 year ago

0.0.49

1 year ago

0.0.33

2 years ago

0.0.30

2 years ago

0.0.31

2 years ago

0.0.32

2 years ago

0.0.29

2 years ago

0.0.20

2 years ago

0.0.21

2 years ago

0.0.22

2 years ago

0.0.23

2 years ago

0.0.24

2 years ago

0.0.25

2 years ago

0.0.16

2 years ago

0.0.17

2 years ago

0.0.18

2 years ago

0.0.19

2 years ago

0.0.26

2 years ago

0.0.27

2 years ago

0.0.28

2 years ago

0.0.15

2 years ago

0.0.14

2 years ago

0.0.13

2 years ago

0.0.12

2 years ago

0.0.11

2 years ago

0.0.10

2 years ago

0.0.9

2 years ago

0.0.8

2 years ago

0.0.7

2 years ago

0.0.6

2 years ago

0.0.5

2 years ago

0.0.4

2 years ago

0.0.3

2 years ago

0.0.2

2 years ago

0.0.1

2 years ago