- 什么是Svg
- 常用的动画特效
- 数字可视化大屏怎么实现
- 地图的openlayers常用的api是什么
- webpack的打包过程
- vite和Rollup
- vue中hooks是什么
- 组件版本管理?如何管理
- url-loader? 主域并发数是什么
- virtualList的实现原理是什么
- 静态资源CDN加速?异步加载模块组件?路由懒加载?
- FCP是什么
- JWT替换传统Session登录
- RefreshToken刷新双token形式解决长时间保留token的安全问题
- webSocket实时获取后台信息
- 切片上传?文件秒传、断电续传、错误重试、控制并发
- Treeshaking,Scope Hosting,Gzip
- 实现水印?
- html2canvas和jspdf解决pdf内容截断问题以及乱码问题
- 外抛slot是什么 elementUI?
- 防抖和节流
- 页面加载完执行一个函数如何实现?
- vue中hash和history的区别
- vue中localtion.href和router.push啥区别
- 自定义指令
1.SVG
是一种用于描述基于二维的矢量图形的XML标记语言。 blog.csdn.net/xzd2333/art…
2.常用的动画特效
1.@keyframes定义动画名称 2.调用动画
@keyframes run {/* 也可使用关键字 "from" 和 "to"(代表 0%(开始)和 100%(完成))*/
0%{ /* 开始状态 */
}
100%{ /* 结束状态 */
}
}
- transition 实现渐变动画
- transform 转变动画
- animation 实现自定义动画
3.数字可视化大屏
前端自适应解决方案:
- 使用flex布局,结合元素百分比
- 使用rem单位
大屏自适应的解决方案:transform:scale
大屏使用rem耗时,而且对浏览器最小字体不支持
juejin.cn/post/709044…
juejin.cn/post/709072…
5.webpack打包
-
初始化参数:从配置文件和shell 语句中读取与合并参数,得到最终的参数。 -
开始编译:用上一步得到的参数初始化 Compiler 对象,加载所有配置的插件,执行 compiler 对象的 run 方法开始执行编译。 -
确定入口:根据配置中的 entry 找出所有的入口文件。 -
编译模块:从入口文件出发,调用所有配置的 Loader 对模块进行编译,找出该模块依赖的模块,再递归本步骤直到所有依赖文件都经过本步骤的处理。 -
完成模块编译: 在经过第 4 步使用 Loader 编译完所有模块之后,得到每个模块被编译后的最终内容以及它们之间的依赖关系。
-
输出资源:根据入口和模块之间的关系,组装成一个个包含多个模块的 chunk,再把每个 chunk 转换成一个单独的文件加入到输出列表,这步是可以修改输出内容的最后机会。 -
输出完成:在确定输出内容之后,根据配置确定输出的路径和文件名,把文件内容写入到文件系统
juejin.cn/post/706680…
6.vite和rollup
webpack常用于应用打包,rollup常用于第三方库打包
7.vue中的hooks
8.组件版本管理
9.url-loader
url-loader 和 file-loader 的工作方式是相似的,但是可以将较小的文件,转成 base64 的 URI(即以 base64 的方式编码图片文件,这样到时候就不需要单独下载它了
juejin.cn/post/702930…
主域并发数: 服务器能够同时处理的并发请求或链接的数量
10.virtualList的实现原理
主要是利用了 对数据的不断截取,只渲染截取的数据
如图所示:列表分为可见区域和缓冲区域,超出这个范围的列表 DOM 都将被删除。
11.CDN加速
使用CDN主要解决两个问题:
- 打包时间太长、打包后代码体积太大,请求慢
- 服务器网络不稳带宽不高,使用cdn可以回避服务器带宽问题 juejin.cn/post/702173…
异步加载模块组件
动态组件:是Vue中一个特殊的Html元素:<component>,它拥有一个特殊的 is 属性,属性值可以是 已注册组件的名称 或 一个组件的选项对象,它是用于不同组件之间进行动态切换的。
异步组件:简单来说是一个概念,一个可以让组件异步加载的方式;它一般会用于性能优化,比如减小首屏加载时间、加载资源大小。
Vue.component('async-example', function (resolve, reject) {
setTimeout(function () {
// 向 `resolve` 回调传递组件定义
resolve({
template: '<div>I am async!</div>'
})
}, 1000)
})
路由懒加载就是将路由匹配的组件变为异步组件,异步组件是指只有页面需要用到时才从服务器加载的组件。
通过异步组件和webpacm代码分割,实现路由懒加载,按需加载,提升路由页面加载速度。
简单来说,写在路由配置文件中的异步加载就是路由懒加载的用法,而写在组件内部的异步加载就是异步组件用法。
www.cnblogs.com/tive/p/1559…
12.FCP是什么
- load(Onload Event),它代表页面中依赖的所有资源加载完的事件。
- DCL(DOMContentLoaded),DOM解析完毕。
- FP(First Paint),表示渲染出第一个像素点。FP一般在HTML解析完成或者解析一部分时候触发。
- FCP(First Contentful Paint),表示渲染出第一个内容,这里的“内容”可以是文本、图片、canvas。
- FMP(First Meaningful Paint),首次渲染有意义的内容的时间,“有意义”没有一个标准的定义,FMP的计算方法也很复杂。
- LCP(largest contentful Paint),最大内容渲染时间。
白屏结束时间 = FP事件触发时间 首屏结束时间 = FCP事件触发时间
13.JWT替换传统Session登录
session登录通常是用户访问服务器生成一个sessionID,储存在服务器中,通时将sessionId传给浏览器,当浏览器再次访问时,http请求就带有sessionId,服务器根据id获取到用户信息 session的缺点是当用户量大时,会占用大量服务器内存,每次客户请求都要向服务器获取sessionId,导致请求速度变慢
现在多采用JWT代替Session,JWT使用JSON来保存令牌信息,并不把信息保存在服务端,而是保存在客户端。JWT的结构包括头部、负载和签名:
头部中保存的是加密算法说明,负载中保存用户信息,签名是根据头部和负责经过算法算出来的值 JWT的登陆流程:
- 客户端向服务单发送登陆请求
- 服务端检验用户名密码,如果成功将从数据库中提取出这个用户的Id、角色等信息
- 服务端采用自定义的秘钥对用户信息(JSON)进行签名,形成签名数据
- 将用户信息(JSON)和上一步形成的签名拼接形成JWT,发送给客户端
- 客户端每次请求都带上这个JWT
- 每次服务器收到带JWT的请求后,使用自定义的秘钥对JWT的签名进行校验,如果成功则从JWT中取出用户信息
14.RefreshToken刷新双token形式解决长时间保留token的安全问题
浏览器向服务器发送请求,返回一个token和refreshToken,浏览器存储到localstrore中。再次发送时,如果校验到401,token失效,前端在请求中拦截,将refreshtoken传给后端,如果refreshtoken没有失效,则返回新的token和refreshtoken,若失效则返回登录页面
解决token时效短,频繁登录认证的问题
15.webSocket实时获取后台信息
使用 WebSocket 实时获取后台信息是一种常见的做法,可以实现双向通信,适用于聊天应用、实时通知、股票报价等场景。下面是一个基本的实现步骤和示例。
1. 后端实现
假设你使用 Node.js 和 ws 库来创建一个 WebSocket 服务器:
// server.js
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });
wss.on('connection', (ws) => {
console.log('新连接建立');
// 每隔 1 秒发送一条消息
const intervalId = setInterval(() => {
const message = JSON.stringify({ time: new Date().toISOString() });
ws.send(message);
}, 1000);
ws.on('close', () => {
clearInterval(intervalId);
console.log('连接关闭');
});
});
2. 前端实现
在前端,使用 WebSocket API 连接到 WebSocket 服务器,并处理接收到的消息:
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>WebSocket 示例</title>
</head>
<body>
<h1>实时信息</h1>
<div id="messages"></div>
<script>
const messagesDiv = document.getElementById('messages');
const socket = new WebSocket('ws://localhost:8080');
socket.onopen = () => {
console.log('连接已打开');
};
socket.onmessage = (event) => {
const data = JSON.parse(event.data);
const message = document.createElement('div');
message.textContent = `收到信息: ${data.time}`;
messagesDiv.appendChild(message);
};
socket.onclose = () => {
console.log('连接已关闭');
};
socket.onerror = (error) => {
console.error('WebSocket 错误:', error);
};
</script>
</body>
</html>
3. 启动服务器和访问前端
-
启动 WebSocket 服务器:
node server.js -
打开浏览器,访问你的 HTML 文件(例如
index.html)。你将看到实时更新的时间信息。
总结
- 后端 使用 WebSocket 服务器接收和发送消息。
- 前端 使用 WebSocket API 连接服务器并处理消息。
你可以根据具体需求扩展这个基础示例,比如增加用户身份验证、处理不同类型的消息等。
16.文件分片上传
- MD5读取文件,获取文件的MD5编码
- 请求服务端判断文件是否上传,如上传完成就直接返回文件地址
- 如未上传,判断是否是断点续传
- 判断是并发上传还是顺序上传
- 开始分片文件上传,分片上传完成后写入已上传列表中
- 判断是否上传完成
https://juejin.cn/post/6844904046436843527#heading-18
17. Treeshaking,Scope Hosting,Gzip
Treeshaking
Tree Shaking 是一种通过消除未使用的代码来优化打包的技术,主要用于 JavaScript 应用中。它依赖于 ES6 模块系统(import 和 export),能够在构建时分析代码,去除那些没有被引用的部分,从而减小打包后的文件大小。
如何实现:
- 确保使用 ES6 模块语法。
- 使用支持 Tree Shaking 的打包工具,如 Webpack 和 Rollup。
- 将
mode设置为production(如在 Webpack 中),因为它会自动进行 Tree Shaking。
例子:
// utils.js
export const usedFunction = () => {};
export const unusedFunction = () => {};
如果在其他模块中只导入了 usedFunction,则打包时 unusedFunction 会被移除。
Scope Hoisting
Scope Hoisting 是一种优化技术,用于减少 JavaScript 代码的封装层级,提高代码执行效率。在 Webpack 中,Scope Hoisting 通过将多个模块合并为一个函数作用域,从而减少了闭包的数量,降低了执行时的开销。
如何实现:
- 使用 Webpack 的
mode: 'production',因为它会自动启用 Scope Hoisting。 - 使用 ES6 模块化语法(
import和export),因为它可以更好地支持 Scope Hoisting。
Gzip
Gzip 是一种文件压缩格式,通常用于减小网页资源的大小,从而加快网页加载速度。服务器在传输 HTML、CSS、JavaScript 等资源时,可以使用 Gzip 对这些文件进行压缩,客户端在接收到这些文件时会自动解压。 如何实现:
- 在服务器上启用 Gzip 压缩。例如,在 Apache 和 Nginx 中,可以通过配置文件轻松开启 Gzip。
- 确保客户端支持 Gzip,现代浏览器通常都支持。 Nginx 配置示例:
gzip on;
gzip_types text/plain application/javascript text/css;
gzip_min_length 1000;
常用配置有:filter(过滤:对哪些文件进行压缩);threshold:1024000 (对大于1mb的文件进行压缩);deleteOriginFile: false(压缩后是否删除源文件)
18.实现水印
第一步还是在页面上覆盖一个固定定位的盒子,然后创建一个canvas画布,绘制出一个水印区域,将这个水印通过toDataURL方法输出为一个图片,将这个图片设置为盒子的背景图,通过backgroud-repeat:repeat;样式实现填满整个屏幕的效果
pointer-events:none解决绝对定位造成点击事件无法穿透的问题
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="info">
<div class="box" onclick="console.log('点击到啦')">
djfdhg ghfjghjg fddfhgj ghfd jkghfjh gfd
djfdhg ghfjghjg fddfhgj ghfd jkghfjh gf
</div>
</div>
<script>
function __canvasWM({
container = document.body,
width = '300px',
height = '200px',
textAlign = 'center',
textBaseline = 'middle',
font = "20px Microsoft Yahei",
fillStyle = 'rgba(184, 184, 184, 0.6)',
content = '水印',
rotate = '45',
zIndex = 10000
} = {}) {
const args = arguments[0];
const canvas = document.createElement('canvas');
canvas.setAttribute('width', width);
canvas.setAttribute('height', height);
const ctx = canvas.getContext("2d");
ctx.textAlign = textAlign;
ctx.textBaseline = textBaseline;
ctx.font = font;
ctx.fillStyle = fillStyle;
ctx.rotate(Math.PI / 180 * rotate);
ctx.fillText(content, parseFloat(width) / 2, parseFloat(height) / 2);
const base64Url = canvas.toDataURL();
const __wm = document.querySelector('.__wm');
const watermarkDiv = __wm || document.createElement("div");
const styleStr = `
position:fixed;
top:0;
left:0;
bottom:0;
right:0;
width:100%;
height:100%;
z-index:${zIndex};
pointer-events:none;
background-repeat:repeat;
background-image:url('${base64Url}')`;
watermarkDiv.setAttribute('style', styleStr);
watermarkDiv.classList.add('__wm');
if (!__wm) {
container.insertBefore(watermarkDiv, container.firstChild);
}
if (typeof module != 'undefined' && module.exports) { //CMD
module.exports = __canvasWM;
} else if (typeof define == 'function' && define.amd) { // AMD
define(function () {
return __canvasWM;
});
} else {
window.__canvasWM = __canvasWM;
}
}
// 调用
__canvasWM({
content: '水印8983'
});
</script>
</body>
</html>
<style>
.box{
width: 600px;
height: 700px;
}
</style>
19. html2canvas和jspdf解决pdf内容截断问题以及乱码问题
使用 html2canvas 和 jspdf 生成 PDF 文件时,确实可能会遇到内容截断和乱码的问题。以下是一些常见的解决方案。
1. 内容截断问题
解决方法:
- 设置页面尺寸:确保在创建 PDF 时,页面尺寸与要捕获的内容匹配。可以通过
jspdf的参数设置页面大小。
const doc = new jsPDF({
orientation: 'portrait',
unit: 'mm',
format: 'a4',
putOnlyUsedFonts: true,
floatPrecision: 16 // float precision for higher quality
});
- 调整 html2canvas 的选项:使用
html2canvas时,可以通过设置scrollX和scrollY来确保捕获到完整内容。
html2canvas(document.querySelector("#element"), {
scrollX: 0,
scrollY: -window.scrollY,
}).then((canvas) => {
const imgData = canvas.toDataURL("image/png");
const imgWidth = 210; // A4 size in mm
const pageHeight = 295; // A4 size in mm
const imgHeight = (canvas.height * imgWidth) / canvas.width;
const heightLeft = imgHeight;
let position = 0;
doc.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight);
position += heightLeft;
if (heightLeft >= pageHeight) {
doc.addPage();
}
doc.save('download.pdf');
});
2. 乱码问题
解决方法:
- 字体支持:确保你使用的字体在 PDF 中是嵌入的。你可以使用
jspdf提供的addFont方法来添加自定义字体。
// 加载字体(例如使用 jsPDF 提供的ttf文件)
const font = "path/to/your/font.ttf"; // 确保字体文件可访问
jsPDF.API.addFileToVFS("CustomFont.ttf", font);
jsPDF.API.addFont("CustomFont.ttf", "CustomFont", "normal");
doc.setFont("CustomFont");
- 确保编码正确:确保在生成 PDF 时,文本的编码是正确的。可以尝试使用 UTF-8 编码。
示例代码
以下是一个完整的示例,将 html2canvas 和 jspdf 结合使用,解决上述问题:
function generatePDF() {
const doc = new jsPDF({
orientation: 'portrait',
unit: 'mm',
format: 'a4',
putOnlyUsedFonts: true,
floatPrecision: 16,
});
html2canvas(document.querySelector("#element"), {
scrollX: 0,
scrollY: -window.scrollY,
}).then((canvas) => {
const imgData = canvas.toDataURL("image/png");
const imgWidth = 210; // A4 width in mm
const pageHeight = 295; // A4 height in mm
const imgHeight = (canvas.height * imgWidth) / canvas.width;
const heightLeft = imgHeight;
let position = 0;
doc.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight);
position += heightLeft;
// 分页处理
while (heightLeft >= pageHeight) {
position -= pageHeight;
doc.addPage();
doc.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight);
}
doc.save('download.pdf');
});
}
查看全部
总结
- 内容截断:确保页面尺寸匹配,适当设置
html2canvas的选项。 - 乱码:确保字体支持和文本编码正确。
20.外抛slot是什么 elementUI?
在 Element UI 中,外抛 slot(或称为作用域插槽)是一种特殊的插槽,用于将数据从父组件传递到子组件,以便父组件能够根据子组件提供的上下文动态地渲染内容。这种机制使得组件更加灵活和可复用。
基本概念
- 插槽:插槽是 Vue 组件中的一种占位符,允许在组件使用时传入自定义内容。
- 作用域插槽:通过作用域插槽,父组件可以访问子组件中的数据或方法。
使用示例
假设你有一个自定义的表格组件,使用外抛 slot 来实现动态渲染表格行。
1. 子组件(Table.vue)
<template>
<table>
<tr v-for="item in items" :key="item.id">
<slot :item="item"></slot>
</tr>
</table>
</template>
<script>
export default {
props: {
items: Array
}
};
</script>
2. 父组件(Parent.vue)
<template>
<div>
<Table :items="tableData">
<template v-slot="{ item }">
<td>{{ item.name }}</td>
<td>{{ item.age }}</td>
</template>
</Table>
</div>
</template>
<script>
import Table from './Table.vue';
export default {
components: { Table },
data() {
return {
tableData: [
{ id: 1, name: 'Alice', age: 25 },
{ id: 2, name: 'Bob', age: 30 }
]
};
}
};
</script>
查看全部
关键点
- 在子组件中,使用
<slot :item="item">语法将item数据传递给插槽。 - 在父组件中,使用
v-slot指令来接收这个数据,并自定义如何渲染每一行。
总结
外抛 slot(作用域插槽)在 Element UI 中提供了一种强大的方式来传递数据,使得组件间的互动更加灵活。通过这种方式,开发者可以根据子组件的上下文动态渲染父组件的内容,从而提高代码的复用性和可维护性。
21.防抖和节流
防抖和节流的使用场景
防抖(debounce)
1.search搜索时,用户在不断输入值时,用防抖来节约请求资源。
节流(throttle)
1.鼠标不断点击触发,mousedown(单位时间内只触发一次) 2.监听滚动事件,比如是否滑到底部自动加载更多,用throttle来判断
如何实现
1.防抖 (多次触发 只执行最后一次)
作用: 高频率触发的事件,在指定的单位时间内,只响应最后一次,如果在指定的时间内再次触发,则重新计算时间 防抖类似于英雄联盟回城6秒,如果回城中被打断,再次回城需要再等6秒
实现代码:
<body>
<input type="text" id="inp">
<script>
// 1.封装防抖函数
function debounce(fn, time) {
// 4.创建一个标记用来存放定时器的返回值
let timeout = null;
return function () {
// 5.每当用户触发input事件 把前一个 setTimeout 清楚掉
clearTimeout(timeout);
// 6.然后又创建一个新的 setTimeout, 这样就能保证输入字符后等待的间隔内 还有字符输入的话,就不会执行 setTimeout里面的内容
timeout = setTimeout(() => {
// 7.这里进行防抖的内容
fn();
}, time);
};
}
// 2.获取inpt元素
var inp = document.getElementById('inp');
// 8. 测试防抖临时使用的函数
function sayHi() {
console.log('防抖成功');
}
// 3.给inp绑定input事件 调用封装的防抖函数 传入要执行的内容与间隔事件
inp.addEventListener('input', debounce(sayHi, 5000));
</script>
</body>
2.节流 (规定时间内 只触发一次)
作用: 高频率触发的事件,在指定的单位时间内,只响应第一次 节流类似于英雄联盟里的英雄平A 一定是内点击多次只进行攻击一次
<script>
// 1.封装节流函数
function throttle(fn, time) {
//3. 通过闭包保存一个 "节流阀" 默认为false
let temp = false;
return function () {
//8.触发事件被调用 判断"节流阀" 是否为true 如果为true就直接trurn出去不做任何操作
if (temp) {
return;
} else {
//4. 如果节流阀为false 立即将节流阀设置为true
temp = true; //节流阀设置为true
//5. 开启定时器
setTimeout(() => {
//6. 将外部传入的函数的执行放在setTimeout中
fn.apply(this, arguments);
//7. 最后在setTimeout执行完毕后再把标记'节流阀'为false(关键) 表示可以执行下一次循环了。当定时器没有执行的时候标记永远是true,在开头被return掉
temp = false;
}, time);
}
};
}
function sayHi(e) {
// 打印当前 document 的宽高
console.log(e.target.innerWidth, e.target.innerHeight);
}
// 2.绑定事件,绑定时就调用节流函数
// 敲黑板!!! 这里是重点 绑定是就要调用一下封装的节流函数 触发事件是触发封装函数内部的函数
window.addEventListener('resize', throttle(sayHi, 2000));
</script>
22.页面加载完执行一个函数如何实现
window.onload=function(){
alert("请参见离职指引");
}
$().ready(function(){
alert("请参见离职指引");
})
定时器
23.vue中hash和history的区别
在 Vue Router 中,hash 和 history 是两种不同的路由模式,各有优缺点。
1). Hash 模式
- 原理:使用 URL 的 hash 部分(
#)来管理路由。例如,URL 会变成http://example.com/#/home。 - 优点:
- 简单易用,兼容性好,支持旧版浏览器。
- 不需要服务器配置,直接在客户端处理。
- 缺点:
- 不支持浏览器的“前进”或“后退”按钮的真正刷新,刷新页面会重新加载整个应用。
- URL 中的 hash 部分不被搜索引擎索引。
2). History 模式
- 原理:使用 HTML5 的 History API 来管理路由,例如 URL 会变成
http://example.com/home。 - 优点:
- URL 更加美观、易读,且不包含
#。 - 支持真正的前进和后退,刷新页面时可以保持状态。
- 更适合搜索引擎优化(SEO)。
- URL 更加美观、易读,且不包含
- 缺点:
- 需要服务器支持,以确保所有路由都能返回同一个 HTML 页面。通常需要配置服务器,以处理 404 错误。
总结
选择哪种模式取决于你的应用需求。如果需要简单的路由并兼容旧版浏览器,选择 hash 模式;如果追求更好的用户体验和 SEO,选择 history 模式。
24.vue中localtion.href和router.push啥区别
在 Vue 中,location.href 和 router.push 都可以用于导航,但它们的工作方式和用途有一些重要的区别。
1. location.href
-
用途:直接改变浏览器的 URL,类似于在浏览器地址栏输入新地址。
-
特点:
- 导航时会导致整个页面重新加载。
- 可以跳转到外部 URL。
- 适用于需要重新加载整个应用或访问外部资源的场景。
2. router.push
-
用途:用于 Vue Router 实现客户端路由的导航。
-
特点:
- 不会导致页面重新加载,而是通过 Vue Router 的机制来切换视图。
- 适合在单页应用中进行导航,保持应用的状态和性能。
- 支持传递路由参数和查询字符串。
总结
- 使用场景:如果你在单页应用中需要无缝切换视图,使用
router.push。如果你需要访问外部 URL 或重新加载页面,则使用location.href。 - 性能:
router.push更高效,因为它避免了完整的页面重载,保持了应用的状态。
vue自定义指令
Vue.directive 方法来注册一个全局指令
1. 创建自定义指令
可以通过 Vue.directive 方法来注册一个全局指令,也可以在组件中使用 directives 选项注册局部指令。
全局指令示例
// 在 main.js 或类似的入口文件中
Vue.directive('focus', {
// 当绑定元素插入到 DOM 中时调用
inserted: function (el) {
el.focus();
}
});
局部指令示例
export default {
directives: {
focus: {
// 当绑定元素插入到 DOM 中时调用
inserted(el) {
el.focus();
}
}
}
}
2. 使用自定义指令
在模板中使用自定义指令时,前面加上 v- 前缀。
<template>
<input v-focus />
</template>
3. 指令钩子函数
自定义指令提供了多个钩子函数,可以在不同的生命周期阶段执行特定操作。常用的钩子函数包括:
- bind:指令第一次绑定到元素时调用,只会调用一次。
- inserted:被绑定元素插入父节点时调用。
- update:所在组件的 VNode 更新时调用,可能会多次调用。
- componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
- unbind:指令与元素解绑时调用。
示例:一个简单的自定义指令
以下是一个简单的自定义指令示例,用于改变文本颜色:
// 在 main.js 中
Vue.directive('color', {
// 绑定元素
bind(el, binding) {
el.style.color = binding.value; // 设置文本颜色
}
});
在模板中使用:
<template>
<div v-color="'red'">这是红色文本</div>
</template>
总结
自定义指令在 Vue 中非常灵活,适用于需要对 DOM 元素进行特殊操作的场景。可以根据需求定义不同的指令和钩子函数,以实现复杂的功能。