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 🙏

© 2025 – Pkg Stats / Ryan Hefner

dc-vue-web-base

v1.1.9

Published

dckj base

Downloads

1

Readme

东臣 Web 端基础框架

Vite + Vue3 + TypeScript + Pinia

版本命名规范

  • 版本需要发布到私仓 npm publish

规范说明

  1. 文件命名规则
    • Vue 文件采用驼峰大写命名,例如:HelloWorld.vue
    • js/ts 文件采用小写命名,例如:hello-world.js
    • assets/images下的图片文件,采用小写中划线格式,例如:hello-world.png
  2. 目录分包规则
    • src/view下的目录按照业务模块来进行划分,例如:system/uesr
    • 增改查分包分别使用Add.vueUpdate.vueDetail.vue, 审批、生成使用Approval.vueGenerate.vue
      例如:system/uesr目录:
      • Manage.vue 表示管理页,一般是表格的页面
      • Add.vue 表示新增用户
      • Update.vue 表示修改用户(可以和新增合并)
      • Detail.vue 表示查看用户详情用户
  3. 路由说明
    • 路由的可以不写name,path必写,对应菜单的菜单地址:linkUrl字段,path建议带上前缀,例如:/account/user/system/menu

使用技术

(推荐使用pnpm进行包管理)
npm install -g pnpm

  • Vite2
  • Vue3
  • TypeScript
  • Pinia
  • VueRouter
  • Eslint
  • Ant Design Vue

框架说明

网络请求

默认写法

import { PostRequestModel, GetRequestModel, PutRequestModel, DeleteRequestModel } from '@/utils/model/request-model'
import { PageModel } from '@/utils/model/result-model'
import { defaultConfig } from '@/http/json-config'
import { FactorVo } from '@/entity/eess/FactorVo'
import { FactorMapVo } from '@/entity/eess/FactorMapVo'

// 当前模块通用请求前缀
const MODULE_API_PREFIX = '/system/factor'

export default {
	page: (query?: {}) => new PostRequestModel<PageModel<FactorVo>>(`${MODULE_API_PREFIX}/page`, query).request(),
	getById: (id: string) => new GetRequestModel<FactorVo>(`${MODULE_API_PREFIX}/${id}`, {}).request(),
	add: (data: {}) => new PostRequestModel<FactorVo>(`${MODULE_API_PREFIX}/`, data).request(),
	update: (id: string, data: {}) => new PutRequestModel<FactorVo>(`${MODULE_API_PREFIX}/${id}`, data).request(),
	delete: (id: string) => new DeleteRequestModel<boolean>(`${MODULE_API_PREFIX}/${id}`, {}).request()
}

修改配置(配置需要继承已有的配置信息)

import { PostRequestModel, GetRequestModel, PutRequestModel, DeleteRequestModel } from '@/utils/model/request-model'
import { PageModel } from '@/utils/model/result-model'
import { defaultConfig } from '@/http/json-config'
import { FactorVo } from '@/entity/eess/FactorVo'
import { FactorMapVo } from '@/entity/eess/FactorMapVo'
import { getDefaultConfig } from '@/http/config/custom-config'

// 当前模块通用请求前缀
const MODULE_API_PREFIX = '/system/factor'

const defaultConfig = getDefaultConfig<any>()
// 修改配置中的值
// defaultConfig。。。

export default {
	page: (query?: {}) => new PostRequestModel<PageModel<FactorVo>>(`${MODULE_API_PREFIX}/page`, query, defaultConfig).request(),
	add: (data: {}) => new PostRequestModel<FactorVo>(`${MODULE_API_PREFIX}/`, data, defaultConfig).request()
}

目录结构

使用tree命令生成

├─api                       所有的接口api
│  ├─account                用户管理模块
│  ├─dynamic                动态表单模块
│  ├─login                  登录模块
│  ├─system                 系统模块
│  └─system-log             系统日志模块
├─assets                    资源文件
│  ├─images                 图片资源
│  │  ├─index               首页的资源文件
│  │  └─login               登录模块的资源文件
│  └─scss                   通用的css部分
├─components                组件
│  ├─form                   表单组件的公共方法
│  ├─form-item              表单的item
│  │  └─props               item的属性
│  ├─rich-text              富文本
│  └─table                  表格
│      └─components         表格的组件部分
├─entity                    实体类
│  ├─account                用户管理模块
│  ├─common                 公告的实体类
│  ├─dynamic                动态表单模块
│  ├─login                  登录模块
│  ├─system                 系统模块
│  └─system-log             系统日志模块
├─http                      网络请求工具类
│  └─config                 请求的配置
├─router                    路由信息
│  └─modules                路由配置
├─store                     缓存
├─utils                     工具类
└─views                     视图
    ├─account               用户管理模块
    │  ├─department         部门管理
    │  ├─information        个人信息
    │  ├─organization       单位管理
    │  ├─role               角色管理
    │  │  └─components
    │  └─user               用户管理
    ├─dynamic               动态表单
    │  └─table              表格
    │      ├─table-columns
    │      └─table-record
    ├─exception             意外的界面,403/404/500
    ├─index                 首页
    │  └─components
    ├─login                 登录页面
    │  └─components
    ├─system                系统界面
    │  ├─dictionary         数据字典
    │  ├─dictionary-type    数据字典类型
    │  ├─menu               菜单
    │  ├─message            消息
    │  └─parameter          系统参数
    └─system-log            系统日志
        ├─backup            系统备份日志
        ├─backup-file       备份文件日志
        ├─file-upload       文件上传日志
        ├─login             登录日志
        ├─message           短信发送日志
        ├─operation         操作日志
        └─version           版本日志

常见问题

  1. 使用 BaseFormItem,文件上传校验问题,已经上传了还是提示不能为空。
    设置校验触发时机为trigger: 'blur'

  2. 使用 BaseFormItem,比如使用选择框,我即想要label又想要value,我要怎么写?
    推荐使用update:extraValue方法进行实现, 可以使用extraNames指定返回字段

    <template>
        <base-form-item v-for="item of fields" :key="item.name" v-model:value="formState[item.name]" v-bind="item" @update:extraValue="extraValueChange" />
    </template>
      
    <script setup lang="ts">
    import fields from '/src/views/index/fields'
    import { reactive } from 'vue'
    import BaseFormItem from 'src/views/components/form-item/BaseFormItem.vue'
    import { ExtraProps } from '/src/components/form-item/field-props'
    import { BaseFormDTO } from '/src/entity/common/base'
      
    const formState = reactive<BaseFormDTO>({})
      
    function extraValueChange(name: string, extra: ExtraProps) {
        // 需要注意的是赋值以后和 onFinish 里面拿不到这个赋值, 两个不是一个对象
      
        // 这样赋值
        Object.assign(formState, extra)
      
        // 这样赋值,返回的key可以使用extraNames
        Object.keys(extra).forEach(key => {
            formState[key] = extra[key]
        })
      
        // 或者通过 name 找到, 然后手动赋值
        // fields.find(value => value.name == name)
        if (name == 'upload-images') {
            //  手动进行操作或者判断
        }
      
        console.log(extra)
    }
    </script>
  3. 使用 BaseFormItem,如何设置自动完成(AutoComplete)/下拉项(Select)/级联项(Cascader)/自动完成(AutoComplete)值?
    首先,需要对fields设置可观察(ref/reactive,例如:

    // 先设置可观察,否则界面不会及时更新
    const fieldList = reactive(fields)
    // 当界面挂载后进行数据处理
    onMounted(async () => {
        // 通过name字段进行查找,这个比较健壮一点,对typeValue没填时进行了处理
        const find = fieldList.find((value: FieldProps) => value.name == 'select')
        if (find) {
            const typeValue = find?.typeValue as SelectProps
            const { data } = await requestMethod.getListRootCode('building_trade_tag')
            if (typeValue) typeValue.options = data
            // fieldNames 用来指定label和value对应的字段名称
            else find.typeValue = { options: data, fieldNames: { label: 'name', value: 'id', children: 'children' } }
        }
       
        // 如果你在`fields`中给`select`设置了`typeValue`,那么这里可以更简单点,使用这段的前提是在`fields`中给`select`设置了`typeValue`
        const typeValue = fieldList.find((value: FieldProps) => value.name == 'select')?.typeValue as SelectProps
        if (typeValue) {
            const { data } = await requestMethod.getListRootCode('building_trade_tag')
            typeValue.options = data
        }
    })
  4. 使用 BaseFormItem,怎么设置文件上传默认值?
    (参考第 3 点)

    // 先设置可观察,否则界面不会及时更新
    onMounted(async () => {
        if (!props.id) return
      
        const typeValue = fieldList.find((value: FieldProps) => value.name == 'upload')?.typeValue as UploadProps
        if (typeValue && props.id) {
            const { data } = await requestMehod.getById(props.id)
            typeValue.fileList = [{ id: data.imageId, uploadPath: data.imageUrl, oldFileName: '可填' }]
        }
    })
  5. Api 请求,怎么设置application/x-www-form-urlencoded

     update: (data: QueryType) => {
        const defaultConfig = getDefaultConfig<AccountUser>()
        defaultConfig.contentType = 'application/x-www-form-urlencoded'
        return new PutRequestModel<AccountUser>('/accountUser/updateMyPass', data, defaultConfig).request()
    }