使用vue3.0+ts写一个简单的插件

2021-01-13 18:57
2599
0
3
vue

使用vue3.0+ts写一个简单的插件

需求:实现一个全局的弹窗插件,例如使用ctx.xxx.show()这种方式

在src目录设置新建一个plugins文件夹,如图所示

index.ts代码:

// 插件注册
import { createVNode, render } from 'vue'
import type { App } from 'vue'

import ShareTip from './index.vue'

const Share: any = function(props: any) {

  const divEle: any =  document.querySelector('#share')

  if (!props.visible || divEle) {
    document.body.removeChild(divEle)
  }

  if (!props.visible) {
    return
  }

  const container = document.createElement('div')

  container.id = 'share'

  const vm = createVNode(ShareTip, props as any)

  render(vm, container)

  document.body.appendChild(container)

}

export default {

  install(app: App): void {

    app.config.globalProperties.$share = {

      show(title: string) {
        Share({ visible: true, title })
      },

      hide() {
        Share({ visible: false })
      }

    }

  }

}

 

index.vue代码

<!--分享引导提示窗-->
<template>
  <div v-if="active" class="share-tips" @click="hide">
    <img src="~@/assets/img/share_guide.png" />
    <div class="share-desc">
      <p>点击右上角</p>
      <p>{{ title }}</p>
    </div>
  </div>
</template>

<script lang="ts">
import { defineComponent, ref, watch, onMounted } from 'vue'

export default defineComponent({
  props: {
    title: {
      type: String
    },
    visible: {
      type: Boolean
    }
  },
  setup(props, ctx) {
    const active = ref(props.visible)

    onMounted(() => {
      active.value = props.visible
    })

    watch(() => props.visible, (res) => {
      active.value = res
    })

    const show = () => {
      active.value = true
      ctx.emit('update:visible', true)
    }

    const hide = () => {
      active.value = false
      ctx.emit('update:visible', false)
    }

    return {
      active,
      show,
      hide,
    }
  }
})
</script>

<style scoped lang="scss">
.share-tips {
  position: fixed;
  background: rgba(0,0,0,0.7);
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  z-index: 9;
  display: flex;
  align-items: center;
  justify-content: center;
  img {
    position: absolute;
    right: 0;
    top: 0;
    width: 285px;
    height: 330px;
  }
  .share-desc {
    max-width: 500px;
    p {
      font-size: 32px;
      color: #ffffff;
      margin-bottom: 24px;
    }
  }
}
</style>

 

在main.ts

import Share from './plugins/share'

app
.use(Store)
.use(Router)
.use(Share)
.use(Vant)
.mount('#app')

在代码中调用:

<script lang="ts">
import { defineComponent, getCurrentInstance } from 'vue'

export default defineComponent({
  setup() {

    const { ctx }: any = getCurrentInstance() 

    const share = () => {
      ctx.$share.show('分享给门店报名参赛')
    }

    return {
      share
    }

  }
})
</script>

 

 

支付宝微信
3
关注公众号获取更多内容
egg sequelize的op模块
结合lazyload实现文章页里面的图片预加载
暂无评论,快抢沙发吧
不支持canvas
春季
夏季
秋季
冬季
暗黑
简约
小清新