1. 程式人生 > 其它 >vue3.x自定義載入指令-花瓣載入元件

vue3.x自定義載入指令-花瓣載入元件

修改以前寫的2.x的載入指令

vue2.x自定義指令-花瓣載入元件傳送門

載入元件 loadingComponent/LoadingComponent1.vue
<template>
    <div class="LoadingComponent" v-show="visible">
        <div class="modal"></div>
        <div class="out">
            <div class="fade-in">
                <div class
="container"> <div class="one common"></div> <div class="two common"></div> <div class="three common"></div> <div class="four common"></div> <div class
="five common"></div> <div class="six common"></div> <div class="seven common"></div> <div class="eight common"></div> </div> </div> </div> </div> </template> <script lang="
ts" setup>import { ref } from 'vue'; const visible = ref(false) defineExpose({ visible }) </script> <style scoped lang="less"> .LoadingComponent { width: 100%; height: 100%; z-index: 11111111111111111111; position: absolute; top: 0px; .modal { width: 100%; height: 100%; position: absolute; top: 0px; background-color: white; opacity: 0.5; } .container { width: 40vw; height: 40vw; position: absolute; left: 0; right: 0; top: 0; bottom: 0; margin: auto; overflow: hidden; } .common { height: 4vw; max-height: 100%; overflow: auto; width: 2vw; margin: auto; max-width: 100%; position: absolute; // background-color: ; border-radius: 0vw 10vw 0vw 10vw; box-shadow: inset 0vw 0vw 0vw 0.1vw #ebc5e6, 0vw 0vw 1.5vw 0vw #e6cee2; } .one { transform: rotate(45deg); left: 0; right: 0; top: 0; bottom: 7.5vw; } .two { transform: rotate(90deg); left: 5.5vw; right: 0; top: 0; bottom: 5.5vw; } .three { transform: rotate(135deg); left: 7.5vw; right: 0; top: 0; bottom: 0; } .four { transform: rotate(180deg); left: 5.5vw; right: 0; top: 5.5vw; bottom: 0; } .five { transform: rotate(225deg); left: 0; right: 0; top: 7.5vw; bottom: 0; } .six { transform: rotate(270deg); left: 0; right: 5.5vw; top: 5.5vw; bottom: 0; } .seven { transform: rotate(315deg); left: 0; right: 7.5vw; top: 0; bottom: 0; } .eight { transform: rotate(360deg); left: 0; right: 5.5vw; top: 0; bottom: 5.5vw; } .one { animation: one 1s ease infinite; -moz-animation: one 1s ease infinite; /* Firefox */ -webkit-animation: one 1s ease infinite; /* Safari and Chrome */ -o-animation: one 1s ease infinite; /* Opera */ } @keyframes one { 0%, 100% { } 50% { background: ; box-shadow: inset 0vw 0vw 0vw 0.1vw #17e1e6, 0vw 0vw 1.5vw 0vw #17e1e6; } } .two { animation: two 1s 0.125s ease infinite; -moz-animation: two 1s 0.125s ease infinite; /* Firefox */ -webkit-animation: two 1s 0.125s ease infinite; /* Safari and Chrome */ -o-animation: two 1s 0.125s ease infinite; /* Opera */ } @keyframes two { 0%, 100% { } 50% { background: ; box-shadow: inset 0vw 0vw 0vw 0.1vw #17e1e6, 0vw 0vw 1.5vw 0vw #17e1e6; } } .three { animation: three 1s 0.25s ease infinite; -moz-animation: three 1s 0.25s ease infinite; /* Firefox */ -webkit-animation: three 1s 0.25s ease infinite; /* Safari and Chrome */ -o-animation: three 1s 0.25s ease infinite; /* Opera */ } @keyframes three { 0%, 100% { } 50% { background: ; box-shadow: inset 0vw 0vw 0vw 0.1vw #17e1e6, 0vw 0vw 1.5vw 0vw #17e1e6; } } .four { animation: four 1s 0.375s ease infinite; -moz-animation: four 1s 0.375s ease infinite; /* Firefox */ -webkit-animation: four 1s 0.375s ease infinite; /* Safari and Chrome */ -o-animation: four 1s 0.375s ease infinite; /* Opera */ } @keyframes four { 0%, 100% { } 50% { background: ; box-shadow: inset 0vw 0vw 0vw 0.1vw #17e1e6, 0vw 0vw 1.5vw 0vw #17e1e6; } } .five { animation: five 1s 0.5s ease infinite; -moz-animation: five 1s 0.5s ease infinite; /* Firefox */ -webkit-animation: five 1s 0.5s ease infinite; /* Safari and Chrome */ -o-animation: five 1s 0.5s ease infinite; /* Opera */ } @keyframes five { 0%, 100% { } 50% { background: ; box-shadow: inset 0vw 0vw 0vw 0.1vw #17e1e6, 0vw 0vw 1.5vw 0vw #17e1e6; } } .six { animation: six 1s 0.625s ease infinite; -moz-animation: six 1s 0.625s ease infinite; /* Firefox */ -webkit-animation: six 1s 0.625s ease infinite; /* Safari and Chrome */ -o-animation: six 1s 0.625s ease infinite; /* Opera */ } @keyframes six { 0%, 100% { } 50% { background: ; box-shadow: inset 0vw 0vw 0vw 0.1vw #17e1e6, 0vw 0vw 1.5vw 0vw #17e1e6; } } .seven { animation: seven 1s 0.75s ease infinite; -moz-animation: seven 1s 0.75s ease infinite; /* Firefox */ -webkit-animation: seven 1s 0.75s ease infinite; /* Safari and Chrome */ -o-animation: seven 1s 0.75s ease infinite; /* Opera */ } @keyframes seven { 0%, 100% { } 50% { background: ; box-shadow: inset 0vw 0vw 0vw 0.1vw #17e1e6, 0vw 0vw 1.5vw 0vw #17e1e6; } } .eight { animation: eight 1s 0.875s ease infinite; -moz-animation: eight 1s 0.875s ease infinite; /* Firefox */ -webkit-animation: eight 1s 0.875s ease infinite; /* Safari and Chrome */ -o-animation: eight 1s 0.875s ease infinite; /* Opera */ } @keyframes eight { 0%, 100% { } 50% { background: ; box-shadow: inset 0vw 0vw 0vw 0.1vw #17e1e6, 0vw 0vw 1.5vw 0vw #17e1e6; } } .container { animation: container 5s linear infinite; -moz-animation: container 5s linear infinite; /* Firefox */ -webkit-animation: container 5s linear infinite; /* Safari and Chrome */ -o-animation: container 5s linear infinite; /* Opera */ } @keyframes container { from { transform: rotate(0deg); } to { transform: rotate(-360deg); } } .progress { animation: progress 15s ease; -moz-animation: progress 15s ease; /* Firefox */ -webkit-animation: progress 15s ease; /* Safari and Chrome */ -o-animation: progress 15s ease; /* Opera */ } @keyframes progress { 0% { left: -24vw; } 10% { left: -20vw; } 30% { left: -16vw; } 50% { left: -12vw; } 65% { left: -10vw; } 80% { left: -4vw; } 100% { left: 0; } } .fade-in { animation: fade-in 2s ease; -moz-animation: fade-in 2s ease; /* Firefox */ -webkit-animation: fade-in 2s ease; /* Safari and Chrome */ -o-animation: fade-in 2s ease; /* Opera */ } @keyframes fade-in { from { opacity: 0; } to { opacity: 1; } } .out { animation: out 2s 15s ease; -moz-animation: out 2s 15s ease; /* Firefox */ -webkit-animation: out 2s 15s ease; /* Safari and Chrome */ -o-animation: out 2s 15s ease; /* Opera */ } @keyframes out { from { opacity: 1; } to { opacity: 0; } } } </style>

指令定義檔案 loadingComponent/index.ts

import LoadingComponent from './LoadingComponent1.vue'
import {
  createApp,
  nextTick,
} from "vue";

const appndChild = (el: any) => {
  el.appendChild(el.instance.$el);
}

const remove = (el: any) => {
  el.removeChild(el.instance.$el);
}


const toggleLoading = (el, binding) => {
  if (binding.value) {
    nextTick(() => {
      // 控制loading元件顯示
      el.instance.visible = true
      // 插入到目標元素
      appndChild(el)
    })
  } else {
    el.instance.visible = false
    remove(el)
  }
}

export default {
  mounted(el: any, bind: any) {
    const app = createApp(LoadingComponent);
    const instance: any = app.mount(document.createElement("div"));
    el.instance = instance;
    if (bind.value) {
      toggleLoading(el, bind)
    }
  },
  updated(el: any, bind: any) {
    if (bind.value !== bind.oldValue) {
      toggleLoading(el, bind)
    }
  },
  onUnmounted(el, bind: any) {
    el.instance && el.instance.$destroy()
  }
}

指令註冊 index.ts

import myLoadingDirective from "./loadingComponent";
export default (app) => {
  //自定義元件
  app.directive('myLoading', myLoadingDirective)
}

main.ts

import loadingdirectives from './directive/loading'
loadingdirectives(app)

使用

v-myLoading="loadingState"