【学习记录24】vue3自定义指令

一、在单vue文件中直接使用

1、html部分

<template><divstyle="height: 100%;"v-loading="loading"><ul><li v-for="item in data">{{item}} - {{item * 2}}</li></ul></div>
</template>

 2、js部分

<script setup>import {ref} from 'vue'// loading图片路径import imgSrc from '@/views/loading.gif'const data = ref(1)// 定义loading初始值为true,插入loadingconst loading = ref(true)// 单页面自定义指令直接使用v开头驼峰命名变量,如下const vLoading = {// dom加载完,在使用v-loading指令的html节点里添加dommounted (el, binding) {const div =  document.createElement('div')div.className = 'loading'const img = document.createElement('img')img.src = imgSrcimg.width = 40div.appendChild(img)el.appendChild(div)},updated(el, binding) {// 当值loading绑定的值为false的时候删除domif (!binding.value) {const loadingDom = document.querySelector('.loading')el.removeChild(loadingDom)}}}// 模拟异步数据,2秒后loading值为falsesetTimeout(() => {loading.value = falsedata.value = 50}, 2000)
</script>

3、实现效果

二、全局注册使用

1、html部分

<template><divstyle="height: 100%;"v-loading="loading"><ul><li v-for="item in data">{{item}} - {{item * 2}}</li></ul></div>
</template>

2、js部分

在components下创建loading文件夹,在loading文件夹里创建directive.js 

// direcitve.jsimport imgSrc from "@/views/loading.gif";const loadingDirective = {mounted(el, binding) {const div = document.createElement('div')div.className = 'loading'const img = document.createElement('img')img.src = imgSrcimg.width = 40div.appendChild(img)el.appendChild(div)},updated(el, binding) {if (!binding.value) {const loadingDom = document.querySelector('.loading')el.removeChild(loadingDom)}}
}
export default loadingDirective

在main.js中全局注册指令

// 引入loading
import loadingDirective from './components/loading/directive'let app = createApp(App)app.use(ElementPlus).use(router)
app.directive('loading', loadingDirective) // 全局注册
app.mount('#app')

三、使用vue组件文件实现自定义指令

1、在components下创建loading文件夹,在loading文件夹里创建directive.js

2、在loading文件夹里创建loading.vue

3、在loading文件夹里放入一张GIF图(loading.gif)

 

 1、loading.vue文件源码

// loading.vue<template><div class="loading"><div class="loading-content"><img src="./loading.gif" width="24" height="24" alt=""><p class="desc">{{title}}</p></div></div>
</template><script setup>// vue3 写法import { ref, defineExpose } from 'vue'const title = ref('正在加载...')const setTitle = (t) => {title.value = t}// 导出setTitle方法defineExpose({setTitle})// vue2 写法// export default {//   name: 'loading',//   data() {//     return {//       title: '正在加载...'//     }//   },//   methods: {//     setTitle(title) {//       this.title = title//     }//   }// }
</script><style scoped lang="scss">.loading {position: absolute;top: 50%;left: 50%;transform: translate3d(-50%, -50%, 0);.loading-content {text-align: center;.desc {line-height: 20px;font-size: $font-size-small;color: $color-text-l;}}}
</style>

2、js部分(directive.js) 

// directive.js// 引入vue方法createApp
import {createApp} from 'vue'
// 引入添加dom和删除dom的方法
import {addClass, removeClass} from '@/assets/js/dom'const relativeCls = 'g-relative'
const loadingDirective = {mounted (el, binding) {// 创建一个loading的vue实例const app = createApp(Loading)// 挂载loading.vue 到div DOM上const instance = app.mount(document.createElement('div'))// 把instance挂到要用指令的element下el.instance = instanceconst title = binding.arg// 如果传了title就重新设置title的值if (typeof title !== 'undefined') {instance.setTitle(title)}// 指令绑定的值为true把自定义的vue实例下的dom节点$el添加到el下if (binding.value) {append(el)}},// 指令绑定的值更新以后updated (el, binding) {const title = binding.argif (typeof title !== 'undefined') {el.instance.setTitle(title)}if (binding.value !== binding.oldValue) {// 指令绑定的值为true添加指令dom,否则删除指令的dombinding.value ? append(el) : remove(el)}}
}function append(el) {const style = getComputedStyle(el)// 如果要绑定的dom没有定位就添加一个有定位的classiif (!['absolute', 'fixed', 'relative'].includes(style.position)) {addClass(el, relativeCls)}el.appendChild(el.instance.$el)
}function remove(el) {removeClass(el, relativeCls)el.removeChild(el.instance.$el)
}export default loadingDirective

 3、@/assets/js/dom.js源码

export function addClass(el, className) {if (!el.classList.contains(className)) {el.classList.add(className)}
}export function removeClass(el, className) {el.classList.remove(className)
}

4、main.js源码 

// 引入loading
import loadingDirective from './components/loading/directive'let app = createApp(App)app.use(ElementPlus).use(router)
app.directive('loading', loadingDirective) // 全局注册
app.mount('#app')

四、进阶(有多个自定义指令)

1、封装一个通用的js

把自定义组件的方法拎出来单独弄一个js文件,我习惯放在src/assets/js/create-my-like-directive.js

// create-my-like-directive.jsimport { createApp } from 'vue'
import { addClass, removeClass } from '@/assets/js/dom'const relativeCls = 'g-relative'export default function createMyLikeDirective (Comp) { // 改动的地方,变成可传参的方法return {mounted (el, binding) {const app = createApp(Comp)  // 传入变动参数const instance = app.mount(document.createElement('div'))const name = Comp.nameif (!el[name]) {el[name] = {}}// 把实例挂载到dom的name下,防止多个自定义指令互相影响干扰出现bugel[name].instance = instanceconst title = binding.argif (title) {instance.setTitle(title)}if (binding.value) {append(el)}},updated (el, binding) {const title = binding.argconst name = Comp.nameif (title) {el[name].instance.setTitle(title)}if (binding.value !== binding.oldValue) {binding.value ? append(el) : remove(el)}}}function append (el) {const style = getComputedStyle(el)const name = Comp.nameif (!['absolute', 'fixed', 'relative'].includes(style.position)) {addClass(el, relativeCls)}el.appendChild(el[name].instance.$el)}function remove (el) {const name = Comp.nameremoveClass(el, relativeCls)el.removeChild(el[name].instance.$el)}
}

2、directive.js修改

import Loading from './loading.vue'
import createMyLikeDirective from '@/assets/js/create-my-like-directive'
// 如果有不同的自定义好的vue文件,Loading变为别的vue文件即可
const loadingDirective = createMyLikeDirective(Loading)export default loadingDirective

 3、main.js修改

// 引入loading
import loadingDirective from './components/loading/directive'// 引入其他的
import AAAA from './components/AAAA/directive'
import BBBB from './components/BBBB/directive'let app = createApp(App)app.use(ElementPlus).use(router)
app.directive('loading', loadingDirective) // 全局注册
app.directive('aaaa', AAAA) // 全局注册
app.directive('bbbb', BBBB) // 全局注册
app.mount('#app')

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/413344.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【NCRE 二级Java语言程序设计04】二级Java考试应用软件使用

目录 前言一、软件介绍和下载1.软件介绍和下载2.下载软件3.下载使用说明和示例教程 二、本地练习环境搭建1.解压启动2.自建Java应用程序3.Hello入门程序 三、NetBeans一般配置1.代码模板2.字体和颜色3.快捷键映射 总结 前言 &#x1f4dc;本专栏主要是分享自己备考全国计算机二…

[go语言]数据类型

目录 知识结构 整型、浮点型 1.整型 2.浮点型 复数、布尔类型 1.复数 2.布尔类型 字符与字符串 1.字符串的格式化 2.字符串的截取 3.格式化好的字符串赋值给量 4.字符串的转换 5.strings包 知识结构 整型、浮点型 1.整型 在Go语言中&#xff0c;整型数据是一种基…

AI工具的使用和分析

人工智能&#xff08;AI&#xff09;工具已经成为了现代社会不可或缺的一部分&#xff0c;它们的应用范围涵盖了各行各业&#xff0c;为人类带来了极大的便利和效率提升。随着技术的不断发展&#xff0c;AI工具的使用和分析也变得越来越重要。本文将探讨AI工具的使用和分析&…

查看神经网络中间层特征矩阵及卷积核参数

可视化feature maps以及kernel weights&#xff0c;使用alexnet模型进行演示。 1. 查看中间层特征矩阵 alexnet模型&#xff0c;修改了向前传播 import torch from torch import nn from torch.nn import functional as F# 对花图像数据进行分类 class AlexNet(nn.Module):d…

day2:TCP、UDP网络通信模型

思维导图 机械臂实现 #include <head.h> #define SER_POTR 8899 #define SER_IP "192.168.125.223" int main(int argc, const char *argv[]) {//创建套接字int cfdsocket(AF_INET,SOCK_STREAM,0);if(cfd-1){perror("");return -1;}//链接struct so…

书生·浦语大模型--第三节课笔记--基于 InternLM 和 LangChain 搭建你的知识库

文章目录 大模型开发范式RAGLangChain框架&#xff1a;构建向量数据库构建检索问答链优化建议web 部署 实践部分环境配置 大模型开发范式 LLM的局限性&#xff1a;时效性&#xff08;最新知识&#xff09;、专业能力有限&#xff08;垂直领域&#xff09;、定制化成本高&#…

响应式Web开发项目教程(HTML5+CSS3+Bootstrap)第2版 例4-4 label

代码 <!doctype html> <html> <head> <meta charset"utf-8"> <title>label</title> </head><body> 性别: <label for"male">男</label> <input type"radio" name"sex&quo…

vue2踩坑之项目:vue2+element实现前端导出

1.安装插件依赖 npm i --save xlsx0.17.0 file-saver2.0.5 2.单页面引入 前端导出插件 import FileSaver from "file-saver"; import * as XLSX from "xlsx"; //html <el-form-item><el-button type"primary" plain size"mini&quo…

三角形任意一外角大于不相邻的任意一内角

一.代数证明 ∵ 对与△ A C B 中 ∠ c 外接三角形是 ∠ B C D ∵对与△ACB中∠c外接三角形是∠BCD ∵对与△ACB中∠c外接三角形是∠BCD ∴ ∠ B C D π − ∠ C ∴∠BCD\pi-∠C ∴∠BCDπ−∠C ∵ ∠ A ∠ B ∠ C π ∵∠A∠B∠C\pi ∵∠A∠B∠Cπ ∴ ∠ B C D ∠ A ∠…

我在Vscode学OpenCV 图像处理五(直方图处理)

直方图是一种统计图&#xff0c;显示了图像中每个灰度级别&#xff08;或颜色通道&#xff09;的像素数量。通过分析图像的直方图&#xff0c;可以获得关于图像对比度、亮度和颜色分布等方面的重要信息。 直方图处理 一、直方图的意义二、绘制直方图2.1 直接使用Matplotlib.pyp…

关于Access中列的冻结的知识,看这篇就够了

在Microsoft Access中&#xff0c;有一个名为“冻结”的功能&#xff0c;使用户可以在滚动到另一个区域时保持数据表的某个区域可见。 可以使用冻结功能冻结数据表中的表、查询、窗体、视图或存储过程中的一个或多个字段。你冻结的字段将移动到数据表的左侧位置。 如何在Micr…

【云原生系列】容器安全

容器之所以广受欢迎&#xff0c;是因为它能简化应用或服务及其所有依赖项的构建、封装与推进&#xff0c;而且这种简化涵盖整个生命周期&#xff0c;跨越不同的工作流和部署目标。然而&#xff0c;容器安全依然面临着一些挑战。虽然容器有一些固有的安全优势&#xff08;包括增…