1、异步组件
在vue3.0除了同步组件,还添加了异步组件的定义与使用, 使用关键字defineAsyncComponent进行定义异步组件, defineAsyncComponent可以接受一个返回 Promise
的工厂函数。Promise 的 resolve
回调应该在服务端返回组件定义后被调用。你也可以调用 reject(reason)
来表示加载失败。
案例一
let asyncComp = Vue.defineAsyncComponent(() => { return new Promise(resolve => { setTimeout(() => { resolve({ template: `<button @click='testEvent'>button</button>`, methods: { testEvent() { console.log('yes') } } }) }, 3000) }) }) const app = Vue.createApp({ template: `<div>this is test <asyncComp/></div>`, components: { asyncComp } }) app.mount('#root')
案例二
import { defineAsyncComponent } from 'vue' const AsyncComp = defineAsyncComponent(() => import('./components/AsyncComponent.vue') ) app.component('async-component', AsyncComp)
注意:以上defineAsyncComponent里的方法是用在路由中的方法
案例三
import { defineAsyncComponent } from 'vue'
const AsyncComp = defineAsyncComponent({
// 工厂函数
loader: () => import('./Foo.vue')
// 加载异步组件时要使用的组件
loadingComponent: LoadingComponent,
// 加载失败时要使用的组件
errorComponent: ErrorComponent,
// 在显示 loadingComponent 之前的延迟 | 默认值:200(单位 ms)
delay: 200,
// 如果提供了 timeout ,并且加载组件的时间超过了设定值,将显示错误组件
// 默认值:Infinity(即永不超时,单位 ms)
timeout: 3000,
// 定义组件是否可挂起 | 默认值:true
suspensible: false,
/**
*
* @param {*} error 错误信息对象
* @param {*} retry 一个函数,用于指示当 promise 加载器 reject 时,加载器是否应该重试
* @param {*} fail 一个函数,指示加载程序结束退出
* @param {*} attempts 允许的最大重试次数
*/
onError(error, retry, fail, attempts) {
if (error.message.match(/fetch/) && attempts <= 3) {
// 请求发生错误时重试,最多可尝试 3 次
retry()
} else {
// 注意,retry/fail 就像 promise 的 resolve/reject 一样:
// 必须调用其中一个才能继续错误处理。
fail()
}
}
})
注意:当异步组件加载完成后,就可以当作普通的组件来使用了
2、mixins的用法
vue3相对于vue2 mixins的用法没有太大的变化,但是可以注册全局的mixin
import ui from 'v_ui' import { defineAsyncComponent } from 'vue' const ABC = defineAsyncComponent(() => { return new Promise(resolve => { resolve(ui.XButton) }) }) //mixins文件中定义 const mixin = { created () { console.log('this is mixins created') }, mounted () { console.log('this is mixins mounted') }, components: { ABC } } export default mixin //main.js中进行调用 const app = createApp(App).use(store).use(router) app.mixin(mixin)
注意:一旦定义全局的mixin后,所有的组件都会被注入,并且可以使用,所以不会轻易使用
3、指令的使用
vue3相对于vue2来讲指令的生命周期做了一些调整,使指令的生命周期更加迎合vue的生命周期函数,其他的与vue2的使用出入不大
const app = Vue.createApp({ template: '<div v-check>this is test</div>' }) app.directive('check', { beforeMount(el, binding, vnode) { console.log('beforeMount', el, binding, vnode) }, mounted(el, binding, vnode) { console.log('mounted', arguments) }, beforeUpdate(el, binding, vnode) { console.log('beforeUpdate', el, binding, vnode) }, updated(el, binding, vnode) { console.log('updated', el, binding, vnode) }, beforeUnmount(el, binding, vnode) { console.log('beforeUnmount', el, binding, vnode) }, unmounted(el, binding, vnode) { console.log('unmounted', el, binding, vnode) } }) //注意:如果一个指令里面只有mounted与updated,那么这个就可以合并成一个函数 app.directive('check', (el, binding, vnode) => { console.log('check', el, binding, vnode) }) app.mount('#root')
4、传送门teleport的使用
vue3相对于vue2添加了一个新特性,即传送门,即通过传送门这个特性,可以把节点挂载到指定的节点上
<style> .container{ width: 200px; height: 200px; background: yellow; position: relative; } .other { width: 400px; height: 400px; background: pink; position: absolute; left: 400px; } .mask{ position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0, 0, 0, 0.4); } </style> <script> const app = Vue.createApp({ template: `<div class='container'> <div class='other'></div> <button @click="clickEvent">按钮</button> <teleport to='body'> <div class='mask' v-show='sign' @click.stop.prevent='() => sign = false'></div> </teleport> </div>`, data() { return { sign: false } }, methods: { clickEvent() { this.sign = !this.sign } } }) app.mount('#root') </script>
注意:teleport这个标签的to接收 body, 以及id
5、render函数的使用
在render函数上vue3区别于vue2在于,render函数参数的变化,vue3的h函数相当于$createElement函数,不再通过参数的形式传递,而是通过vue对象中获取h函数
const app = Vue.createApp({}) app.component('my-title', { render() { return Vue.h( 'h1', // 标签名称 this.blogTitle // 标签内容 ) }, props: { blogTitle: { type: String, required: true } } }) app.mount('#app')
注意:render函数的优先级要高到template,因为template在底层也是会编译成render函数的形式