VUE3学习 第六章 V3自动引入插件、深入v-model、自定义指令directive、自定义Hooks、编写Vue3插件、
创始人
2024-04-06 02:07:52
0

一、V3自动引入插件

unplugin-auto-import/vite
vite配置

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import VueJsx from '@vitejs/plugin-vue-jsx'
import AutoImport from 'unplugin-auto-import/vite'
// https://vitejs.dev/config/
export default defineConfig({plugins: [vue(),VueJsx(),AutoImport({imports:['vue'],dts:"src/auto-import.d.ts"})]
})

配置完成之后使用ref reactive watch 等 无须import 导入 可以直接使用

GitHub - antfu/unplugin-auto-import: Auto import APIs on-demand for Vite, Webpack and Rollup

二、v-model

TIps 在Vue3 v-model 是破坏性更新的
v-model在组件里面也是很重要的
v-model 其实是一个语法糖 通过props 和 emit组合而成的

  1. 默认值的改变
    prop:value -> modelValue;
    事件:input -> update:modelValue;
    v-bind 的 .sync 修饰符和组件的 model 选项已移除
    新增 支持多个v-model
    新增 支持自定义 修饰符 Modifiers

1. v-model 单个绑定 和 多个绑定

案例(绑定一个 v-model 和 绑定多个 v-model): 子组件


父组件


2. 自定义修饰符

添加到组件 v-model 的修饰符将通过 modelModifiers prop 提供给组件。在下面的示例中,我们创建了一个组件,其中包含默认为空对象的 modelModifiers prop

5. 案例自定义拖拽指令

四、自定义Hooks

Vue3 自定义Hook
主要用来处理复用代码逻辑的一些封装
这个在vue2 就已经有一个东西是Mixins混入

mixins就是将这些多个相同的逻辑抽离出来,各个组件只需要引入mixins,就能实现一次写代码,多组件受益的效果。

弊端就是 会涉及到覆盖的问题

  1. 组件的data、methods、filters会覆盖mixins里的同名data、methods、filters。
  2. 第二点就是 变量来源不明确(隐式传入),不利于阅读,使代码变得难以维护。

1. Vue3 的自定义的hook

Vue3 的 hook函数 相当于 vue2 的 mixin, 不同在与 hooks 是函数

Vue3 的 hook函数 可以帮助我们提高代码的复用性, 让我们能在不同的组件中都利用 hooks 函数

Vue3 hook 库Get Started | VueUse

案例:

// 这个就是 自己封装的 hook文件
import { onMounted } from 'vue'type Options = {el: string
}type Return = {Baseurl: string | null
}
export default function (option: Options): Promise {return new Promise((resolve) => {onMounted(() => {const file: HTMLImageElement = document.querySelector(option.el) as HTMLImageElement;file.onload = ():void => {resolve({Baseurl: toBase64(file)})}})const toBase64 = (el: HTMLImageElement): string => {const canvas: HTMLCanvasElement = document.createElement('canvas')const ctx = canvas.getContext('2d') as CanvasRenderingContext2Dcanvas.width = el.widthcanvas.height = el.heightctx.drawImage(el, 0, 0, canvas.width,canvas.height)console.log(el.width);return canvas.toDataURL('image/png')}})}

五、Vue3定义全局函数和变量

1. globalProperties

由于Vue3 没有Prototype 属性 使用 app.config.globalProperties 代替 然后去定义变量和函数

// 之前 (Vue 2.x)
Vue.prototype.$http = () => {}
// 之后 (Vue 3.x)
const app = createApp({})
app.config.globalProperties.$http = () => {}

2. 过滤器 案例(Vue3 移除了 filters)

app.config.globalProperties.$filters = {format(str: T): string {return `$${str}`}
}

声明文件 不然TS无法正确类型 推导

type Filter = {format: (str: T) => T}
// 声明要扩充@vue/runtime-core包的声明.
// 这里扩充"ComponentCustomProperties"接口, 因为他是vue3中实例的属性的类型.declare module '@vue/runtime-core' {export interface ComponentCustomProperties {$filters: Filter  // 上面是写死的!   主要是这里, 如果还有别的 在下面添加就可以了}}

setup 读取值

import { getCurrentInstance, ComponentInternalInstance } from 'vue';const { appContext } = getCurrentInstance()console.log(appContext.config.globalProperties.$filters);

六、编写Vue3插件

插件是自包含的代码,通常向 Vue 添加全局级功能。你如果是一个对象需要有install方法Vue会帮你自动注入到install 方法 你如果是function 就直接当install 方法去使用

1. 使用插件

在使用 createApp() 初始化 Vue 应用程序后,你可以通过调用 use() 方法将插件添加到你的应用程序中

2. 案例 实现一个 loading 全局插件

  1. Loading.Vue 编写 loading 组件 并对外暴露方法和属性

  1. Loading.ts 注入到install 方法中
import {  createVNode, render, VNode, App } from 'vue';
import Loading from './index.vue'export default {install(app: App) {//createVNode vue提供的底层方法 可以给我们组件创建一个虚拟DOM 也就是Vnodeconst vnode: VNode = createVNode(Loading)//render 把我们的Vnode 生成真实DOM 并且挂载到指定节点render(vnode, document.body)// Vue 提供的全局配置 可以自定义app.config.globalProperties.$loading = {show: () => vnode.component?.exposed?.show(),hide: () => vnode.component?.exposed?.hide()}}
}
  1. Main.ts 主要是 挂载 并声明一下
import Loading from './components/loading'let app = createApp(App)
app.use(Loading)  // 挂载type Lod = {show: () => void,hide: () => void
}
//编写ts loading 声明文件放置报错 和 智能提示
declare module '@vue/runtime-core' {export interface ComponentCustomProperties {$loading: Lod}
}app.mount('#app')
  1. 使用方法


3. Vue use 源码手写

import type { App } from 'vue'
import { app } from './main'interface Use {install: (app: App, ...options: any[]) => void
}const installedList = new Set()export function MyUse(plugin: T, ...options: any[]) {if(installedList.has(plugin)){return console.warn('重复添加插件',plugin)}else{plugin.install(app, ...options)installedList.add(plugin)}
}

相关内容

热门资讯

保存时出现了1个错误,导致这篇... 当保存文章时出现错误时,可以通过以下步骤解决问题:查看错误信息:查看错误提示信息可以帮助我们了解具体...
汇川伺服电机位置控制模式参数配... 1. 基本控制参数设置 1)设置位置控制模式   2)绝对值位置线性模...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
表格中数据未显示 当表格中的数据未显示时,可能是由于以下几个原因导致的:HTML代码问题:检查表格的HTML代码是否正...
本地主机上的图像未显示 问题描述:在本地主机上显示图像时,图像未能正常显示。解决方法:以下是一些可能的解决方法,具体取决于问...
表格列调整大小出现问题 问题描述:表格列调整大小出现问题,无法正常调整列宽。解决方法:检查表格的布局方式是否正确。确保表格使...
不一致的条件格式 要解决不一致的条件格式问题,可以按照以下步骤进行:确定条件格式的规则:首先,需要明确条件格式的规则是...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...