Browse Source

chore: structure change

xiaoxian521 4 years ago
parent
commit
f4cd720ce8
43 changed files with 568 additions and 486 deletions
  1. 125 373
      package-lock.json
  2. 1 1
      package.json
  3. 10 0
      src/components/BreadCrumb/index.ts
  4. 1 1
      src/components/BreadCrumb/src/BreadCrumb.vue
  5. 10 0
      src/components/Cropper/index.ts
  6. 127 0
      src/components/Cropper/src/Cropper.tsx
  7. 3 0
      src/components/Cropper/src/index.ts
  8. 10 0
      src/components/Flop/index.ts
  9. 0 0
      src/components/Flop/src/Flipper.vue
  10. 2 1
      src/components/Flop/src/index.vue
  11. 10 0
      src/components/HamBurger/index.ts
  12. 1 1
      src/components/HamBurger/src/HamBurger.vue
  13. 20 0
      src/components/Map/index.ts
  14. 4 2
      src/components/Map/src/Amap.vue
  15. 1 0
      src/components/Map/src/BaiduMap.vue
  16. 1 1
      src/components/countTo/index.ts
  17. 1 1
      src/components/countTo/src/countTo.tsx
  18. 2 8
      src/components/countTo/src/props.ts
  19. 2 1
      src/components/info/index.vue
  20. 1 1
      src/components/selector/index.ts
  21. 1 1
      src/components/selector/src/index.ts
  22. 1 1
      src/components/selector/src/selector.tsx
  23. 0 3
      src/components/splitPane/index.vue
  24. 0 43
      src/echarts/index.ts
  25. 8 8
      src/layout/components/Navbar.vue
  26. 2 2
      src/router/index.ts
  27. 4 0
      src/utils/mitt.ts
  28. 39 0
      src/utils/useAttrs.ts
  29. 0 0
      src/views/components/count-to/index.vue
  30. 22 14
      src/views/components/cropping/index.vue
  31. 0 0
      src/views/components/flow-chart/index.vue
  32. 3 3
      src/views/components/map/index.vue
  33. 1 1
      src/views/components/selector/index.vue
  34. 1 1
      src/views/components/split-pane/index.vue
  35. 4 2
      src/views/components/video/index.vue
  36. 4 4
      src/views/login.vue
  37. 3 3
      src/views/register.vue
  38. 6 6
      src/views/welcome.vue
  39. 12 3
      tsconfig.json
  40. 99 0
      types/global.d.ts
  41. 26 0
      types/index.d.ts
  42. 0 0
      types/shims-tsx.d.ts
  43. 0 0
      types/shims-vue.d.ts

File diff suppressed because it is too large
+ 125 - 373
package-lock.json


+ 1 - 1
package.json

@@ -35,7 +35,7 @@
     "wangeditor": "^4.0.3",
     "xe-ajax": "^4.0.5",
     "xe-utils": "^3.1.12",
-    "xgplayer": "^2.18.3"
+    "xgplayer": "^2.19.1"
   },
   "devDependencies": {
     "@types/mockjs": "^1.0.3",

+ 10 - 0
src/components/BreadCrumb/index.ts

@@ -0,0 +1,10 @@
+import { App } from "vue"
+import breadCrumb from "./src/BreadCrumb.vue"
+
+export const BreadCrumb = Object.assign(breadCrumb, {
+  install(app: App) {
+    app.component(breadCrumb.name, breadCrumb)
+  }
+})
+
+export default BreadCrumb

+ 1 - 1
src/components/breadCrumb/index.vue → src/components/BreadCrumb/src/BreadCrumb.vue

@@ -21,7 +21,7 @@ import { ref, defineComponent, watch, Ref } from "vue";
 import { useRoute, useRouter, RouteLocationMatched } from "vue-router";
 
 export default defineComponent({
-  name: "breadCrumb",
+  name: "BreadCrumb",
   setup() {
     const levelList: Ref<RouteLocationMatched[]> = ref([]);
     const route = useRoute();

+ 10 - 0
src/components/Cropper/index.ts

@@ -0,0 +1,10 @@
+import { App } from "vue"
+import cropper from "./src/Cropper"
+
+export const Cropper = Object.assign(cropper, {
+  install(app: App) {
+    app.component(cropper.name, cropper)
+  }
+})
+
+export default Cropper

+ 127 - 0
src/components/Cropper/src/Cropper.tsx

@@ -0,0 +1,127 @@
+import type { CSSProperties } from 'vue'
+
+import { defineComponent, onBeforeMount, nextTick, ref, unref, computed, PropType, getCurrentInstance } from 'vue'
+
+import { useAttrs } from '/@/utils/useAttrs'
+import { emitter } from '/@/utils/mitt'
+
+import Cropper from 'cropperjs'
+import 'cropperjs/dist/cropper.css'
+
+type Options = Cropper.Options
+
+const defaultOptions: Cropper.Options = {
+  aspectRatio: 16 / 9,
+  zoomable: true,
+  zoomOnTouch: true,
+  zoomOnWheel: true,
+  cropBoxMovable: true,
+  cropBoxResizable: true,
+  toggleDragModeOnDblclick: true,
+  autoCrop: true,
+  background: true,
+  highlight: true,
+  center: true,
+  responsive: true,
+  restore: true,
+  checkCrossOrigin: true,
+  checkOrientation: true,
+  scalable: true,
+  modal: true,
+  guides: true,
+  movable: true,
+  rotatable: true,
+}
+export default defineComponent({
+  name: "Cropper",
+  props: {
+    src: {
+      type: String,
+      required: true,
+    },
+    alt: {
+      type: String,
+    },
+    width: {
+      type: [String, Number],
+      default: '',
+    },
+    height: {
+      type: [String, Number],
+      default: '360px',
+    },
+    crossorigin: {
+      type: String || Object,
+      default: undefined,
+    },
+    imageStyle: {
+      type: Object as PropType<CSSProperties>,
+      default: {},
+    },
+    options: {
+      type: Object as PropType<Options>,
+      default: {},
+    }
+  },
+  setup(props) {
+    let vm: any
+    const cropper: any = ref<Nullable<Cropper>>(null)
+
+    const isReady = ref(false)
+
+    const getImageStyle = computed(
+      (): CSSProperties => {
+        return {
+          height: props.height,
+          width: props.width,
+          maxWidth: '100%',
+          ...props.imageStyle,
+        }
+      }
+    )
+
+    const getWrapperStyle = computed(
+      (): CSSProperties => {
+        const { height, width } = props
+        return { width: `${width}`.replace(/px/, '') + 'px', height: `${height}`.replace(/px/, '') + 'px' }
+      }
+    )
+
+    async function init() {
+      const imgEl = vm.refs.imgElRef
+      if (!imgEl) {
+        return
+      }
+      cropper.value = new Cropper(imgEl, {
+        ...defaultOptions,
+        ready: () => {
+          isReady.value = true
+        },
+        ...props.options,
+      })
+    }
+
+    onBeforeMount(() => {
+      vm = getCurrentInstance()
+      nextTick(() => {
+        init()
+        // tsx语法返回渲染模板,外部组件想调用内部方法或者获取setup里面的实例,暂时想到的办法是通过公共事件
+        emitter.emit("cropperInstance", unref(cropper))
+      })
+    })
+
+    return () => (
+      <>
+        <div class={useAttrs({ excludeListeners: true, excludeKeys: ['class'] })} style={unref(getWrapperStyle)}>
+          <img
+            ref="imgElRef"
+            src={props.src}
+            alt={props.alt}
+            crossorigin={props.crossorigin}
+            style={unref(getImageStyle)}
+          />
+        </div>
+      </>
+    )
+  },
+})

+ 3 - 0
src/components/cropper/index.vue → src/components/Cropper/src/index.ts

@@ -1,3 +1,4 @@
+/**
 <template>
   <div :class="$attrs.class" :style="getWrapperStyle">
     <img
@@ -43,6 +44,7 @@
     rotatable: true,
   };
   export default defineComponent({
+    name: "Cropper",
     props: {
       src: {
         type: String,
@@ -126,3 +128,4 @@
     },
   });
 </script>
+ */

+ 10 - 0
src/components/Flop/index.ts

@@ -0,0 +1,10 @@
+import { App } from "vue"
+import flop from "./src/index.vue"
+
+export const Flop = Object.assign(flop, {
+  install(app: App) {
+    app.component(flop.name, flop)
+  }
+})
+
+export default Flop

+ 0 - 0
src/components/flop/flipper.vue → src/components/Flop/src/Flipper.vue


+ 2 - 1
src/components/flop/index.vue → src/components/Flop/src/index.vue

@@ -13,8 +13,9 @@
 
 <script lang='ts'>
 import { ref, onBeforeMount, getCurrentInstance, nextTick } from "vue";
-import flippers from "./flipper.vue";
+import flippers from "./Flipper.vue";
 export default {
+  name: "Flop",
   components: {
     flippers,
   },

+ 10 - 0
src/components/HamBurger/index.ts

@@ -0,0 +1,10 @@
+import { App } from "vue"
+import hamBurger from "./src/HamBurger.vue"
+
+export const HamBurger = Object.assign(hamBurger, {
+  install(app: App) {
+    app.component(hamBurger.name, hamBurger)
+  }
+})
+
+export default HamBurger

+ 1 - 1
src/components/hamBurger/index.vue → src/components/HamBurger/src/HamBurger.vue

@@ -18,7 +18,7 @@
 <script>
 import { defineComponent } from "vue";
 export default defineComponent({
-  name: "hamBurger",
+  name: "HamBurger",
   props: {
     isActive: {
       type: Boolean,

+ 20 - 0
src/components/Map/index.ts

@@ -0,0 +1,20 @@
+import { App } from "vue"
+import amap from "./src/Amap.vue"
+import baiduMap from "./src/BaiduMap.vue"
+
+export const Amap = Object.assign(amap, {
+  install(app: App) {
+    app.component(amap.name, amap)
+  }
+})
+
+export const BaiduMap = Object.assign(baiduMap, {
+  install(app: App) {
+    app.component(baiduMap.name, baiduMap)
+  }
+})
+
+export default {
+  Amap,
+  BaiduMap
+}

+ 4 - 2
src/components/map/amap.vue → src/components/Map/src/Amap.vue

@@ -19,9 +19,10 @@ import {
   getCurrentInstance,
 } from "vue";
 
-import { mapJson } from "../../api/mock";
+import { mapJson } from "/@/api/mock";
+import { deviceDetection } from "/@/utils/deviceDetection"
+
 import greenCar from "/@/assets/green.png";
-import { deviceDetection } from "../../utils/deviceDetection"
 
 let MarkerCluster = null;
 
@@ -40,6 +41,7 @@ export interface mapInter {
 }
 
 export default defineComponent({
+  name: "Amap",
   setup() {
     let vm: any;
     let map: MapConfigureInter;

+ 1 - 0
src/components/map/baiduMap.vue → src/components/Map/src/BaiduMap.vue

@@ -6,6 +6,7 @@
 
 <script lang='ts'>
 export default {
+  name: "BaiduMap",
   setup(){
     return{
 

+ 1 - 1
src/components/countTo/index.ts

@@ -1,5 +1,5 @@
 import { App } from "vue"
-import countTo from "./src/countTo"
+import countTo from "./src/CountTo"
 
 export const CountTo = Object.assign(countTo, {
   install(app: App) {

+ 1 - 1
src/components/countTo/src/countTo.tsx

@@ -25,7 +25,7 @@ export default defineComponent({
       timestamp: number | null
       rAF: any
       remaining: number | null
-      color: any
+      color: string
       fontSize: string
     }>({
       localStartVal: props.startVal,

+ 2 - 8
src/components/countTo/src/props.ts

@@ -13,14 +13,8 @@ export const countToProps = {
       return value >= 0
     },
   },
-  color: {
-    type: String as PropType<string>,
-    require: false
-  },
-  fontSize: {
-    type: String as PropType<string>,
-    require: false
-  },
+  color: propTypes.string.def(),
+  fontSize: propTypes.string.def(),
   decimal: propTypes.string.def('.'),
   separator: propTypes.string.def(','),
   prefix: propTypes.string.def(''),

+ 2 - 1
src/components/info/index.vue

@@ -57,7 +57,7 @@ import {
   watch,
   nextTick,
 } from "vue";
-import { storageSession } from "../../utils/storage";
+import { storageSession } from "/@/utils/storage";
 
 export interface ContextProps {
   userName: string;
@@ -71,6 +71,7 @@ export interface ContextProps {
 import { useRouter, useRoute } from "vue-router";
 
 export default defineComponent({
+  name: "Info",
   props: {
     ruleForm: {
       type: Object as PropType<ContextProps>,

+ 1 - 1
src/components/selector/index.ts

@@ -1,5 +1,5 @@
 import { App } from "vue"
-import selector from "./src/selector"
+import selector from "./src/Selector"
 
 export const Selector = Object.assign(selector, {
   install(app: App) {

+ 1 - 1
src/components/selector/src/index.ts

@@ -48,7 +48,7 @@ let selectedList = [];
 let overList = [];
 
 export default defineComponent({
-  name: "HsSelector",
+  name: "Selector",
   props: {
     HsKey: {
       type: Number || String,

+ 1 - 1
src/components/selector/src/selector.tsx

@@ -22,7 +22,7 @@ let overList = []
 let selectedList = []
 
 export default defineComponent({
-  name: "HsSelector",
+  name: "Selector",
   props: {
     HsKey: {
       type: Number || String,

+ 0 - 3
src/components/splitPane/index.vue

@@ -36,11 +36,8 @@
 import {
   defineComponent,
   ref,
-  getCurrentInstance,
   computed,
-  watch,
   PropType,
-  onBeforeMount,
 } from "vue";
 import resizer from "./resizer.vue";
 

+ 0 - 43
src/echarts/index.ts

@@ -1,43 +0,0 @@
-import * as echarts from 'echarts/core'
-
-import {
-  BarChart,
-  LineChart,
-  PieChart,
-  MapChart,
-  PictorialBarChart,
-  RadarChart,
-} from 'echarts/charts'
-
-import {
-  TitleComponent,
-  TooltipComponent,
-  GridComponent,
-  PolarComponent,
-  AriaComponent,
-  ParallelComponent,
-  LegendComponent,
-  RadarComponent,
-} from 'echarts/components'
-
-import { SVGRenderer } from 'echarts/renderers'
-
-echarts.use([
-  LegendComponent,
-  TitleComponent,
-  TooltipComponent,
-  GridComponent,
-  PolarComponent,
-  AriaComponent,
-  ParallelComponent,
-  BarChart,
-  LineChart,
-  PieChart,
-  MapChart,
-  RadarChart,
-  SVGRenderer,
-  PictorialBarChart,
-  RadarComponent,
-])
-
-export default echarts

+ 8 - 8
src/layout/components/Navbar.vue

@@ -1,12 +1,12 @@
 <template>
   <div class="navbar">
-    <hamburger
+    <Hamburger
       :is-active="sidebar.opened"
       class="hamburger-container"
       @toggleClick="toggleSideBar"
     />
 
-    <breadcrumb class="breadcrumb-container" />
+    <Breadcrumb class="breadcrumb-container" />
 
     <div class="right-menu">
       <screenfull />
@@ -31,14 +31,14 @@
 </template>
 
 <script lang="ts">
-import { ref, reactive, defineComponent, onMounted, nextTick } from "vue";
-import Breadcrumb from "../../components/breadCrumb/index.vue";
-import Hamburger from "../../components/hamBurger/index.vue";
+import { ref, defineComponent, onMounted } from "vue";
+import Breadcrumb from "/@/components/BreadCrumb";
+import Hamburger from "/@/components/HamBurger";
 import screenfull from "../components/screenfull/index.vue";
 import { useMapGetters } from "../store";
-import { useRoute, useRouter } from "vue-router";
-import { mapGetters, useStore } from "vuex";
-import { storageSession } from "../../utils/storage";
+import { useRouter } from "vue-router";
+import { useStore } from "vuex";
+import { storageSession } from "/@/utils/storage";
 import { useI18n } from "vue-i18n";
 import ch from "/@/assets/ch.png";
 import en from "/@/assets/en.png";

+ 2 - 2
src/router/index.ts

@@ -88,7 +88,7 @@ const routes: Array<RouteRecordRaw> = [
       },
       {
         path: '/components/countTo',
-        component: () => import(/* webpackChunkName: "components" */ '../views/components/countTo/index.vue'),
+        component: () => import(/* webpackChunkName: "components" */ '../views/components/count-to/index.vue'),
         meta: {
           title: 'countTo',
           showLink: false,
@@ -106,7 +106,7 @@ const routes: Array<RouteRecordRaw> = [
       },
       // {
       //   path: '/components/flowChart',
-      //   component: () => import(/* webpackChunkName: "components" */ '../views/components/flowChart/index.vue'),
+      //   component: () => import(/* webpackChunkName: "components" */ '../views/components/flow-chart/index.vue'),
       //   meta: {
       //     title: 'flowChart',
       //     showLink: false,

+ 4 - 0
src/utils/mitt.ts

@@ -0,0 +1,4 @@
+import type { Emitter }  from 'mitt';
+import mitt from 'mitt';
+
+export const emitter: Emitter = mitt();

+ 39 - 0
src/utils/useAttrs.ts

@@ -0,0 +1,39 @@
+import { getCurrentInstance, reactive, shallowRef, watchEffect } from 'vue'
+import type { Ref } from 'vue'
+interface Params {
+  excludeListeners?: boolean
+  excludeKeys?: string[]
+}
+
+const DEFAULT_EXCLUDE_KEYS = ['class', 'style']
+const LISTENER_PREFIX = /^on[A-Z]/
+
+export function entries<T>(obj: Recordable<T>): [string, T][] {
+  return Object.keys(obj).map((key: string) => [key, obj[key]])
+}
+
+export function useAttrs(params: Params = {}): Ref<Recordable> | {} {
+  const instance = getCurrentInstance()
+  if (!instance) return {}
+
+  const { excludeListeners = false, excludeKeys = [] } = params
+  const attrs = shallowRef({})
+  const allExcludeKeys = excludeKeys.concat(DEFAULT_EXCLUDE_KEYS)
+
+  // Since attrs are not reactive, make it reactive instead of doing in `onUpdated` hook for better performance
+  instance.attrs = reactive(instance.attrs)
+
+  watchEffect(() => {
+    const res = entries(instance.attrs).reduce((acm, [key, val]) => {
+      if (!allExcludeKeys.includes(key) && !(excludeListeners && LISTENER_PREFIX.test(key))) {
+        acm[key] = val
+      }
+
+      return acm
+    }, {} as Recordable)
+
+    attrs.value = res
+  })
+
+  return attrs
+}

+ 0 - 0
src/views/components/countTo/index.vue → src/views/components/count-to/index.vue


+ 22 - 14
src/views/components/cropping/index.vue

@@ -1,7 +1,7 @@
 <template>
   <div style="margin: 10px">
     <div class="cropper-container">
-      <cropperImage ref="refCropper" :src="img" @cropperedInfo="cropperedInfo" style="width:45%" />
+      <Cropper ref="refCropper" :width="'45vw'" :src="img" />
       <img :src="cropperImg" class="croppered" v-if="cropperImg" />
     </div>
     <el-button type="primary" @click="onCropper">裁剪</el-button>
@@ -9,39 +9,47 @@
   </div>
 </template>
 <script lang="ts">
-import { defineComponent, ref, onBeforeMount, getCurrentInstance } from "vue";
-import cropperImage from "../../../components/cropper/index.vue";
+import { defineComponent, ref, onBeforeMount, nextTick } from "vue";
+import Cropper from "/@/components/Cropper";
 import img from "./picture.jpeg";
+import { emitter } from "/@/utils/mitt";
+
+let cropperInstance = null;
 export default defineComponent({
   components: {
-    cropperImage
+    Cropper,
   },
   setup() {
-    let vm: any;
     let info = ref("");
     let cropperImg = ref("");
 
     const onCropper = (): void => {
-      vm.refs.refCropper.croppered();
+      nextTick(() => {
+        let imgInfo = cropperInstance.getData();
+        cropperInstance.getCroppedCanvas().toBlob((blob) => {
+          let fileReader: FileReader = new FileReader();
+          fileReader.onloadend = (e: any) => {
+            cropperImg.value = e.target.result;
+            info.value = imgInfo;
+          };
+          fileReader.readAsDataURL(blob);
+        }, "image/jpeg");
+      });
     };
 
     onBeforeMount(() => {
-      vm = getCurrentInstance();
+      emitter.on("cropperInstance", (key) => {
+        cropperInstance = key;
+      });
     });
 
-    function cropperedInfo({ imgBase64, imgInfo }) {
-      info.value = imgInfo;
-      cropperImg.value = imgBase64;
-    }
-
     return {
       img,
       info,
       cropperImg,
       onCropper,
-      cropperedInfo
     };
-  }
+  },
 });
 </script>
 

+ 0 - 0
src/views/components/flowChart/index.vue → src/views/components/flow-chart/index.vue


+ 3 - 3
src/views/components/map/index.vue

@@ -1,14 +1,14 @@
 <template>
   <div class="map">
-    <amap />
+    <Amap />
   </div>
 </template>
 
 <script lang='ts'>
-import amap from "../../../components/map/amap.vue";
+import { Amap } from "/@/components/Map";
 export default {
   components: {
-    amap
+    Amap
   },
   setup(){
     return{

+ 1 - 1
src/views/components/selector/index.vue

@@ -14,7 +14,7 @@
 
 <script lang='ts'>
 import { ref } from "vue";
-import Selector from "/@/components/selector";
+import Selector from "/@/components/Selector";
 
 export default {
   components: { Selector },

+ 1 - 1
src/views/components/split-pane/index.vue

@@ -25,7 +25,7 @@
 <script lang="ts">
 import splitpane, {
   ContextProps,
-} from "../../../components/splitPane/index.vue";
+} from "/@/components/SplitPane/index.vue";
 import { reactive } from "vue";
 export default {
   name: "split",

+ 4 - 2
src/views/components/video/index.vue

@@ -5,8 +5,10 @@
 <script lang='ts'>
 import { onMounted } from "vue";
 import Player from "xgplayer/dist/simple_player";
-import { volume, playbackRate, screenShot } from "xgplayer/dist/controls";
-import { deviceDetection } from "../../../utils/deviceDetection"
+import volume from 'xgplayer/dist/controls/volume';
+import playbackRate from 'xgplayer/dist/controls/playbackRate';
+import screenShot from 'xgplayer/dist/controls/screenShot';
+import { deviceDetection } from "/@/utils/deviceDetection"
 
 export default {
   setup() {

+ 4 - 4
src/views/login.vue

@@ -13,11 +13,11 @@ import {
   reactive,
   onBeforeMount,
 } from "vue";
-import info, { ContextProps } from "../components/info/index.vue";
-import { getVerify, getLogin } from "../api/user";
+import info, { ContextProps } from "/@/components/Info/index.vue";
+import { getVerify, getLogin } from "/@/api/user";
 import { useRouter } from "vue-router";
-import { storageSession } from "../utils/storage";
-import { warnMessage, successMessage } from "../utils/message";
+import { storageSession } from "/@/utils/storage";
+import { warnMessage, successMessage } from "/@/utils/message";
 export default {
   name: "login",
   components: {

+ 3 - 3
src/views/register.vue

@@ -16,10 +16,10 @@ import {
   onBeforeMount,
   getCurrentInstance,
 } from "vue";
-import info, { ContextProps } from "../components/info/index.vue";
-import { getRegist, getVerify } from "../api/user";
+import info, { ContextProps } from "/@//components/Info/index.vue";
+import { getRegist, getVerify } from "/@/api/user";
 import { useRouter } from "vue-router";
-import { warnMessage, successMessage } from "../utils/message";
+import { warnMessage, successMessage } from "/@/utils/message";
 export default {
   name: "register",
   components: {

+ 6 - 6
src/views/welcome.vue

@@ -11,7 +11,7 @@
           />
           <span>{{ greetings }}</span>
         </div>
-        <flop v-if="!mobile" />
+        <Flop v-if="!mobile" />
       </div>
     </el-affix>
 
@@ -27,10 +27,10 @@
 </template>
 
 <script lang='ts'>
-import flop from "../components/flop/index.vue";
-import { ref, computed, onMounted, nextTick, onUpdated } from "vue";
-import { deviceDetection } from "../utils/deviceDetection";
-import { echartsJson } from "../api/mock";
+import Flop from "/@/components/Flop";
+import { ref, computed, onMounted, nextTick } from "vue";
+import { deviceDetection } from "/@/utils/deviceDetection";
+import { echartsJson } from "/@/api/mock";
 import {
   useEventListener,
   tryOnUnmounted,
@@ -42,7 +42,7 @@ let brokenLine: any = null; //折线图实例
 export default {
   name: "welcome",
   components: {
-    flop,
+    Flop,
   },
   setup() {
     let mobile = ref(deviceDetection());

+ 12 - 3
tsconfig.json

@@ -23,11 +23,17 @@
     "paths": {
       "/@/*": [
         "src/*"
+      ],
+      "/#/*": [
+        "types/*"
       ]
     },
-    "types": ["node"],
+    "types": [
+      "node"
+    ],
     "typeRoots": [
-      "node_modules/@types"
+      "./node_modules/@types/",
+      "./types"
     ],
   },
   "include": [
@@ -35,7 +41,10 @@
     "src/**/*.tsx",
     "src/**/*.vue",
     "tests/**/*.ts",
-    "src/utils/path.js"    
+    "src/utils/path.js",
+    "types/**/*.d.ts",
+    "types/**/*.ts",
+    "types/shims-tsx.d.ts"
   ],
   "exclude": [
     "node_modules",

+ 99 - 0
types/global.d.ts

@@ -0,0 +1,99 @@
+import type {
+  ComponentRenderProxy,
+  VNode,
+  ComponentPublicInstance,
+  FunctionalComponent,
+  PropType as VuePropType,
+} from 'vue'
+
+declare global {
+  const __APP_INFO__: {
+    pkg: {
+      name: string
+      version: string
+      dependencies: Recordable<string>
+      devDependencies: Recordable<string>
+    }
+    lastBuildTime: string
+  }
+  declare interface Window {
+    // Global vue app instance
+    __APP__: App<Element>
+  }
+
+  // vue
+  declare type PropType<T> = VuePropType<T>
+
+  export type Writable<T> = {
+    -readonly [P in keyof T]: T[P]
+  }
+
+  declare type Nullable<T> = T | null
+  declare type NonNullable<T> = T extends null | undefined ? never : T
+  declare type Recordable<T = any> = Record<string, T>
+  declare type ReadonlyRecordable<T = any> = {
+    readonly [key: string]: T
+  }
+  declare type Indexable<T = any> = {
+    [key: string]: T
+  }
+  declare type DeepPartial<T> = {
+    [P in keyof T]?: DeepPartial<T[P]>
+  }
+  declare type TimeoutHandle = ReturnType<typeof setTimeout>
+  declare type IntervalHandle = ReturnType<typeof setInterval>
+
+  declare interface ChangeEvent extends Event {
+    target: HTMLInputElement
+  }
+
+  declare interface WheelEvent {
+    path?: EventTarget[]
+  }
+  interface ImportMetaEnv extends ViteEnv {
+    __: unknown
+  }
+
+  declare interface ViteEnv {
+    VITE_PORT: number
+    VITE_USE_MOCK: boolean
+    VITE_USE_PWA: boolean
+    VITE_PUBLIC_PATH: string
+    VITE_PROXY: [string, string][]
+    VITE_GLOB_APP_TITLE: string
+    VITE_GLOB_APP_SHORT_NAME: string
+    VITE_USE_CDN: boolean
+    VITE_DROP_CONSOLE: boolean
+    VITE_BUILD_COMPRESS: 'gzip' | 'brotli' | 'none'
+    VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE: boolean
+    VITE_LEGACY: boolean
+    VITE_USE_IMAGEMIN: boolean
+    VITE_GENERATE_UI: string
+  }
+
+  declare function parseInt(s: string | number, radix?: number): number
+
+  declare function parseFloat(string: string | number): number
+
+  namespace JSX {
+    // tslint:disable no-empty-interface
+    type Element = VNode
+    // tslint:disable no-empty-interface
+    type ElementClass = ComponentRenderProxy
+    interface ElementAttributesProperty {
+      $props: any
+    }
+    interface IntrinsicElements {
+      [elem: string]: any
+    }
+    interface IntrinsicAttributes {
+      [elem: string]: any
+    }
+  }
+}
+
+declare module 'vue' {
+  export type JSXComponent<Props = any> =
+    | { new(): ComponentPublicInstance<Props> }
+    | FunctionalComponent<Props>
+}

+ 26 - 0
types/index.d.ts

@@ -0,0 +1,26 @@
+declare interface Fn<T = any, R = T> {
+  (...arg: T[]): R
+}
+
+declare interface PromiseFn<T = any, R = T> {
+  (...arg: T[]): Promise<R>
+}
+
+declare type RefType<T> = T | null
+
+declare type LabelValueOptions = {
+  label: string
+  value: any
+}[]
+
+declare type EmitType = (event: string, ...args: any[]) => void
+
+declare type TargetContext = '_self' | '_blank'
+
+declare interface ComponentElRef<T extends HTMLElement = HTMLDivElement> {
+  $el: T
+}
+
+declare type ComponentRef<T extends HTMLElement = HTMLDivElement> = ComponentElRef<T> | null
+
+declare type ElRef<T extends HTMLElement = HTMLDivElement> = Nullable<T>

+ 0 - 0
src/shims-tsx.d.ts → types/shims-tsx.d.ts


+ 0 - 0
src/shims-vue.d.ts → types/shims-vue.d.ts


Some files were not shown because too many files changed in this diff