even

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

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函数的形式

 

posted on 2021-05-14 22:37  even_blogs  阅读(139)  评论(0编辑  收藏  举报