npm+vue-cli发布vue自定义组件
Posted cgd199158
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了npm+vue-cli发布vue自定义组件相关的知识,希望对你有一定的参考价值。
npm+vue-cli发布vue自定义组件
日常开发中,我们经常会封装一些组件,在多个项目切换组件的修改特别麻烦,我们可以把这些经常用到的组件发布到npm上面进行统一管理,这样可以大大提高我们的工作效率,甚至到后期可以自己封装一套属于自己的组件库;
- 使用vue-cli快速创建项目
components目录中创建自定义组件;下面以vue-cricleprogressbar组件为例CircleProgress.vue
<template> <div class="content" ref="box"> <svg :id="idStr" style="transform: rotate(-90deg)" : : xmlns="http://www.w3.org/2000/svg" > <linearGradient :id="`gradient-${id}`" gradientUnits="userSpaceOnUse"> <stop v-for="(item, index) in gradientsColor" :key="index" :offset="item.offset" :stop-color="item.color" /> </linearGradient> <circle :r="(width-radius)/2" :cy="width/2" :cx="width/2" :stroke- :stroke="backgroundColor" fill="none" /> <circle v-if="gradientsColorShow" ref="$bar" :r="(width-radius)/2" :cy="width/2" :cx="width/2" :stroke="gradientsColor ? `url(#gradient-${id})` : barColor" :stroke- :stroke-linecap="isRound ? \'round\' : \'square\'" :stroke-dasharray="(width-radius)*3.14" :stroke-dashoffset="dashoffsetValue" fill="none" /> </svg> <div class="center_text"> <p v-if="!$slots.default" class="title">{{progress}}%</p> <slot></slot> </div> </div> </template> <script> // import _ from "lodash"; export default { props: { widthPresent: { type: Number, default: 1 }, gradientsColor: { type: [Boolean, Array], default: false }, radius: { type: [Number, String], default: 20 }, // 进度条厚度 progress: { type: [Number, String], default: 20 }, // 进度条百分比 barColor: { type: String, default: "#1890ff" }, // 进度条颜色 backgroundColor: { type: String, default: "rgba(0,0,0,0.3)" }, // 背景颜色 isAnimation: { // 是否是动画效果 type: Boolean, default: true }, isRound: { // 是否是圆形画笔 type: Boolean, default: true }, id: { // 组件的id,多组件共存时使用 type: [String, Number], default: 1 }, duration: { // 整个动画时长 type: [String, Number], default: 1000 }, delay: { // 延迟多久执行 type: [String, Number], default: 200 }, timeFunction: { // 动画缓动函数 type: String, default: "cubic-bezier(0.99, 0.01, 0.22, 0.94)" } }, data() { return { width: 200, idStr: "", oldValue: 0 }; }, computed: { gradientsColorShow: function() { return true; }, dashoffsetValue: function() { const { isAnimation, width, radius, progress, oldValue } = this; return isAnimation ? ((width - radius) * 3.14 * (100 - oldValue)) / 100 : ((width - radius) * 3.14 * (100 - progress)) / 100; } }, watch: { id: function() { this.idStr = `circle_progress_keyframes_${this.id || 1}`; }, progress: function(newData, oldData) { if (newData !== oldData) { this.oldValue = oldData; this.setAnimation(); } } }, mounted() { this.idStr = `circle_progress_keyframes_${this.id || 1}`; let self = this; this.setCircleWidth(); this.setAnimation(); // 此处不能使用window.onresize window.addEventListener("resize", function() { self.setCircleWidth(); self.setAnimation(self); }); }, methods: { setCircleWidth() { const { widthPresent } = this; let box = this.$refs.box; let width = box.clientWidth * widthPresent; let height = box.clientHeight * widthPresent; let cW = width > height ? height : width; this.width = cW; }, setAnimation() { let self = this; if (self.isAnimation) { // 重复定义判断 if (document.getElementById(self.idStr)) { self.$refs.$bar.classList.remove(`circle_progress_bar${self.id}`); } this.$nextTick(() => { this.startAnimation(); }); } }, startAnimation() { // 生成动画样式文件 let style = document.createElement("style"); style.id = this.idStr; style.type = "text/css"; style.innerhtml = ` @keyframes circle_progress_keyframes_name_${this.id} { from {stroke-dashoffset: ${((this.width - this.radius) * 3.14 * (100 - this.oldValue)) / 100}px;} to {stroke-dashoffset: ${((this.width - this.radius) * 3.14 * (100 - this.progress)) / 100}px;}} .circle_progress_bar${ this.id } {animation: circle_progress_keyframes_name_${this.id} ${ this.duration }ms ${this.delay}ms ${this.timeFunction} forwards;}`; // 添加新样式文件 document.getElementsByTagName("head")[0].appendChild(style); // 往svg元素中添加动画class this.$refs.$bar.classList.add(`circle_progress_bar${this.id}`); } } }; </script> <style scoped> .content { height: 100%; display: flex; justify-content: center; align-items: center; } .center_text { position: absolute; color: #1890ff; font-size: 22px; font-weight: bold; } </style>
在创建src/index.js,这里提供两种方法
// 方法一,直接引入组件,无法全局注册 import CircleProgress from \'./components/CircleProgress.vue\'; export default CircleProgress; // 方法二,为组件提供install安装方法,供按需引入 import CircleProgress from \'./components/CircleProgress.vue\'; CircleProgress .install = function (Vue) { Vue.component(CircleProgress.name, CircleProgress ) } export default CircleProgress
配置package.json文件
{ "name": "vue-circleprogressbar", // 组件名称 "version": "1.2.2", // 组件版本号 "private": false, "main": "lib/vue-circleprogressbar.umd.min.js", // 组件入口,在scripts.package命令中生成 "scripts": { "serve": "vue-cli-service serve", "build": "vue-cli-service build", "lint": "vue-cli-service lint", "package": "vue-cli-service build --target lib --name vue-circleprogressbar --dest lib ./src/components/index.js", //创建lib文件夹,将打包好的组件导入文件夹中 }, "keywords": [], "author": [], "license": "MIT", "dependencies": {}, "devDependencies": {} }
到这里本地开发工作就基本完成了,下一步就是把本地组件推送到npm上面
- 首先需要在 npm 创建一个账号
- 在终端执行 npm login 输入你注册的 npm 的账号和密码
- 执行npm publish,如果没问题的话这里组件就成功上传到npm上面了
- 后面就可以像引入其他组件一样直接用npm install安装组件进行引入
不清楚的可以参考我写的vue-circleprogressbar组件源码: vue-circleProgress组件
以上是关于npm+vue-cli发布vue自定义组件的主要内容,如果未能解决你的问题,请参考以下文章