vue3的常用功能

文章目录

  • 一、前言
  • 二、自动注册全局组件
    • 2.1、自动注册`components`目录下所有`vue`组件并以组件的文件名为组件的名称
    • 2.2、使用这个插件
    • 2.3、为全局组件添加类型提示
  • 三、函数式图片预览
  • 四、手动封装 `svgIcon` 组件
  • 五、封装拖拽钩子函数
  • 六、`vscode` 中 `vue3` 代码片段
  • 七、最后

一、前言

本文主要分享一下在使用vue3开发项目时的一些常用功能

二、自动注册全局组件

2.1、自动注册components目录下所有vue组件并以组件的文件名为组件的名称

// components/index.tsimport { type App, defineAsyncComponent } from 'vue'
const components = Object.entries(import.meta.glob('./**/*.vue'))
const preFix = 'Es'
export default {// use 的时候install: (app: App) => {components.forEach(([key, comp]) => {// 得到组件的名称const name = getCompName(comp.name || key)app.component(preFix + name, defineAsyncComponent(comp as any))})}
}function getCompName(key: string) {const nameReg = //(\w+).vue/return nameReg.test(key) ? key.match(nameReg)![1] : key
}
  1. 使用 import.meta.glob 动态导入所有以 .vue 结尾的文件,并将它们作为键值对的形式存储在 components 变量中。
  2. install 方法中,通过遍历 components 数组,对每个组件进行注册
  3. 通过 comp.name 获取组件的名称,如果名称不存在,则使用组件的路径 key。然后,使用 defineAsyncComponent 将组件定义为异步组件
  4. getCompName 函数用于从组件路径中提取组件的名称。使用正则对组件路径进行匹配,提取出路径中最后一个斜杠后的单词作为组件名称

2.2、使用这个插件

import { createApp } from 'vue'
import App from './App.vue'import MyComponents from './components'createApp(App).use(MyComponents).mount('#app')

自动注册全局组件虽然很方便,但在使用时缺少了ts类型提示,下面介绍一下为全局组件添加类型提示

2.3、为全局组件添加类型提示

这需要我们自己编写.d.ts声明文件

// src/typings/component.d.ts
export {}declare module 'vue' {export interface GlobalComponents {EsDialog: typeof import('../components/Dialog.vue')['default']}
}

img

三、函数式图片预览

图片预览是一个比较常用的功能,封装成函数调用可以简化我们使用的方式

基于 element-plusElImageViewer 组件

对于有类似的功能都可以使用这种方式,例如我们想使用函数调用的方式弹窗

// utils/preview.ts
import { createVNode, render } from 'vue'
import { ElImageViewer, ImageViewerProps } from 'element-plus'type PreviewOption = Partial<ImageViewerProps>export function preview(option: PreviewOption) {const container = document.createElement('div')let vm = createVNode(ElImageViewer, {...option,onClose() {render(null, container)}})// 将组件渲染成真实节点render(vm, container)document.body.appendChild(container.firstElementChild!)
}
  1. preview 函数接受一个 option 参数,它是 PreviewOption(ImageViewerProps 类型的部分可选类型) 类型的对象,用于配置图片预览的选项。
  2. 函数内部,首先创建了一个 div 元素作为容器,用于渲染预览组件。
  3. 使用 createVNode 创建了一个 ElImageViewer 组件实例 vm
  4. 使用 render 方法将 vm 渲染为真实的节点,并将其挂载到之前创建的容器中,最后添加到body页面上
  5. 传入的 props中 监听 close 事件移除节点

调用

preview({urlList: ['https://fuss10.elemecdn.com/0/6f/e35ff375812e6b0020b6b4e8f9583jpeg.jpeg'],initialIndex: 0
})

四、手动封装 svgIcon 组件

这节主要是vangle组件库的icon组件封装方式的介绍,为想自己手动封装svgIcon组件的朋友可以作个参考

以下是代码实现

  • Icon.vue
<template><i class="es-icon" :style="style" v-html="icon"></i>
</template><script lang="ts" setup>
import { computed, CSSProperties } from 'vue'
import { IconProps, getIcon } from './icon'const props = defineProps(IconProps)const icon = computed(() => getIcon(props.name))
const style = computed<CSSProperties>(() => {if (!props.size && !props.color) return {}return {fontSize: typeof props.size === 'string' ? props.size : `${props.size}px`,'--color': props.color,}
})
</script><style scoped lang="scss">
.es-icon {--color: inherit;height: 1em;width: 1em;line-height: 1em;display: inline-flex;justify-content: center;align-items: center;position: relative;fill: currentColor;color: var(--color);font-size: inherit;font-style: normal;svg {height: 1em;width: 1em;}
}
</style>
  • 以下是getIcon的实现 icon.ts
export const svgs = import.meta.glob('./svg/*.svg', { eager: true, as: 'raw' })
export const IconProps = {name: String,color: String,size: [String, Number]
}export const getIcon = (name?: string) => {if (!name) return ''return svgs[`./svg/${name}.svg`]
}

使用 import.meta.glob 动态导入svg目录下所有以 .svg 结尾的文件,as: 'raw' 表示导入的文件内容以原始字符串形式保存

getIcon 根据name获取svg的内容

  • 直接使用
<es-icon name="add-location" />
<es-icon name="add-location" color="pink" />
<es-icon name="add-location" color="pink" :size="30" />

五、封装拖拽钩子函数

import { onBeforeUnmount, onMounted, watchEffect, Ref } from 'vue'export const useDraggable = (targetRef: Ref<HTMLElement | undefined>,dragRef: Ref<HTMLElement | undefined>,draggable: Ref<boolean>
) => {// 保存偏移量let transform = {offsetX: 0,offsetY: 0,}const onMousedown = (e: MouseEvent) => {const downX = e.clientXconst downY = e.clientYconst { offsetX, offsetY } = transform// 获取拖拽目标的位置和尺寸信息const targetRect = targetRef.value!.getBoundingClientRect()const targetTop = targetRect.topconst targetWidth = targetRect.widthconst targetHeight = targetRect.height// 计算拖拽目标在页面中的可移动范围const clientWidth = document.documentElement.clientWidthconst clientHeight = document.documentElement.clientHeightconst minLeft = -targetRect.left + offsetXconst minTop = -targetTop + offsetYconst maxLeft = clientWidth - targetRect.left - targetWidth + offsetXconst maxTop = clientHeight - targetTop - targetHeight + offsetYconst onMousemove = (e: MouseEvent) => {// 计算移动后的位置/*** offsetX + e.clientX - downX: 初始偏移量 offsetX 加上 e.clientX - downX 移动的距离得到拖拽元素在水平方向上的新位置。* Math.max(offsetX + e.clientX - downX, minLeft) 确保新位置大于等于最小可移动位置 minLeft,即不超出左边界* Math.min(..., maxLeft) 确保新位置小于等于最大可移动位置 maxLeft,即不超出右边界。这样做的目的是防止拖拽元素移出指定的范围。*/const moveX = Math.min(Math.max(offsetX + e.clientX - downX, minLeft),maxLeft)// 和上面同理const moveY = Math.min(Math.max(offsetY + e.clientY - downY, minTop),maxTop)// 更新偏移量和元素位置transform = {offsetX: moveX,offsetY: moveY,}targetRef.value!.style.transform = `translate(${moveX}px, ${moveY}px)`}const onMouseup = () => {// 移除事件监听document.removeEventListener('mousemove', onMousemove)document.removeEventListener('mouseup', onMouseup)}// 监听鼠标移动和鼠标抬起事件document.addEventListener('mousemove', onMousemove)document.addEventListener('mouseup', onMouseup)}const onDraggable = () => {if (dragRef.value && targetRef.value) {dragRef.value.addEventListener('mousedown', onMousedown)}}const offDraggable = () => {if (dragRef.value && targetRef.value) {dragRef.value.removeEventListener('mousedown', onMousedown)}}onMounted(() => {watchEffect(() => {if (draggable.value) {onDraggable()} else {offDraggable()}})})onBeforeUnmount(() => {offDraggable()})
}

useDraggable 的函数,接受三个参数:

targetRef:拖拽目标Ref

dragRef:拖拽触发区域Ref

draggable: 开启/关闭拖拽

在函数内部定义了一个变量 transform,用于保存拖拽过程中的偏移量。

  1. onMousedown 函数中,首先记录下鼠标按下时的坐标 downXdownY,以及当前的偏移量 offsetXoffsetY
  2. 获取拖拽目标元素的位置和尺寸信息,计算出拖拽目标在页面中可移动的范围。
  3. 移动时 onMousemove 中,根据鼠标移动的位置计算出新的偏移量 moveXmoveY,并更新 transform 对象和拖拽目标元素的位置
  4. 最后,定义了一个 onMouseup 函数,当鼠标抬起时执行的事件处理函数。在函数内部,移除鼠标移动和鼠标抬起事件的监听。

六、vscodevue3 代码片段

针对 Vue 3.2+ 的代码片段模板,用于在 VSCode 中快速生成 Vue 组件的模板代码

在项目的 .vscode 目录下创建一个名为 vue3.2.code-snippets 的文件,它是一个 JSON 格式的代码片段文件

{"Vue3.2+快速生成模板": {"prefix": "Vue3.2+","body": ["<template>","\t<div>\n","\t</div>","</template>\n","<script setup lang='ts'>","</script>\n","<style lang='scss' scoped>\n","</style>","$2"],"description": "Vue3.2+"}
}

prefix:定义了在代码编辑器中触发该代码片段的前缀,这里设定为 Vue3.2+

body:定义了代码片段的主体部分,它是一个数组,包含多行模板代码

description:对该代码片段的描述

vue文件中输入Vue3.2+(会有自动提示) 按下 Tab 键,就会自动插入这段模板代码。你可以根据需要自行修改和完善这个模板。

img

七、最后

本人每篇文章都是一字一句码出来,希望对大家有所帮助,多提提意见。顺手来个三连击,点赞👍收藏💖关注✨,一起加油☕

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

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

相关文章

vue3:25—其他API

目录 1、shallowRef和shallowReactive 2、readonly与shallowReadonly readonly shallowReadonly 3、toRaw和markRaw toRaw markRaw 4、customRef 1、shallowRef和shallowReactive shallowRef 1.作用:创建一个响应式数据&#xff0c;但只对顶层属性进行响应式处理。2…

[Vulnhub靶机] DriftingBlues: 4

[Vulnhub靶机] DriftingBlues: 4靶机渗透思路及方法&#xff08;个人分享&#xff09; 靶机下载地址&#xff1a; https://download.vulnhub.com/driftingblues/driftingblues4_vh.ova 靶机地址&#xff1a;192.168.67.23 攻击机地址&#xff1a;192.168.67.3 一、信息收集 …

Python数据可视化库之mplfinance使用详解

概要 Python 是一种强大的编程语言,拥有众多用于数据可视化的库和工具。其中之一是 mplfinance(Matplotlib Finance),它是基于 Matplotlib 的库,专门用于创建金融图表和交互式金融数据可视化。本文将深入介绍 mplfinance,包括其基本概念、功能特性以及如何使用示例代码创…

“手把手教你玩转函数递归,建议收藏!“

目录 1. 什么是递归 2. 递归的限制条件 3. 递归的举例 4. 递归与迭代 正⽂开始 1. 递归是什么&#xff1f; 递归是学习C语⾔函数绕不开的⼀个话题&#xff0c;那什么是递归呢&#xff1f; 递归其实是⼀种解决问题的⽅法&#xff0c;在C语⾔中&#xff0c;递归就是函数⾃…

阿里云服务器多少钱?2024年阿里云服务器租用费用表大全

2024年阿里云服务器租用价格表更新&#xff0c;云服务器ECS经济型e实例2核2G、3M固定带宽99元一年、ECS u1实例2核4G、5M固定带宽、80G ESSD Entry盘优惠价格199元一年&#xff0c;轻量应用服务器2核2G3M带宽轻量服务器一年61元、2核4G4M带宽轻量服务器一年165元12个月、2核4G服…

免费生成ios证书的方法(无需mac电脑)

使用hbuilderx的uniapp框架开发移动端程序很方便&#xff0c;可以很方便地开发出移动端的小程序和app。但是打包ios版本的app的时候却很麻烦&#xff0c;官方提供的教程需要使用mac电脑来生成证书&#xff0c;但是mac电脑却不便宜&#xff0c;一般的型号都差不多上万。 因此&a…

java_error_in_pycharm.hprof文件是什么?能删除吗?

java_error_in_pycharm.hprof文件是什么&#xff1f;能删除吗&#xff1f; &#x1f335;文章目录&#x1f335; &#x1f333;引言&#x1f333;&#x1f333;hprof格式文件介绍&#x1f333;&#x1f333;java_error_in_pycharm.hprof文件什么情况下能删除&#x1f333;&…

C#静态数组删除数组元素不改变数组长度 vs 动态数组删除数组元素改变数组长度

目录 一、使用的方法 1.对静态数组删除指定长度并不改变数长度的方法 &#xff08;1&#xff09;静态数组 &#xff08;2&#xff09;对静态数组删除元素不得改变其长度 2.对动态数组删除指定长度并改变数长度的方法 &#xff08;1&#xff09;动态数组 &#xff08;2&a…

故障诊断 | 一文解决,TCN时间卷积神经网络模型的故障诊断(Matlab)

效果一览 文章概述 故障诊断 | 一文解决,TCN时间卷积神经网络模型的故障诊断(Matlab) 模型描述 时间卷积神经网络(TCN)是一种用于序列数据建模和预测的深度学习模型。它通过卷积操作在时间维度上对序列数据进行特征提取,并且可以处理可变长度的输入序列。 要使用TCN进行…

L1-080 乘法口诀数列

一、题目 二、解题思路 三、代码 #include<iostream> using namespace std; int main() {int a1,a2,n;cin>>a1>>a2>>n;if(n1){cout<<a1;return 0; }int a[n*2];cout<<a1<<" "<<a2;a[0]a1;a[1]a2;for(int i2,j2;i&l…

05 06 Verilog基础语法与应用讲解

05. 1. 位操作 计数器实验升级&#xff0c;设计8个LED灯以每个0.5s的速率循环闪烁&#xff08;跑马灯&#xff09; 1.1 方法1&#xff1a;使用移位操作符<<来控制led灯的循环亮灭 设计代码 Verilog中&#xff0c;判断操作的时候不加位宽限定是可以的&#xff0c;比如i…

Qt QVariant类应用

QVariant类 QVariant类本质为C联合(Union)数据类型&#xff0c;它可以保存很多Qt类型的值&#xff0c;包括 QBrush&#xff0c;QColor&#xff0c;QString等等&#xff0c;也能存放Qt的容器类型的值。 QVariant::StringList 是 Qt 定义的一个 QVariant::type 枚举类型的变量&…