当前位置: 首页 > news >正文

vue2企业级项目(六)

vue2企业级项目(六)

自定义指令

  1. 创建src/directive/index.js

    const directives = require.context("./modules", true, /\.js$/);export default {install: (Vue) => {directives.keys().forEach((key) => {let directive = directives(key).default;let name = key.replace(/^\.\/(.*)\.\w+$/, "$1");directive && Vue.directive(name, directive);});},
    };
  2. main.js注入使用

    import directives from "./directive";...Vue.use(directives);
    
  3. 创建src/directive/modules目录

1、v-loading

element-ui有,就不需要

2、v-draggable

创建src/directive/draggable.js

import { checkDataType } from "@/utils/utils";
let recoverStyle = null;export default {update(el, binding) {let config = binding.value;let visible = false;let target = ".el-dialog__header";let control = ".el-dialog";if (checkDataType(config, "object")) {visible = config.visible;target = config.target;control = config.control;} else {visible = config;}const dialogHeaderEl = el.querySelector(target);const dragDom = el.querySelector(control);dialogHeaderEl.style.cursor = "move";function readStyle(dom, attr) {if (document.body.currentStyle) return dom.currentStyle[attr];return getComputedStyle(dom, false)[attr];}if (visible) {recoverStyle = {left: readStyle(dragDom, "left"),top: readStyle(dragDom, "top"),margin: readStyle(dragDom, "margin"),};dialogHeaderEl.onmousedown = function(e) {// 获取鼠标相对当前元素内部位置const disX = e.clientX - dragDom.offsetLeft;const disY = e.clientY - dragDom.offsetTop;// 获取当前窗口视图大小const screenWidth = document.body.clientWidth;const screenHeight = document.documentElement.clientHeight;// 获取当前元素大小const dragDomWidth = dragDom.offsetWidth;const dragDomheight = dragDom.offsetHeight;// 计算获取最大偏移量const maxLeft = screenWidth - dragDomWidth;const maxTop = screenHeight - dragDomheight;document.onmousemove = function(e) {let left = e.clientX - disX;let top = e.clientY - disY;// 碰撞判断if (left <= 0) left = 0;if (left >= maxLeft) left = maxLeft;if (top <= 0) top = 0;if (top >= maxTop) top = maxTop;left = ((left * 100) / screenWidth).toFixed(2) + "%";top = ((top * 100) / screenHeight).toFixed(2) + "%";dragDom.style.left = left;dragDom.style.top = top;dragDom.style.margin = 0;};document.onmouseup = function() {document.onmousemove = null;document.onmouseup = null;};};} else {// 还原初始化的样式dragDom.style.left = recoverStyle.left;dragDom.style.top = recoverStyle.top;dragDom.style.margin = recoverStyle.margin;dialogHeaderEl.onmousedown = null;recoverStyle = null;}},
};

3、v-click-outside

创建src/directive/click-outside.js

export default {bind(el, binding) {// 点击事件回调函数const onClickOutside = (event) => {if (!(el === event.target || el.contains(event.target))) {binding.value(event);}};// 将回调函数绑定到元素上el._clickOutsideCallback = onClickOutside;// 添加点击事件监听器document.addEventListener("click", onClickOutside);},unbind(el) {// 移除点击事件监听器document.removeEventListener("click", el._clickOutsideCallback);delete el._clickOutsideCallback;},
};

4、v-ripple(简单的)

创建src/directive/ripple.js

function createRipple(el, radius, color, disX, disY) {new Promise((resolve) => {const rippleDom = document.createElement("span");rippleDom.className = "ripple";rippleDom.setAttribute("style",`display: block;position: absolute;border-radius: 50%;transform: translate(-50%, -50%) scale(0);transition: 0.5s;background-color: ${color || "rgba(0, 0, 0, 0.6)"};top: ${disY}px;left: ${disX}px;width: ${radius * 3}px;height: ${radius * 3}px;animation: ripple-animation 0.5s linear;`,);el.appendChild(rippleDom);let timer = setTimeout(() => {el.removeChild(rippleDom);resolve(timer);}, 520);}).then((timer) => {clearTimeout(timer);});
}function rippleShow(e) {const targetDom = e.target;const radius =targetDom.offsetHeight > targetDom.offsetWidth? targetDom.offsetHeight: targetDom.offsetWidth;const disX = e.clientX - targetDom.offsetLeft;const disY = e.clientY - targetDom.offsetTop;createRipple(targetDom, radius, e?._ripple, disX, disY);
}export default {bind(el, binding) {el._ripple = binding.value;el.style.position = "relative";el.style.overflow = "hidden";el.style.userSelect = "none";el.addEventListener("mousedown", rippleShow);},unbind(el) {el._ripple = null;el.removeEventListener("mousedown", rippleShow);},
};

创建src/styles/animation.less,并在scr/styles/index.less内引入

// ripple动画
@keyframes ripple-animation {to {transform: translate(-50%, -50%) scale(1);opacity: 0;}
}

5、v-intersect

交叉观察者

创建src/directive/intersect.js

export default {bind(el, binding) {let info = null;let callback = null;if (typeof binding.value === "object") {info = binding.value?.info;callback = binding.value?.callback;} else {callback = binding.value;}const observer = new IntersectionObserver((entries) => {entries.forEach((entry) => {if (entry.isIntersecting) {callback && callback(info);}});},{ root: el.parentElement },);observer.observe(el);},
};

6、v-scroll

滚动监听

创建src/directive/scroll.js

export default {bind(el, binding) {el.onscroll = function() {binding.value({x: el.scrollLeft,y: el.scrollTop,});};},unbind(el) {el.onscroll = null;},
};

7、v-scroll-to

滚动设置

创建src/directive/scroll-to.js

export default {update(el, binding) {let x = binding.modifiers?.x || false;if (binding.value && binding.value === binding.oldValue) return;if (typeof binding.value === "number") {x ? (el.scrollLeft = binding.value) : (el.scrollTop = binding.value);} else if (typeof binding.value === "string") {let targetDom = document.querySelector(binding.value);if (x) {let border = getComputedStyle(el, false)["borderLeftWidth"];let padding = getComputedStyle(el, false)["paddingLeft"];border = border.replace("px", "");padding = padding.replace("px", "");el.scrollLeft = targetDom.offsetLeft - el.offsetLeft - border - padding;} else {let border = getComputedStyle(el, false)["borderTopWidth"];let padding = getComputedStyle(el, false)["paddingTop"];border = border.replace("px", "");padding = padding.replace("px", "");el.scrollTop = targetDom.offsetTop - el.offsetTop - border - padding;}}},
};

8、v-auto-scroll

自动滚动

创建src/directive/scroll-auto.js

function active(el, scroll, step, max, x) {window.requestAnimationFrame(() => {x ? (el.scrollLeft = scroll) : (el.scrollTop = scroll);scroll += step;if (scroll >= max) scroll = 0 + step;active(el, scroll, step, max, x);});
}export default {inserted(el, binding) {const x = binding.modifiers?.x || false;let step = 0;let scroll = 0;if (typeof binding.value === "object") {step = binding.value?.step || 5;scroll = binding.value?.begin || 0;} else {step = binding.value || 5;}const scrollMax = x ? el.scrollWidth : el.scrollHeight;el._children = [].slice.call(el.children);el._children.forEach((child) => {el.appendChild(child.cloneNode(true));});active(el, scroll, step, scrollMax, x);},unbind(el) {el.innerHtml = "";let children = [].slice.call(el.children);children.forEach((child) => {el.removeChild(child);});el._children.forEach((child) => {el.appendChild(child.cloneNode(true));});},
};

相关文章:

vue2企业级项目(六)

vue2企业级项目&#xff08;六&#xff09; 自定义指令 创建src/directive/index.js const directives require.context("./modules", true, /\.js$/);export default {install: (Vue) > {directives.keys().forEach((key) > {let directive directives(key…...

OSPF的选路原则

域内 --- 1类&#xff0c;2类LSA 域间 --- 3类LSA 域外 --- 5类&#xff0c;7类LSA --- 根据开销值的计算规则不同&#xff0c;还分为类型1和类型2 1.如果学到的路由都是通过1类&#xff0c;2类LSA获取的域内路由 --- 这种情况直接比较开销值&#xff0c;优先选择开销值小的路…...

4.操作元素属性

4.1操作元素常用属性 ●通过 JS 设置/修改 标签元素属性&#xff0c;比如通过src更换图片 ●最常见的属性比如&#xff1a;href、 title、 src 等 ●语法: 对象.属性 值【示例】 // 1.获取元素 const pic document.querySelector( img ) // 2.操作元素 pic.src ./images/b…...

uniapp 微信小程序:v-model双向绑定问题(自定义 props 名无效)

uniapp 微信小程序&#xff1a;v-model双向绑定问题&#xff08;自定义 props 名无效&#xff09; 前言问题双向绑定示例使用 v-model使用 v-bind v-on使用 sync 修饰符 参考资料 前言 VUE中父子组件传递数据的基本套路&#xff1a; 父传子 props子传父 this.$emit(事件名, …...

【Lua学习笔记】Lua进阶——Table(3) 元表

接上文 文章目录 元表__tostring__call__index__newindex运算符元方法其它元表操作 元表 Q&#xff1a;为什么要使用元表&#xff1f; A&#xff1a;在Lua中&#xff0c;常常会需要表与表之间的操作。元表中提供了一些元方法&#xff0c;通过自定义元方法可以实现想要的功能&…...

AI编程常用工具 Jupyter Notebook

点击上方蓝色字体&#xff0c;选择“设为星标” 回复”云原生“获取基础架构实践 深度学习编程常用工具 我们先来看 4 个常用的编程工具&#xff1a;Sublime Text、Vim、Jupyter。虽然我介绍的是 Jupyter&#xff0c;但并不是要求你必须使用它&#xff0c;你也可以根据自己的喜…...

RocketMQ重复消费的解决方案::分布式锁直击面试!

文章目录 场景分析方法的幂等分布式锁Redis实现分布式锁抢锁的设计思路 分布式锁案例 直击面试rocketmq什么时候重复消费消息丢失的问题消息在哪里丢失发送端确保发送成功并且配合失败的业务处理消费端确保消息不丢失rocketmq 主从同步刷盘 场景分析 分布式系统架构中,队列是分…...

如何降低TCP在局域网环境下的数据传输延迟

以Ping为例。本案例是一个测试题目&#xff0c;只有现象展示&#xff0c;不含解决方案。 ROS_Kinetic_26 使用rosserial_windows实现windows与ROS master发送与接收消息_windows 接收ros1 消息 什么是ping&#xff1f; AI&#xff1a; ping是互联网控制消息协议&#xff08;…...

【LeetCode】78.子集

题目 给你一个整数数组 nums &#xff0c;数组中的元素 互不相同 。返回该数组所有可能的子集&#xff08;幂集&#xff09;。 解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。 示例 1&#xff1a; 输入&#xff1a;nums [1,2,3] 输出&#xff1a;[[],[1],[2],[1…...

认可功能介绍 - 技术声誉靠认可

需求 大家在学习和工作中&#xff0c; 经常碰到一些热心帮助自己的人&#xff0c; 我们怎么向他们表示感谢呢&#xff1f; 各位博主在 CSDN 也做了很多贡献&#xff0c;也有不少用户在做各种各样的社区活动&#xff0c;这些活动给我们的领军人物什么回馈呢&#xff1f; 这些…...

EtherNet/IP转CAN网关can协议标准

生产管理设备中&#xff0c;会有设备与其他设备的协议不同&#xff0c;数据无法互通&#xff0c;让你的工作陷入困境。这时&#xff0c;一款神奇的产品出现了——远创智控YC-EIP-CAN通讯网关&#xff01; 1, 这款通讯网关采用ETHERNET/IP从站功能&#xff0c;可以将各种CAN总线…...

解决代理IP负载均衡与性能优化的双重挑战

在当今数字化时代&#xff0c;代理IP的应用范围日益广泛&#xff0c;它不仅在数据爬取、网络抓取等领域发挥着重要作用&#xff0c;也成为网络安全和隐私保护的有力工具。然而&#xff0c;面对庞大的数据流量和复杂的网络环境&#xff0c;如何实现代理IP的负载均衡和性能优化成…...

深度探索 Elasticsearch 8.X:function_score 参数解读与实战案例分析

在 Elasticsearch 中&#xff0c;function_score 可以让我们在查询的同时对搜索结果进行自定义评分。 function_score 提供了一系列的参数和函数让我们可以根据需求灵活地进行设置。 近期有同学反馈&#xff0c;function_score 的相关参数不好理解&#xff0c;本文将深入探讨 f…...

测牛学堂:软件测试之andorid app性能测试面试知识点总结(二)

APP性能测试指标之FPS 如果经常玩游戏的同学应该听过FPS。 FPS本来是图像领域中的概念&#xff0c;是指画面每秒传输的帧数。每秒钟帧数越多&#xff0c;所显示的动作就会越流畅。 但是因为功耗的限制&#xff0c;一般60fps就是跑满的效果了。 我们测试的话&#xff0c;一般…...

尚医通06:数据字典+EasyExcel+mongodb

内容介绍 1、数据字典列表前端 2、EasyExcel介绍、实例 3、数据字典导出接口、前端 4、数据字典导入接口、前端 5、数据字典添加redis缓存 6、MongoDB简介 7、MongoDB安装 8、MongoDB基本概念 数据字典列表前端 1、测试问题 &#xff08;1&#xff09;报错日志 &am…...

【前端知识】React 基础巩固(三十二)——Redux的三大原则、使用流程及实践

React 基础巩固(三十二)——Redux的三大原则 一、Redux的三大原则 单一数据源 整个应用程序的state被存储在一颗object tree 中&#xff0c;并且这个object tree 只存储在一个store中&#xff1b;Redux并没有强制让我们不能创建多个Store&#xff0c;但是那样做不利于数据维护…...

[NLP]使用Alpaca-Lora基于llama模型进行微调教程

Stanford Alpaca 是在 LLaMA 整个模型上微调&#xff0c;即对预训练模型中的所有参数都进行微调&#xff08;full fine-tuning&#xff09;。但该方法对于硬件成本要求仍然偏高且训练低效。 [NLP]理解大型语言模型高效微调(PEFT) 因此&#xff0c; Alpaca-Lora 则是利用 Lora…...

Linux Shell 脚本编程学习之【第5章 文件的排序、合并与分割 (第四部分之cut命令) 】

第5章 文件的排序、合并与分割 &#xff08;第四部分之cut命令&#xff09; 4 cut 命令4.1 选项及其意义4.2 输出字符 &#xff08;-c&#xff09;4.3 改变分隔符&#xff08;-d&#xff09;和提取特定域&#xff08;-f&#xff09; 5 paste 命令5.1 paste 命令选项及其意义5.2…...

php-golang-rpc jsonrpc和php客户端tivoka/tivoka包实践

golang 代码&#xff1a; package main import ( "fmt" "net" "net/rpc" "net/rpc/jsonrpc" ) type App struct{} type Res struct { Code int json:"code" Msg string json:"msg" Data any json:"…...

flutter 打包iOS安装包

flutter iOS Xcode打包并导出ipa文件安装包 1、 Xcode配置 1、 启动打包 1、 等待打包 1、 打包完成、准备导出ipa 1、 选择模式 1、 选择配置文件 1、 导出 1、 选择导出位置 1、 得到ipa...

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

19c补丁后oracle属主变化,导致不能识别磁盘组

补丁后服务器重启&#xff0c;数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后&#xff0c;存在与用户组权限相关的问题。具体表现为&#xff0c;Oracle 实例的运行用户&#xff08;oracle&#xff09;和集…...

linux之kylin系统nginx的安装

一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源&#xff08;HTML/CSS/图片等&#xff09;&#xff0c;响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址&#xff0c;提高安全性 3.负载均衡服务器 支持多种策略分发流量…...

Objective-C常用命名规范总结

【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名&#xff08;Class Name)2.协议名&#xff08;Protocol Name)3.方法名&#xff08;Method Name)4.属性名&#xff08;Property Name&#xff09;5.局部变量/实例变量&#xff08;Local / Instance Variables&…...

五年级数学知识边界总结思考-下册

目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解&#xff1a;由来、作用与意义**一、知识点核心内容****二、知识点的由来&#xff1a;从生活实践到数学抽象****三、知识的作用&#xff1a;解决实际问题的工具****四、学习的意义&#xff1a;培养核心素养…...

Python爬虫(二):爬虫完整流程

爬虫完整流程详解&#xff08;7大核心步骤实战技巧&#xff09; 一、爬虫完整工作流程 以下是爬虫开发的完整流程&#xff0c;我将结合具体技术点和实战经验展开说明&#xff1a; 1. 目标分析与前期准备 网站技术分析&#xff1a; 使用浏览器开发者工具&#xff08;F12&…...

C#中的CLR属性、依赖属性与附加属性

CLR属性的主要特征 封装性&#xff1a; 隐藏字段的实现细节 提供对字段的受控访问 访问控制&#xff1a; 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性&#xff1a; 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑&#xff1a; 可以…...

Windows安装Miniconda

一、下载 https://www.anaconda.com/download/success 二、安装 三、配置镜像源 Anaconda/Miniconda pip 配置清华镜像源_anaconda配置清华源-CSDN博客 四、常用操作命令 Anaconda/Miniconda 基本操作命令_miniconda创建环境命令-CSDN博客...

实战设计模式之模板方法模式

概述 模板方法模式定义了一个操作中的算法骨架&#xff0c;并将某些步骤延迟到子类中实现。模板方法使得子类可以在不改变算法结构的前提下&#xff0c;重新定义算法中的某些步骤。简单来说&#xff0c;就是在一个方法中定义了要执行的步骤顺序或算法框架&#xff0c;但允许子类…...

yaml读取写入常见错误 (‘cannot represent an object‘, 117)

错误一&#xff1a;yaml.representer.RepresenterError: (‘cannot represent an object’, 117) 出现这个问题一直没找到原因&#xff0c;后面把yaml.safe_dump直接替换成yaml.dump&#xff0c;确实能保存&#xff0c;但出现乱码&#xff1a; 放弃yaml.dump&#xff0c;又切…...