汕头网站制作哪家好,443是端口网站建设,wordpress多站点 文章导入,网站推广的软件前言#xff1a;
最近在做公司项目中#xff0c;有这么一件事情#xff0c;很是头疼#xff0c;就是同一套代码#xff0c;不同项目#xff0c;要改相同bug#xff0c;改好多遍#xff0c;改的都想吐#xff0c;于是就想做一个组件库#xff0c;这样更新一下就全都可…前言
最近在做公司项目中有这么一件事情很是头疼就是同一套代码不同项目要改相同bug改好多遍改的都想吐于是就想做一个组件库这样更新一下就全都可以了当然也是第一次主导组件库的搭建有哪些不对的还请各位大佬指出来哈。
准备
1、node(18)
2、Verdaccio 是一个Node.js创建的轻量的私有npm proxy registry可以直接在你本地起一个私有库
npm i verdaccio -g启动verdaccio就会出现下面的页面
可以直接创建一个用户
npm adduser --registry http://localhost:4873/会让你输入用户名和密码这个要记好哈后面上传的时候要用到
开始
看到网上大佬们用的是Monorepo方式那咱们也用这种方式虽然不太懂为啥要这样总之随主流指定出错少哈哈 创建文件夹 mkdir?Monorepo?
# 初始化文件
pnpm init在此目录下面创建.npmrc # 和npm一样将别的包的依赖都放在node_modules下不加的话会放在.pnpm下
shamefully-hoist true新建pnpm-workspace.yaml文件 packages: # 将所有的项目都放到这里 - ‘packages/*’ # 示例 - ‘examples’
4.创建文件目录 packages、examples
packages – 将所有组件放到这里
examples – 测试组件
packages文件目录里面的所有文件夹都要进行初始化 pnpm init 5、进入到components里面一定要安装相应的依赖呀
?npm i vue typescript sass element-plus?decimal.js?element-plus/icons-vue ?-D -w-D 就不用介绍了
-w 是安装在根目录下
6、配置tsconfig.json文件
{compilerOptions: {allowJs: true, //允许编译器编译JSJSX文件target: ES2015, //指定ECMAScript目标版本useDefineForClassFields: true,module: ESNext, //设置程序的模块系统moduleResolution: Node, //模块解析策略。默认使用node的模块解析策略strict: true, //启用所有严格类型检查选项jsx: preserve, //preserve模式,在preserve模式下生成代码中会保留JSX以供后续的转换操作使用sourceMap: true, //生成目标文件的sourceMap文件resolveJsonModule: true, //允许导入扩展名为“.json”的模块esModuleInterop: false, //允许module.exportsxxx 导出由import from 导入.因为很多老的js库使用了commonjs的导出方式并且没有导出default属性lib: [ //TS需要引用的库ESNext,DOM],forceConsistentCasingInFileNames: true, //禁止对同一个文件的不一致的引用allowSyntheticDefaultImports: true, //允许从没有设置默认导出的模块中默认导入skipLibCheck: true, //忽略所有的声明文件 *.d.ts的类型检查baseUrl: ./, // 解析非相对模块的基地址默认是当前目录paths: { //模块名到基于 baseUrl的路径映射的列表//*: [src/*],},types: [ //要包含的类型声明文件名列表vite/client,element-plus/global,]},include: [ //包含的文件src/**/*.ts,src/**/*.d.ts,src/**/*.tsx,src/**/*.js,src/**/*.jsx,src/**/*.vue,]
}7、初始化 examples 文件夹
1、初始化
pnpm init2、安装 vite 和 vitejs/plugin-vue
pnpm vite vitejs/plugin-vue -D -w3.新建vite.config.ts 并配置 import { defineConfig } from vite
import vue from vitejs/plugin-vue
export default defineConfig({plugins:[vue()]
})4、新建index.html
!DOCTYPE html
html langenheadmeta charsetUTF-8 /meta http-equivX-UA-Compatible contentIEedge /meta nameviewport contentwidthdevice-width, initial-scale1.0 /titleDocument/title/headbodydiv idapp/divscript srcmain.ts typemodule/script/body
/html注意 vite 是基于 esmodule 的 所以 typemodule
vitejs/plugin-vue 会默认加载 examples 下的 index.html5、新建app.vuetemplatedivapp/div
/templatescript setup langts
/scriptstyle scoped
/style6、新建main.tsimport {createApp} from vue
import App from ./app.vue
const app createApp(App)
app.mount(#app)7、因为直接引入.vue 文件 TS 会找不到对应的类型声明所以需要新建 typings命名没有明确规定TS 会自动寻找.d.ts 文件文件夹来专门放这些声明文件。declare module *.vue {import type { DefineComponent } from vue;const component:DefineComponent{},{},any
}8、在package.json 文件中配置 scripts 脚本scripts: {dev: vite},
9.pnpm run dev 启动项目8、初始化packages/components 文件夹
components 文件夹1.目录结构
-- components-- src-- index.ts-- input-number-- inputNumber.vue-- index.ts
-- index.ts
-- package.json2.inputNumber.vue 如下代码3.input-number/index.tsimport InputNumber from ./inputNumber.vue
InputNumber.install (app) {app.component(InputNumber.name, InputNumber)
}
export default InputNumber4.components/index.ts
import InputNumber from ./src/input-number/inputNumber.vue;
// 将所有的组件都放到这里进行导出
const components [InputNumber
]
// 定义install方法const install (app) {// 之策所有组件components.forEach(item {app.component(item.name, item)})
}const DHSUI {install
}// 支持按需引入
export {InputNumber
}// 导出install方法
export default DHSUI以input框为例
src/input-number/inputNumber.vue
templateel-input v-modelinputValue classcustomInput v-bind$attrs :maxlengthprops.maxlength inputhandleInputtemplate #suffixspan classiconBtn add clickaddel-iconArrowUp //el-icon/spanspan classiconBtn decrease clickdecreaseel-iconArrowDown //el-icon/span/templatetemplate v-ifprops.isAppend #append{{ props.appendText }}/template/el-input
/template
script langtsexport default {name: InputNumber
}
/script
script setup langtsimport { ElInput, ElIcon } from element-plusimport element-plus/dist/index.cssimport {ArrowUp, ArrowDown } from element-plus/icons-vueimport { Decimal } from decimal.js;import { onlyNumOnePoint, canBeMinus } from dhs-ui/utils;
import { ref, watch } from vue;// 根据最长字符生成最大值
const generateMaxString (maxLength: any) {const maxValue 9.repeat(maxLength as unknown as number);return maxValue;
};
interface Props {modelValue: string;isAppend?: boolean;appendText?: string;min?: number;max?: number;step?: number;maxlength?: number | string;precision?: number;
}
const props withDefaults(definePropsProps(), {modelValue: ,precision: 4,isAppend: false
});
const emits defineEmits([input, update:modelValue]);
const inputValue ref(props.modelValue);
const add () {const step props.step || 1;let val inputValue.value;if (!val) {val 0;}let decimalVal new Decimal(val);if (maxNum() new Decimal(maxNum()) decimalVal) {inputValue.value decimalVal.toFixed();} else {inputValue.value decimalVal.plus(step).toFixed();}
};
const decrease () {const step props.step || 1;let val inputValue.value;if (!val parseFloat(val) ! 0) val 0;if (props.min || props.min 0) {if (parseFloat(val) props.min) {val props.min.toFixed();inputValue.value val;return;}}let decimalVal new Decimal(val);inputValue.value decimalVal.sub(step).toFixed();
};
// number 小数点位数
const vilidateNumberInput (value: any, number: number) {let result: any;if (props.min || props.min 0) {result onlyNumOnePoint(value, number, !!number);} else {result canBeMinus(value, number);}return result;
};const maxNum () {if (props.max) {return props.max.toFixed();} else {return props.maxlength ? generateMaxString(props.maxlength) : null;}
};
watch(() props.modelValue,( newValue: any) {inputValue.value newValue;},{ deep: true }
);
watch(inputValue, (nv: any) {emits(update:modelValue, nv);
});
const handleInput (val: any) {inputValue.value vilidateNumberInput(val, props.precision);emits(input, val);
};
/scriptstyle scoped langscss
.customInput {.iconBtn {position: absolute;right: 1px;display: block;width: 32px;background-color: #f5f7fa;border-left: 1px solid var(--default-border-color);height: 15px;line-height: 15px;cursor: pointer;}.add {top: 1px;border-radius: 0 4px 0 0;}.decrease {border-top: 1px solid var(--default-border-color);bottom: 1px;border-radius: 0 0 4px 0;}.is-disabled {.add,.decrease {pointer-events: none;}}
}
/style9、在examples/app.vue测试组件
templatedivInputNumber :modelValueinputValue //div
/templatescript setup langts
import { ref } from vue;
import {InputNumber} from ../packages/components/src/input-number/inputNumber.vue;const inputValue ref(0)
/scriptstyle scoped/style出现了你所要的组件就说明可以进行打包了。
10、在components文件夹中打包组件
components 文件夹 新建vite.config.ts 这里我们选择打包cjs(CommonJS)和esm(ESModule)两种形式,cjs模式主要用于服务端引用(ssr),而esm就是我们现在经常使用的方式它本身自带treeShaking而不需要额外配置按需引入(前提是你将模块分别导出)非常好用~
为了也能在ts项目中使用还需要自动生成类型声明文件
pnpm add vite-plugin-dts1.4.1 -D -wimport { defineConfig } from vite;
import vue from vitejs/plugin-vue;
import dts from vite-plugin-dts;
export default defineConfig({build: {//打包文件目录outDir: es,//压缩//minify: false,rollupOptions: {//忽略打包的文件external: [vue, element-plus],input: [index.ts],output: [{//打包格式format: es,//打包后文件名entryFileNames: [name].mjs,//让打包目录和我们目录对应preserveModules: false,exports: named,//配置打包根目录dir: ../DHS-UI/es,},{//打包格式format: cjs,//打包后文件名entryFileNames: [name].js,//让打包目录和我们目录对应preserveModules: false,exports: named,//配置打包根目录dir: ../DHS-UI/lib,},],},lib: {entry: ./index.ts,},},plugins: [vue(),dts({entryRoot: ./src,outputDir: [../DHS-UI/es/src, ../DHS-UI/lib/src],//指定使用的tsconfig.json为我们整个项目根目录下,如果不配置,你也可以在components下新建tsconfig.jsontsConfigFilePath: ../../tsconfig.json,}),],
});配置同目录下的package.json文件
scripts: {build: vite build},11、运行 build 进行打包会在目录中生成打包好的包 11、打包好的文件进行初始化
pnpm init修改package.json 文件
{name: dhs-uii,version: 1.0.2,description: ,main: lib/index.js,module: es/index.mjs,files: [es,lib],scripts: {test: echo Error: no test specified exit 1},sideEffects: [**/*.css],keywords: [dhs-ui,vue3组件库,frontend,element-plus],author: dengdeng,license: ISC,typings: lib/index.d.ts
}下一章进行发布及遇到的问题。
感谢大佬文章搭建一个组件库vue3_vue3组件库搭建-CSDN博客