lvkun996 преди 3 години
родител
ревизия
ccebdadb83

+ 2 - 1
.eslintrc.js

@@ -13,6 +13,7 @@ module.exports = {
   },
   rules: {
     'vue/multi-word-component-names': 0,
-    '@typescript-eslint/no-empty-function': 'off'
+    '@typescript-eslint/no-empty-function': 'off',
+    'no-undef': 'off'
   }
 }

+ 2 - 0
package.json

@@ -12,9 +12,11 @@
     "ant-design-vue": "^3.3.0-beta.4",
     "babel-plugin-import": "^1.13.6",
     "core-js": "^3.8.3",
+    "mitt": "^3.0.0",
     "pinia": "^2.0.33",
     "vue": "^3.2.13",
     "vue-class-component": "^8.0.0-0",
+    "vue-hooks-plus": "^1.6.2",
     "vue-router": "^4.0.3"
   },
   "devDependencies": {

+ 3 - 0
src/constant/app.ts

@@ -0,0 +1,3 @@
+export default {
+  theme: ''
+}

+ 1 - 0
src/constant/index.ts

@@ -0,0 +1 @@
+export { default as app } from './app'

+ 3 - 0
src/enum/emitter.ts

@@ -0,0 +1,3 @@
+export enum Emitter {
+  'NAVBAR' = 'NAVBAR'
+}

+ 2 - 0
src/enum/index.ts

@@ -0,0 +1,2 @@
+export { Emitter } from './emitter'
+export { AppRouter } from './router'

+ 3 - 0
src/enum/router.ts

@@ -0,0 +1,3 @@
+export enum AppRouter {
+  'ROUTER' = 'ROUTER'
+}

+ 3 - 0
src/enum/store.ts

@@ -0,0 +1,3 @@
+export enum ConstantStore {
+  'ROUTER' = 'ROUTER'
+}

+ 16 - 0
src/hooks/effect.ts

@@ -0,0 +1,16 @@
+import { Emitter } from '@/enum/emitter'
+import mitt from 'mitt'
+
+const emitter = mitt()
+
+export const useEmitter = () => {
+  const _on = (key: keyof typeof Emitter, cb: () => void) => emitter.on(key, cb)
+  const _emit = (key: keyof typeof Emitter) => emitter.emit(key)
+  const _off = (key: keyof typeof Emitter, cb: () => void) => emitter.off(key, cb)
+
+  return {
+    on: _on,
+    emit: _emit,
+    off: _off
+  }
+}

+ 1 - 0
src/hooks/index.ts

@@ -0,0 +1 @@
+export { useEmitter } from './effect'

+ 7 - 0
src/layout/breadcrumb.vue

@@ -0,0 +1,7 @@
+<template>
+  <a-breadcrumb style="margin: 16px 0">
+    <a-breadcrumb-item>Home</a-breadcrumb-item>
+    <a-breadcrumb-item>List</a-breadcrumb-item>
+    <a-breadcrumb-item>App</a-breadcrumb-item>
+  </a-breadcrumb>
+</template>

+ 5 - 16
src/layout/layout.vue

@@ -2,17 +2,13 @@
     <a-layout class="a-layout" >
         <Navbar />
         <a-layout>
-        <Sider />
+        <Sider :router="silders" />
         <a-layout style="padding: 0 24px 24px">
-            <a-breadcrumb style="margin: 16px 0">
-                <a-breadcrumb-item>Home</a-breadcrumb-item>
-                <a-breadcrumb-item>List</a-breadcrumb-item>
-                <a-breadcrumb-item>App</a-breadcrumb-item>
-            </a-breadcrumb>
+          <Breadcrumb />
             <a-layout-content
             :style="{ background: '#fff', padding: '24px', margin: 0, minHeight: '280px' }"
             >
-                <RouterView></RouterView>
+              <RouterView></RouterView>
             </a-layout-content>
         </a-layout>
         </a-layout>
@@ -20,19 +16,12 @@
 </template>
 
 <script  lang="ts" setup >
-import { UserOutlined, LaptopOutlined, NotificationOutlined } from '@ant-design/icons-vue'
-import { defineComponent, ref } from 'vue'
 import router from '@/router/index'
 import Navbar from './navbar.vue'
 import Sider from './sider.vue'
-const onCollapse = () => {}
-const onBreakpoint = () => {}
+import Breadcrumb from './breadcrumb.vue'
 
-console.log(router.options.routes)
-
-const selectedKeys1 = ref<string[]>(['2'])
-
-const collapsed = ref<boolean>(false)
+const silders = router.options.routes.find(route => route.path === '/')?.children
 
 </script>
 

+ 13 - 11
src/layout/navbar.vue

@@ -5,27 +5,29 @@
           theme="dark"
           mode="horizontal"
           :style="{ lineHeight: '64px' }"
+          v-model:selectedKeys="selectedKeys1"
       >
           <a-menu-item
-              v-for="route in navbarRoutes"
-              :key="route.path"
+            v-for="route in appRouter.$state.router.navbar.route"
+            :key="route.path"
+            @click="changeRouter(route.path)"
+
           >
-              {{route.name}}
+            {{route.name}}
           </a-menu-item>
       </a-menu>
   </a-layout-header>
 </template>
 
 <script lang="ts" setup >
-import { computed } from 'vue'
-import router from '@/router/index'
+import { ref } from 'vue'
+import { useAppRouter } from '@/store/router'
+const appRouter = useAppRouter()
+
+const selectedKeys1 = ref<string[]>([appRouter.$state.router.navbar.selectPath])
+
+const changeRouter = (path: string) => appRouter.changeNavbar(path)
 
-const navbarRoutes = computed(() => router.options.routes.map(route => {
-  return {
-    path: route.path,
-    name: route.name
-  }
-}))
 </script>
 
 <style lang="less" scoped >

+ 25 - 9
src/layout/sider.vue

@@ -12,19 +12,22 @@
          <a-menu
             v-model:selectedKeys="selectedKeys2"
             v-model:openKeys="openKeys"
+
             mode="inline"
             :style="{ height: '100%', borderRight: 0 }"
             >
-
-            <a-sub-menu  v-for="item in silders" :key="item.path">
+            <template v-for="item in appRouter.router.sider.route" :key="item.path">
+              <a-sub-menu  v-if="item.children" :key="item.path">
                 <template #title>
                 <span>
                     <user-outlined />
                     {{item.name}}
                 </span>
                 </template>
-                <a-menu-item v-for="_ in item.children" :key="_.path" >{{_.name}}</a-menu-item>
-            </a-sub-menu>
+                <a-menu-item @click="changeRoute(_)" v-for="_ in item.children" :key="_.path" >{{_.name}}</a-menu-item>
+              </a-sub-menu>
+              <a-menu-item v-else @click="changeRoute(item)" >{{item.name}}</a-menu-item>
+            </template>
             </a-menu>
         </a-layout-sider>
     </a-col>
@@ -32,16 +35,29 @@
 </template>
 
 <script lang="ts" setup  >
-import { ref, computed } from 'vue'
-import router from '@/router/index'
+import { ref } from 'vue'
+import RootRouter from '@/router/index'
+import { useAppRouter } from '@/store/router'
+import { useEmitter } from '@/hooks/index'
+import { Emitter } from '@/enum/emitter'
+
+const emitter = useEmitter()
+const appRouter = useAppRouter()
 
 const onCollapse = () => {}
 const onBreakpoint = () => {}
 
-const selectedKeys2 = ref<string[]>(['1'])
-const openKeys = ref<string[]>(['sub1'])
+const selectedKeys2 = ref<string[]>([appRouter.router.sider!.selectPath])
+const openKeys = ref<string[]>(appRouter.router.sider!.openKeys)
+
+emitter.on(Emitter.NAVBAR, () => {
+  selectedKeys2.value = [appRouter.router.sider!.selectPath]
+  openKeys.value = appRouter.router.sider!.openKeys
+})
 
-const silders = router.options.routes.find(route => route.path === '/')?.children
+const changeRoute = (route: Router.RoutesProps) => {
+  RootRouter.push(route.path)
+}
 
 </script>
 

+ 5 - 0
src/pages/Iot/index.vue

@@ -0,0 +1,5 @@
+<template>
+  <div class="iot" >
+    iot
+  </div>
+</template>

+ 5 - 0
src/pages/Iot/net.vue

@@ -0,0 +1,5 @@
+<template>
+  <div class="iot" >
+    net
+  </div>
+</template>

+ 29 - 3
src/router/index.ts

@@ -1,15 +1,16 @@
-import { createRouter, createWebHistory } from 'vue-router'
+import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'
 
-const routes: Array<Router.RoutesProps> = [
+const routes: Array<RouteRecordRaw> = [
   {
     path: '/',
     name: '首页',
-    title: '首页',
     component: () => import('@/layout/layout.vue'),
+    redirect: '/dashboard',
     children: [
       {
         path: '/dashboard',
         name: '仪表盘',
+        redirect: '/dashboard-item',
         component: () => import('@/pages/Dashboard/index.vue'),
         children: [
           {
@@ -20,6 +21,31 @@ const routes: Array<Router.RoutesProps> = [
         ]
       }
     ]
+  },
+  {
+    path: '/iot',
+    name: '物联网',
+    component: () => import('@/layout/layout.vue'),
+    redirect: '/iot/dashboard',
+    children: [
+      {
+        path: '/iot/dashboard',
+        name: '物联网',
+        redirect: '/iot/dashboard-item',
+        children: [
+          {
+            path: '/iot/dashboard-item',
+            name: '物联网',
+            component: () => import('@/pages/Iot/index.vue')
+          }
+        ]
+      },
+      {
+        path: '/net/dashboard',
+        name: '互联网',
+        component: () => import('@/pages/Iot/net.vue')
+      }
+    ]
   }
 ]
 

+ 0 - 5
src/router/typeing.d.ts

@@ -1,6 +1 @@
 
-namespace Router {
-  type RoutesProps = RouteRecordRaw & {
-    title: string
-  }
-}

+ 1 - 0
src/store/index.ts

@@ -0,0 +1 @@
+// import { createPinia } from 'pinia'

+ 84 - 0
src/store/router.ts

@@ -0,0 +1,84 @@
+import { defineStore } from 'pinia'
+import { ConstantStore } from '@/enum/store'
+import { ref, computed, onMounted, watch, reactive, watchEffect } from 'vue'
+import RootRouter from '@/router'
+import { useLocalStorageState } from 'vue-hooks-plus'
+import { AppRouter as AppRouterEnum, Emitter } from '@/enum'
+import { useEmitter } from '@/hooks/index'
+import { useRoute } from 'vue-router'
+
+/**
+ * 1. 获取当前路由path
+ * 2. 从缓存中获取router, 防止刷新都丢失状态
+ * 3. 获取navbar路由list
+ *  3.1 根据当前的路由path 反推到最顶级父元素 将其置为常亮
+ * 4. 每次点击navbar的路由的时候,将对应的sider第一项展开
+ */
+
+const emitter = useEmitter()
+
+const initAppRouterState: Router.RouterRecords = {
+  navbar: {
+    route: [],
+    selectPath: ''
+  },
+  sider: {
+    route: [],
+    selectPath: '',
+    openKeys: []
+  }
+}
+export const useAppRouter = defineStore(ConstantStore.ROUTER, () => {
+  let appRouter = reactive<Router.RouterRecords>(initAppRouterState)
+
+  const route = useRoute()
+
+  const [appRouterState, setAppRouterState] = useLocalStorageState<Router.RouterRecords>(AppRouterEnum.ROUTER, {
+    defaultValue: initAppRouterState
+  })
+
+  const siderRoutes = computed(() => RootRouter.getRoutes().find(item => item.path === appRouter.navbar!.selectPath)?.children)
+
+  const initAppRouter = () => {
+    appRouter.navbar.route = RootRouter.options.routes.map(route => {
+      return {
+        path: route.path,
+        name: route.name
+      }
+    })
+
+    appRouter.navbar.selectPath = RootRouter.options.routes[0].path
+
+    appRouter.sider.route = siderRoutes.value!
+
+    setAppRouterState(appRouter)
+  }
+
+  const changeNavbar = (path: string) => {
+    RootRouter.push(path)
+    appRouter.navbar.selectPath = path
+  }
+
+  watch(
+    () => RootRouter.currentRoute.value.path,
+    () => {
+      appRouter.sider = {
+        route: RootRouter.getRoutes().find(item => item.path === appRouter.navbar!.selectPath)?.children as Router.RoutesProps[],
+        selectPath: RootRouter.currentRoute.value.path,
+        openKeys: [RootRouter.currentRoute.value.matched[1].path]
+      }
+      setAppRouterState(appRouter)
+      emitter.emit(Emitter.NAVBAR)
+    }
+  )
+
+  appRouter = appRouterState.value as Router.RouterRecords
+
+  if (appRouter.navbar.route.length === 0) {
+    initAppRouter()
+  }
+  return {
+    router: appRouter,
+    changeNavbar
+  }
+})

+ 18 - 0
src/typeing.d.ts

@@ -0,0 +1,18 @@
+declare namespace Router {
+
+  type RoutesProps = RouteRecordRaw & {
+    title: string
+  }
+
+  type RouterRecords = {
+    navbar: {
+      route: RoutesProps[],
+      selectPath: string
+    },
+    sider: {
+      route: RoutesProps[],
+      selectPath: string,
+      openKeys: string[]
+    },
+  }
+}

+ 81 - 0
yarn.lock

@@ -1264,6 +1264,11 @@
   dependencies:
     "@types/node" "*"
 
+"@types/js-cookie@^3.0.1":
+  version "3.0.3"
+  resolved "https://registry.npmmirror.com/@types/js-cookie/-/js-cookie-3.0.3.tgz#d6bfbbdd0c187354ca555213d1962f6d0691ff4e"
+  integrity sha512-Xe7IImK09HP1sv2M/aI+48a20VX+TdRJucfq4vfRVy6nWN8PYPOEnlMRSgxJAgYQIXJVL8dZ4/ilAM7dWNaOww==
+
 "@types/json-schema@*", "@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9":
   version "7.0.11"
   resolved "https://registry.npmmirror.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3"
@@ -2963,6 +2968,11 @@ debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4:
   dependencies:
     ms "2.1.2"
 
+decode-uri-component@^0.2.2:
+  version "0.2.2"
+  resolved "https://registry.npmmirror.com/decode-uri-component/-/decode-uri-component-0.2.2.tgz#e69dbe25d37941171dd540e024c444cd5188e1e9"
+  integrity sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==
+
 deep-is@^0.1.3:
   version "0.1.4"
   resolved "https://registry.npmmirror.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831"
@@ -3719,6 +3729,11 @@ fill-range@^7.0.1:
   dependencies:
     to-regex-range "^5.0.1"
 
+filter-obj@^1.1.0:
+  version "1.1.0"
+  resolved "https://registry.npmmirror.com/filter-obj/-/filter-obj-1.1.0.tgz#9b311112bc6c6127a16e016c6c5d7f19e0805c5b"
+  integrity sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==
+
 finalhandler@1.2.0:
   version "1.2.0"
   resolved "https://registry.npmmirror.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32"
@@ -4278,6 +4293,11 @@ interpret@^1.4.0:
   resolved "https://registry.npmmirror.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e"
   integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==
 
+intersection-observer@^0.12.2:
+  version "0.12.2"
+  resolved "https://registry.npmmirror.com/intersection-observer/-/intersection-observer-0.12.2.tgz#4a45349cc0cd91916682b1f44c28d7ec737dc375"
+  integrity sha512-7m1vEcPCxXYI8HqnL8CKI6siDyD+eIWSwgB3DZA+ZTogxk9I4CDnj4wilt9x/+/QbHI4YG5YZNmC6458/e9Ktg==
+
 ipaddr.js@1.9.1:
   version "1.9.1"
   resolved "https://registry.npmmirror.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3"
@@ -4556,6 +4576,11 @@ joi@^17.4.0:
     "@sideway/formula" "^3.0.1"
     "@sideway/pinpoint" "^2.0.0"
 
+js-cookie@^3.0.1:
+  version "3.0.1"
+  resolved "https://registry.npmmirror.com/js-cookie/-/js-cookie-3.0.1.tgz#9e39b4c6c2f56563708d7d31f6f5f21873a92414"
+  integrity sha512-+0rgsUXZu4ncpPxRL+lNEptWMOWl9etvPHc/koSRp6MPwpRYAhmk0dUG00J4bxVV3r9uUzfo24wW0knS07SKSw==
+
 js-message@1.0.7:
   version "1.0.7"
   resolved "https://registry.npmmirror.com/js-message/-/js-message-1.0.7.tgz#fbddd053c7a47021871bb8b2c95397cc17c20e47"
@@ -4896,6 +4921,11 @@ make-dir@^3.0.2, make-dir@^3.1.0:
   dependencies:
     semver "^6.0.0"
 
+marked@^4.0.17:
+  version "4.3.0"
+  resolved "https://registry.npmmirror.com/marked/-/marked-4.3.0.tgz#796362821b019f734054582038b116481b456cf3"
+  integrity sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==
+
 mdn-data@2.0.14:
   version "2.0.14"
   resolved "https://registry.npmmirror.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50"
@@ -5011,6 +5041,11 @@ minipass@^3.1.1:
   dependencies:
     yallist "^4.0.0"
 
+mitt@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.npmmirror.com/mitt/-/mitt-3.0.0.tgz#69ef9bd5c80ff6f57473e8d89326d01c414be0bd"
+  integrity sha512-7dX2/10ITVyqh4aOSVI9gdape+t9l2/8QxHrFmUXu4EEUpdlxl6RudZUPZoc+zuY2hk1j7XxVroIVIan/pD/SQ==
+
 mkdirp@^0.5.6:
   version "0.5.6"
   resolved "https://registry.npmmirror.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6"
@@ -5817,6 +5852,23 @@ qs@6.11.0:
   dependencies:
     side-channel "^1.0.4"
 
+qs@^6.11.0:
+  version "6.11.1"
+  resolved "https://registry.npmmirror.com/qs/-/qs-6.11.1.tgz#6c29dff97f0c0060765911ba65cbc9764186109f"
+  integrity sha512-0wsrzgTz/kAVIeuxSjnpGC56rzYtr6JT/2BwEvMaPhFIoYa1aGO8LbzuU1R0uUYQkLpWBTOj0l/CLAJB64J6nQ==
+  dependencies:
+    side-channel "^1.0.4"
+
+query-string@^7.1.1:
+  version "7.1.3"
+  resolved "https://registry.npmmirror.com/query-string/-/query-string-7.1.3.tgz#a1cf90e994abb113a325804a972d98276fe02328"
+  integrity sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==
+  dependencies:
+    decode-uri-component "^0.2.2"
+    filter-obj "^1.1.0"
+    split-on-first "^1.0.0"
+    strict-uri-encode "^2.0.0"
+
 queue-microtask@^1.2.2:
   version "1.2.3"
   resolved "https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
@@ -6117,6 +6169,11 @@ schema-utils@^4.0.0:
     ajv-formats "^2.1.1"
     ajv-keywords "^5.0.0"
 
+screenfull@^5.0.0:
+  version "5.2.0"
+  resolved "https://registry.npmmirror.com/screenfull/-/screenfull-5.2.0.tgz#6533d524d30621fc1283b9692146f3f13a93d1ba"
+  integrity sha512-9BakfsO2aUQN2K9Fdbj87RJIEZ82Q9IGim7FqM5OsebfoFC6ZHXgDq/KvniuLTPdeM8wY2o6Dj3WQ7KeQCj3cA==
+
 scroll-into-view-if-needed@^2.2.25:
   version "2.2.31"
   resolved "https://registry.npmmirror.com/scroll-into-view-if-needed/-/scroll-into-view-if-needed-2.2.31.tgz#d3c482959dc483e37962d1521254e3295d0d1587"
@@ -6385,6 +6442,11 @@ spdy@^4.0.2:
     select-hose "^2.0.0"
     spdy-transport "^3.0.0"
 
+split-on-first@^1.0.0:
+  version "1.1.0"
+  resolved "https://registry.npmmirror.com/split-on-first/-/split-on-first-1.1.0.tgz#f610afeee3b12bce1d0c30425e76398b78249a5f"
+  integrity sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==
+
 sprintf-js@~1.0.2:
   version "1.0.3"
   resolved "https://registry.npmmirror.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
@@ -6417,6 +6479,11 @@ statuses@2.0.1:
   resolved "https://registry.npmmirror.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c"
   integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==
 
+strict-uri-encode@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.npmmirror.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz#b9c7330c7042862f6b142dc274bbcc5866ce3546"
+  integrity sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==
+
 string-argv@0.3.1:
   version "0.3.1"
   resolved "https://registry.npmmirror.com/string-argv/-/string-argv-0.3.1.tgz#95e2fbec0427ae19184935f816d74aaa4c5c19da"
@@ -6899,6 +6966,20 @@ vue-eslint-parser@^8.0.0, vue-eslint-parser@^8.0.1:
     lodash "^4.17.21"
     semver "^7.3.5"
 
+vue-hooks-plus@^1.6.2:
+  version "1.6.2"
+  resolved "https://registry.npmmirror.com/vue-hooks-plus/-/vue-hooks-plus-1.6.2.tgz#97e921cb997623e6cde92bbe7fc7c50fa4b349c1"
+  integrity sha512-dFe7e6YxXVcdGzIsjpkps5M1/a+9ee3QjWNpdI/srnVnrjubD66SuNasduzmqK25Bhxm2Z0wG1iWYAkvB+9faw==
+  dependencies:
+    "@types/js-cookie" "^3.0.1"
+    intersection-observer "^0.12.2"
+    js-cookie "^3.0.1"
+    lodash "^4.17.21"
+    marked "^4.0.17"
+    qs "^6.11.0"
+    query-string "^7.1.1"
+    screenfull "^5.0.0"
+
 vue-hot-reload-api@^2.3.0:
   version "2.3.4"
   resolved "https://registry.npmmirror.com/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz#532955cc1eb208a3d990b3a9f9a70574657e08f2"