十二、异步组件&代码分包&suspense
顶层axios:在setup中,可以不需要使用async,它会自动编译成这个
<script setup lang="ts">
import axios from 'axios'const {data:{data}} = await axios({url:"http://localhost:8080/data.json"
})
<script/>
异步加载,分包
<script setup lang="ts">
import { defineAsyncComponent } from 'vue'
const Dialog = defineAsyncComponent(() => import('../../components/Dialog/index.vue'))//完整写法
const AsyncComp = defineAsyncComponent({// 加载函数loader: () => import('./Foo.vue'),// 加载异步组件时使用的组件loadingComponent: LoadingComponent,// 展示加载组件前的延迟时间,默认为 200msdelay: 200,// 加载失败后展示的组件errorComponent: ErrorComponent,// 如果提供了一个 timeout 时间限制,并超时了// 也会显示这里配置的报错组件,默认值是:Infinitytimeout: 3000
})
</script>
<suspense>
组件有两个插槽。它们都只接收一个直接子节点。default
插槽里的节点会尽可能展示出来。如果不能,则展示 fallback
插槽里的节点。
<Suspense><template #default><Dialog><template #default><div>我在哪儿</div></template></Dialog></template><template #fallback><div>loading...</div></template>
</Suspense>
十三、Teleport传送组件
Teleport 是一种能够将我们的模板渲染至指定DOM节点,不受父级style、v-show等属性影响,但data、prop数据依旧能够共用的技术;类似于 React 的 Portal。
主要解决的问题 因为Teleport节点挂载在其他指定的DOM节点下,完全不受父级style样式影响
通过to 属性 插入指定元素位置 to="body" 便可以将Teleport 内容传送到指定位置
也可以自定义传送位置 支持 class id等 选择器
使用disabled 设置为 true则 to属性不生效 false 则生效
<Teleport :disabled="false" to="body"><Loading></Loading>
</Teleport>
十四、keepalive
有时候我们不希望组件被重新渲染影响使用体验;或者处于性能考虑,避免多次重复渲染降低性能。而是希望组件可以缓存下来,维持当前的状态。这时候就需要用到keep-alive
组件。
开启keep-alive 生命周期的变化
初次进入时: onMounted> onActivated
退出后触发 deactivated
再次进入:
只会触发 onActivated
事件挂载的方法等,只执行一次的放在 onMounted中;组件每次进去执行的方法放在 onActivated中
<keep-alive :include="" :exclude="" :max=""></keep-alive>
十五、transition动画组件
<button @click='flag = !flag'>切换</button>
<transition name='fade'><div v-if='flag' class="box"></div>
</transition>
自定义过度类名
enter-from-class
enter-active-class
enter-to-class
leave-from-class
leave-active-class
leave-to-class
十六、依赖注入Provide / Inject
父组件:
import { provide } from 'vue';
import Child from './components/Child.vue';
provide("color","我是顶级父组件")
子组件:
const color = inject("color")
console.log(color);
十七、兄弟之间的传参
方法一:传给父亲--》儿子
方法二:bus(全局事件总线)传参。废除了
方法三:mitt
安装
npm i mitt -S
全局引入mitt
import mitt from 'mitt'
const Mit = mitt()
//TypeScript注册
// 由于必须要拓展ComponentCustomProperties类型才能获得类型提示
declare module "vue" {export interface ComponentCustomProperties {$Bus: typeof Mit}
}const app = createApp(App)
// 挂载到全局组件
app.config.globalProperties.$Bus = Mit
app.use(store).use(router).mount('#app')
A组件派发事件
<template><div><button @click="emit">点我派发事件</button></div>
</template><script setup lang='ts'>
import { getCurrentInstance } from 'vue'
const instance = getCurrentInstance();
const emit = () => {instance?.proxy?.$Bus.emit('on-click', 100)
}
</script>
B组件接收事件
import { getCurrentInstance } from 'vue'
const instance = getCurrentInstance()
instance?.proxy?.$Bus.on('on-click', (num) => {console.log(num,'===========>B')
})
监听所有事件:
instance?.proxy?.$Bus.on('*',(type,num)=>{console.log(type,num,'===========>B')
})
移除监听的事件:
instance?.proxy?.$Bus.off('on-num',Fn)//unListen
移除所有监听事件:
instance?.proxy?.$Bus.all.clear()
十八、自定义指令
自定义指令:简写。鉴权 directer
<template><div><button v-has-show="'create'">创建</button><button v-has-show="'edit'">新建</button><button v-has-show="'del'">删除</button></div>
</template><script setup lang='ts'>
import type { Directive } from 'vue';const permission = ["create","edit","del"
]//自定义指令
const vHasShow:Directive<HTMLElement,string> = (el,bingding) =>{console.log(el,bingding);if(!permission.includes(bingding.value)){el.style.display = 'none'}
}</script>
十九、自定义Hooks
- Vue3 的 hook函数 可以帮助我们提高代码的复用性, 让我们能在不同的组件中都利用 hooks 函数
二十、Vue3定义全局函数和变量
设置
const app = createApp({})
app.config.globalProperties.$http = () => {}
读取
const app = getCurrentInstance()
console.log(app?.proxy?.$name)
二十一、自定Vue3插件
二十二、样式穿透
vue2:/deep/ vue3:deep(类名)