自动注册components目录下所有vue组件并以组件的文件名为组件的名称
// components/index.ts
import { 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
}
使用这个插件
import { createApp } from 'vue'
import App from './App.vue'
import MyComponents from './components'
createApp(App).use(MyComponents).mount('#app')
自动注册全局组件虽然很方便,但在使用时缺少了ts类型提示,下面介绍一下为全局组件添加类型提示
这需要我们自己编写.d.ts声明文件
// src/typings/component.d.ts
export {}
declare module 'vue' {
export interface GlobalComponents {
EsDialog: typeof import('../components/Dialog.vue')['default']
}
}
图片预览是一个比较常用的功能,封装成函数调用可以简化我们使用的方式
基于 element-plus 的 ElImageViewer 组件
对于有类似的功能都可以使用这种方式,例如我们想使用函数调用的方式弹窗
// 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!)
}
调用
preview({
urlList: ['https://fuss10.elemecdn.com/0/6f/e35ff375812e6b0020b6b4e8f9583jpeg.jpeg'],
initialIndex: 0
})
这节主要是vangle组件库的icon组件封装方式的介绍,为想自己手动封装svgIcon组件的朋友可以作个参考
以下下是代码实现
<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>
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.clientX
const downY = e.clientY
const { offsetX, offsetY } = transform
// 获取拖拽目标的位置和尺寸信息
const targetRect = targetRef.value!.getBoundingClientRect()
const targetTop = targetRect.top
const targetWidth = targetRect.width
const targetHeight = targetRect.height
// 计算拖拽目标在页面中的可移动范围
const clientWidth = document.documentElement.clientWidth
const clientHeight = document.documentElement.clientHeight
const minLeft = -targetRect.left + offsetX
const minTop = -targetTop + offsetY
const maxLeft = clientWidth - targetRect.left - targetWidth + offsetX
const maxTop = clientHeight - targetTop - targetHeight + offsetY
const 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,用于保存拖拽过程中的偏移量。
针对 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 键,就会自动插入这段模板代码。你可以根据需要自行修改和完善这个模板。
先到这吧!想到了再更新...
作者:幽月之格
链接:https://juejin.cn/post/7256975111562674233
来源:稀土掘金
安装 vue-cli3,在使用任何 @vue/composition-api 提供的能力前,必须先通过 Vue.use() 进行安装,安装插件后,您就可以使用新的 Composition API 来开发组件了。
Vue3 就是基于 Proxy 对其数据响应系统进行了重写,现在这部分可以作为独立的模块配合其他框架使用。数据响应可分为三个阶段: 初始化阶段 --> 依赖收集阶段 --> 数据响应阶段
在2019.10.5日发布了Vue3.0预览版源码,但是预计最早需要等到 2020 年第一季度才有可能发布 3.0 正式版。新版Vue 3.0计划并已实现的主要架构改进和新功能:
有关即将发布的 Vue.js 的第 3 个主要版本的信息越来越多。通过下面的讨论,虽然还不能完全确定其所有内容,但是我们可以放心地认为,它将是对当前版本(已经非常出色)的巨大改进。 Vue 团队在改进框架 API 方面做得非常出色
用新的 Vue 3 编写的程序效果会很好,但性能并不是最重要的部分。对开发人员而言,最重要的是新版本将会怎样影响我们编写代码的方式。如你所料,Vue 3 带来了许多令人兴奋的新功能。值得庆幸的是
emmm 用半天时间捋顺了 vue3 的源码,再用半天时间写了个 mini 版……我觉得我也是没谁了,vue3 的源码未来一定会烂大街的,我们越早的去复现它,就……emm可以越早的装逼hhh
10 月 5 日,尤雨溪在 GitHub 开放了 Vue 3.0 处于 pre-alpha 状态的源码,这次 Vue 3.0 Updates 版本的更新,将带来五项重大改进:速度体积、可维护性、面向原生、易用性
从一开始使用 Vue 时,对于之前的 jq 开发而言,一个很大的区别就是基本不用手动操作 dom,data 中声明的数据状态改变后会自动重新渲染相关的 dom。换句话说就是 Vue 自己知道哪个数据状态发生了变化及哪里有用到这个数据需要随之修改。
Vue 开发团队终于在今天发布了 3.0-beta.1 版本,也就是测试版。通常来说,从测试版到正式版,只会修复 bug,不会引入新功能,或者删改老功能。所以,如果你对新版本非常感兴趣,或者有新项目即将上马,不妨尝试一下新版本
对于大多数单页应用程序而言,管理路由是一项必不可少的功能。随着新版本的Vue Router处于Alpha阶段,我们已经可以开始查看下一个版本的Vue中它是如何工作的。
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!