vue3学习(十三)---全局定义事件及编写vue插件
vue
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
项目地址:https://gitcode.com/gh_mirrors/vu/vue
免费下载资源
·
文章目录
全局定义事件 globalProperties
之前我们使用vue2
的时候使用Vue.prototype
会将loading、toast、axios等定义为全局属性方便后期使用。
Vue3
没有prototype
属性,使用app.config.globalProperties
来绑定属性和事件。
const app = createApp({})
app.config.globalProperties.$http = () => {}
自定义全局过滤器
声明文件要写,不然TS无法正确类型 推导
app.config.globalProperties.$filters = {
format<T extends any>(str: T): string {
return `$${str}`
}
}
声明文件 不然TS无法正确类型 推导
type Filter = {
format<T>(str: T): string
}
// 声明要扩充@vue/runtime-core | vue 包的声明.
// 这里扩充"ComponentCustomProperties"接口, 因为他是vue3中实例的属性的类型.
declare module 'vue' {
export interface ComponentCustomProperties {
$filters: Filter
}
}
读取
template中可以直接读取
<template>
<div>
{($filters.format("的飞机')}}
</div>
</template>
js中需要getCurrentInstance获取当前实例,然后在实例中获取
import { getCurrentInstance, ComponentInternalInstance } from 'vue';
const { appContext } = <ComponentInternalInstance>getCurrentInstance()
console.log(appContext.config.globalProperties.$filters);
推荐第二种方式
import {ref,reactive,getCurrentInstance} from 'vue'
const app = getCurrentInstance()
console.log(app?.proxy?.$filters.format('js'))
扩展:vueuse库
编写Vue3插件
插件是自包含的代码,通常向 Vue
添加全局级功能。你如果是一个对象需要有install
方法Vue
会帮你自动注入到install
方法。
你如果是function
就直接当install
方法去使用。
1.编写loading.vue页面
<template>
<div v-if="isShow" class="loading">
<div class="loading-content">Loading...</div>
</div>
</template>
<script setup lang='ts'>
import { ref } from 'vue';
const isShow = ref(false)//定位loading 的开关
const show = () => {
isShow.value = true
}
const hide = () => {
isShow.value = false
}
setup形式默认不向外部暴露属性和方法,无法像vue2一样直接能获取到子组件的实例方法
defineExpose 对外暴露 当前组件的属性和方法
defineExpose({
isShow,
show,
hide
})
</script>
<style scoped lang="less">
.loading {
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.8);
display: flex;
justify-content: center;
align-items: center;
&-content {
font-size: 30px;
color: #fff;
}
}
</style>
2. 编写核心loading.ts
import { createVNode, render, VNode, App } from 'vue';
import Loading from './index.vue'
export default {
install(app: App) {
createVNode vue提供的底层方法 可以给我们组件创建一个虚拟DOM 也就是Vnode
const 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()
}
}
}
3.main.ts中注册、编写声明文件
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')
4.页面中使用
<template>
<div></div>
</template>
<script setup lang='ts'>
import { ref,reactive,getCurrentInstance} from 'vue'
const instance = getCurrentInstance()
const loading = instance?.proxy?.$Loading;
loading.show()
setTimeout(()=>{
loading.hide()
},5000)
// console.log(instance)
</script>
<style>
*{
padding: 0;
margin: 0;
}
</style>
5.手写源码
import type { App } from 'vue'
import { app } from './main'
interface Use {
install: (app: App, ...options: any[]) => void
}
const installedList = new Set()
export function MyUse<T extends Use>(plugin: T, ...options: any[]) {
if(installedList.has(plugin)){
return console.warn('重复添加插件',plugin)
}else{
plugin.install(app, ...options)
installedList.add(plugin)
}
}
GitHub 加速计划 / vu / vue
207.54 K
33.66 K
下载
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
最近提交(Master分支:2 个月前 )
73486cb5
* chore: fix link broken
Signed-off-by: snoppy <michaleli@foxmail.com>
* Update packages/template-compiler/README.md [skip ci]
---------
Signed-off-by: snoppy <michaleli@foxmail.com>
Co-authored-by: Eduardo San Martin Morote <posva@users.noreply.github.com> 4 个月前
e428d891
Updated Browser Compatibility reference. The previous currently returns HTTP 404. 5 个月前
更多推荐
已为社区贡献3条内容
所有评论(0)