说在前面
使用vue框架开发的同学们,在开发过程中应该或多或少都会使用到自定义指令吧,大家平时都是怎么管理自己的vue指令的呢?每新建一个新项目就复制一份代码过去?试试来搭建一个vue指令库吧
vue指令有什么好处
Vue 指令是 Vue.js 框架提供的一种特殊属性,用于在 DOM 元素上添加交互行为和样式。使用 Vue 指令可以带来以下好处:
1. 与 DOM 分离
指令将 DOM 操作和交互逻辑与组件分离开来,提高了代码的可读性和可维护性。指令可以将复杂的 DOM 操作封装到一个简单的指令中,使组件代码更加简洁清晰。
2. 优化可重用性
指令可以被多个组件共享和重用,减少了重复编写相似代码的工作量。通过将常用的交互行为封装成指令,可以在不同的组件中快速应用,并且可以根据需要进行定制和扩展。
3. 提升开发效率
Vue 指令提供了一种声明式的方式来处理 DOM 操作和交互行为,使开发人员可以直观地理解和编写交互逻辑。相比手动操作 DOM,使用指令可以节省大量的开发时间和工作量。
4. 增强可维护性
通过将通用逻辑抽象成指令,可以减少重复代码的编写,降低代码量,提高代码的可维护性和可读性。
搭建步骤
要搭建一个 Vue 指令库并发布到 npm 上,可以按照以下步骤进行操作:
一、安装vue环境
已有的可以跳过
npm i vue -g
npm i vue-cli -g
二、创建一个vue项目
vue create .
文件目录如下图:
三、调整目录
1、packages
增加一个packages目录,用来存放我们的组件模块
2、examples
修改原来的src目录为examples,用于运行展示代码
四、文件调整
1、vue.config.js
修改项目入口
const path = require('path')
function resolve(dir) {
return path.join(__dirname, dir)
}
module.exports = {
// 修改 src 为 examples
pages: {
// lintOnSave: false,
index: {
entry: "examples/main.js",
template: "public/index.html",
filename: "index.html"
}
},
// 组件样式内联
css: {
extract: false
},
// 扩展 webpack 配置,使 packages 加入编译
chainWebpack: config => {
config.resolve.alias
.set('@', resolve('examples'))
.set('~', resolve('packages'))
}
};
五、将指令代码放到packages目录中
完整组件目录如下,指令文件我们放在directives目录下。
这里以一个3D旋转指令为例来给大家介绍一下:
package/directives/JRotate3D.js
指令逻辑代码编写
export default {
// 当被绑定的元素插入到 DOM 中时
inserted: function (el) {
let startX,
startY,
currentX = 0,
currentY = 0;
el.style.display = "inline-block";
el.style.cursor = "pointer";
// 绑定 mousedown 事件,在鼠标按下时开始拖拽
el.addEventListener("mousedown", function (event) {
event.preventDefault();
startX = event.pageX - currentX;
startY = event.pageY - currentY;
// 绑定 mousemove 事件,在鼠标移动时旋转元素
document.addEventListener("mousemove", onMouseMove);
// 绑定 mouseup 事件,在鼠标松开时结束拖拽
document.addEventListener("mouseup", onMouseUp);
});
// 针对手机端还需要绑定 touchstart,touchmove 和 touchend 事件
el.addEventListener("touchstart", function (event) {
event.preventDefault();
startX = event.touches[0].clientX - currentX;
startY = event.touches[0].clientY - currentY;
document.addEventListener("touchmove", onTouchMove);
document.addEventListener("touchend", onTouchEnd);
});
// 定义鼠标移动时的方法
function onMouseMove(event) {
event.preventDefault();
currentX = event.pageX - startX;
currentY = event.pageY - startY;
applyTransform(el);
}
// 定义鼠标松开时的方法
function onMouseUp() {
document.removeEventListener("mousemove", onMouseMove);
document.removeEventListener("mouseup", onMouseUp);
}
// 定义触摸移动时的方法
function onTouchMove(event) {
event.preventDefault();
currentX = event.touches[0].clientX - startX;
currentY = event.touches[0].clientY - startY;
applyTransform(el);
}
// 定义触摸结束时的方法
function onTouchEnd() {
document.removeEventListener("touchmove", onTouchMove);
document.removeEventListener("touchend", onTouchEnd);
}
// 应用 transform 属性以旋转元素
function applyTransform(el) {
el.style.transform = `rotateX(${currentY}deg) rotateY(${currentX}deg)`;
}
},
};
packages/index.js
// 使用 require.context 动态导入所有指令
const requireDirective = require.context(`./directives/`, false, /\.js$/);
// 定义 install 方法,接收 Vue 作为参数。
const install = function (Vue) {
if (install.installed) return;
requireDirective.keys().forEach((directiveFileName) => {
const moduleName = directiveFileName.replace(/^\.\/(.*)\.\w+$/, "$1");
const directiveConfig = requireDirective(directiveFileName);
Vue.directive(moduleName, directiveConfig.default);
});
};
// 判断是否是直接引入文件
if (typeof window !== "undefined" && window.Vue) {
install(window.Vue);
}
export default {
// 导出的对象必须具有 install,才能被 Vue.use() 方法安装
install,
// 以下是具体的组件列表
...components,
};
六、测试指令
main.js引入指令
import jvuewhell from './../packages/index'
// 注册指令库
Vue.use(jvuewhell)
在App.vue中使用指令
<img
v-JRotate3D
alt=""
src="https://gitee.com/jyeontostore/img-bed/raw/master/img/1699276911873.jpg"
/>
体验地址
七、上传到npm
测试通过了之后也就到了最后的一步,将我们的组件上传到npm库上去。
package.json信息填写
在script中加上打包命令:
"scripts": {
"lib": "vue-cli-service build --target lib --name jvuewhell --dest lib packages/index.js"
},
填写好基本信息
"name": "@jyeontu/jvuewhell",
"version": "0.1.0",
"author": "JYeontu",
"license": "MIT",
"description":"vue组件库封装",
"main": "lib/jvuewhell.umd.min.js",
"keyword": "vue components",
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint",
"lib": "vue-cli-service build --target lib --name jvuewhell --dest lib packages/index.js"
},
打包
npm run lib
设置.npmignore,只上传我们需要的文件
examples/
packages/
public/
node_modules/
dist/
登录npm
在cmd中输入命令 npm login(注意不要使用其他源)
npm login
需要先注册账号,没有的可以先去官网注册
发布
npm publish
因为我的name为'@jyeontu/jvuewhell',所以需要使用下面命令
npm publish --access public
发布成功之后就可以上自己的npm库里查看了。
源码
一、gitee
gitee 地址:gitee.com/zheng_yongt…
二、公众号
关注公众号『前端也能这么有趣』发送 组件库即可获取源码。
说在后面
🎉 这里是 JYeontu,现在是一名前端工程师,有空会刷刷算法题,平时喜欢打羽毛球 🏸 ,平时也喜欢写些东西,既为自己记录 📋,也希望可以对大家有那么一丢丢的帮助,写的不好望多多谅解 🙇,写错的地方望指出,定会认真改进 😊,偶尔也会在自己的公众号『前端也能这么有趣』发一些比较有趣的文章,有兴趣的也可以关注下。在此谢谢大家的支持,我们下文再见 🙌。