Kaynağa Gözat

refactor(dashboard): change to setup syntax

vben 3 yıl önce
ebeveyn
işleme
45a8eb974a

+ 3 - 3
package.json

@@ -74,10 +74,10 @@
     "@types/fs-extra": "^9.0.12",
     "@types/inquirer": "^7.3.3",
     "@types/intro.js": "^3.0.2",
-    "@types/jest": "^27.0.0",
+    "@types/jest": "^27.0.1",
     "@types/lodash-es": "^4.17.4",
     "@types/mockjs": "^1.0.4",
-    "@types/node": "^16.6.0",
+    "@types/node": "^16.6.1",
     "@types/nprogress": "^0.2.0",
     "@types/qrcode": "^1.4.1",
     "@types/qs": "^6.9.7",
@@ -134,7 +134,7 @@
     "vite-plugin-theme": "^0.8.1",
     "vite-plugin-windicss": "^1.2.7",
     "vue-eslint-parser": "^7.10.0",
-    "vue-tsc": "^0.2.2"
+    "vue-tsc": "^0.2.3"
   },
   "resolutions": {
     "//": "Used to install imagemin dependencies, because imagemin may not be installed in China. If it is abroad, you can delete it",

+ 1 - 10
src/views/dashboard/analysis/components/GrowCard.vue

@@ -26,18 +26,9 @@
     </template>
   </div>
 </template>
-<script lang="ts">
-  import { defineComponent } from 'vue';
-
+<script lang="ts" setup>
   import { CountTo } from '/@/components/CountTo/index';
   import { Icon } from '/@/components/Icon';
   import { Tag, Card } from 'ant-design-vue';
-
   import { growCardList } from '../data';
-  export default defineComponent({
-    components: { CountTo, Tag, Card, Icon },
-    setup() {
-      return { growCardList };
-    },
-  });
 </script>

+ 50 - 56
src/views/dashboard/analysis/components/SalesProductPie.vue

@@ -3,67 +3,61 @@
     <div ref="chartRef" :style="{ width, height }"></div>
   </Card>
 </template>
-<script lang="ts">
-  import { defineComponent, Ref, ref, watch } from 'vue';
-
+<script lang="ts" setup>
+  import { Ref, ref, watch } from 'vue';
   import { Card } from 'ant-design-vue';
   import { useECharts } from '/@/hooks/web/useECharts';
 
-  export default defineComponent({
-    components: { Card },
-    props: {
-      loading: Boolean,
-      width: {
-        type: String as PropType<string>,
-        default: '100%',
-      },
-      height: {
-        type: String as PropType<string>,
-        default: '300px',
-      },
+  const props = defineProps({
+    loading: Boolean,
+    width: {
+      type: String as PropType<string>,
+      default: '100%',
     },
-    setup(props) {
-      const chartRef = ref<HTMLDivElement | null>(null);
-      const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);
-      watch(
-        () => props.loading,
-        () => {
-          if (props.loading) {
-            return;
-          }
-          setOptions({
-            tooltip: {
-              trigger: 'item',
-            },
+    height: {
+      type: String as PropType<string>,
+      default: '300px',
+    },
+  });
 
-            series: [
-              {
-                name: '访问来源',
-                type: 'pie',
-                radius: '80%',
-                center: ['50%', '50%'],
-                color: ['#5ab1ef', '#b6a2de', '#67e0e3', '#2ec7c9'],
-                data: [
-                  { value: 500, name: '电子产品' },
-                  { value: 310, name: '服装' },
-                  { value: 274, name: '化妆品' },
-                  { value: 400, name: '家居' },
-                ].sort(function (a, b) {
-                  return a.value - b.value;
-                }),
-                roseType: 'radius',
-                animationType: 'scale',
-                animationEasing: 'exponentialInOut',
-                animationDelay: function () {
-                  return Math.random() * 400;
-                },
-              },
-            ],
-          });
+  const chartRef = ref<HTMLDivElement | null>(null);
+  const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);
+  watch(
+    () => props.loading,
+    () => {
+      if (props.loading) {
+        return;
+      }
+      setOptions({
+        tooltip: {
+          trigger: 'item',
         },
-        { immediate: true }
-      );
-      return { chartRef };
+
+        series: [
+          {
+            name: '访问来源',
+            type: 'pie',
+            radius: '80%',
+            center: ['50%', '50%'],
+            color: ['#5ab1ef', '#b6a2de', '#67e0e3', '#2ec7c9'],
+            data: [
+              { value: 500, name: '电子产品' },
+              { value: 310, name: '服装' },
+              { value: 274, name: '化妆品' },
+              { value: 400, name: '家居' },
+            ].sort(function (a, b) {
+              return a.value - b.value;
+            }),
+            roseType: 'radius',
+            animationType: 'scale',
+            animationEasing: 'exponentialInOut',
+            animationDelay: function () {
+              return Math.random() * 400;
+            },
+          },
+        ],
+      });
     },
-  });
+    { immediate: true }
+  );
 </script>

+ 16 - 24
src/views/dashboard/analysis/components/SiteAnalysis.vue

@@ -13,34 +13,26 @@
     </p>
   </Card>
 </template>
-<script lang="ts">
-  import { defineComponent, ref } from 'vue';
-
+<script lang="ts" setup>
+  import { ref } from 'vue';
   import { Card } from 'ant-design-vue';
-
   import VisitAnalysis from './VisitAnalysis.vue';
   import VisitAnalysisBar from './VisitAnalysisBar.vue';
 
-  export default defineComponent({
-    components: { Card, VisitAnalysis, VisitAnalysisBar },
-    setup() {
-      const activeKey = ref('tab1');
-
-      const tabListTitle = [
-        {
-          key: 'tab1',
-          tab: '流量趋势',
-        },
-        {
-          key: 'tab2',
-          tab: '访问量',
-        },
-      ];
+  const activeKey = ref('tab1');
 
-      function onTabChange(key) {
-        activeKey.value = key;
-      }
-      return { tabListTitle, activeKey, onTabChange };
+  const tabListTitle = [
+    {
+      key: 'tab1',
+      tab: '流量趋势',
     },
-  });
+    {
+      key: 'tab2',
+      tab: '访问量',
+    },
+  ];
+
+  function onTabChange(key) {
+    activeKey.value = key;
+  }
 </script>

+ 93 - 97
src/views/dashboard/analysis/components/VisitAnalysis.vue

@@ -1,110 +1,106 @@
 <template>
   <div ref="chartRef" :style="{ height, width }"></div>
 </template>
-<script lang="ts">
-  import { defineComponent, onMounted, ref, Ref } from 'vue';
-
+<script lang="ts" setup>
+  import { onMounted, ref, Ref } from 'vue';
   import { useECharts } from '/@/hooks/web/useECharts';
-
   import { basicProps } from './props';
-  export default defineComponent({
-    props: basicProps,
-    setup() {
-      const chartRef = ref<HTMLDivElement | null>(null);
-      const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);
 
-      onMounted(() => {
-        setOptions({
-          tooltip: {
-            trigger: 'axis',
-            axisPointer: {
-              lineStyle: {
-                width: 1,
-                color: '#019680',
-              },
-            },
+  defineProps({
+    ...basicProps,
+  });
+  const chartRef = ref<HTMLDivElement | null>(null);
+  const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);
+
+  onMounted(() => {
+    setOptions({
+      tooltip: {
+        trigger: 'axis',
+        axisPointer: {
+          lineStyle: {
+            width: 1,
+            color: '#019680',
           },
-          xAxis: {
-            type: 'category',
-            boundaryGap: false,
-            data: [
-              '6:00',
-              '7:00',
-              '8:00',
-              '9:00',
-              '10:00',
-              '11:00',
-              '12:00',
-              '13:00',
-              '14:00',
-              '15:00',
-              '16:00',
-              '17:00',
-              '18:00',
-              '19:00',
-              '20:00',
-              '21:00',
-              '22:00',
-              '23:00',
-            ],
-            splitLine: {
-              show: true,
-              lineStyle: {
-                width: 1,
-                type: 'solid',
-                color: 'rgba(226,226,226,0.5)',
-              },
-            },
-            axisTick: {
-              show: false,
-            },
+        },
+      },
+      xAxis: {
+        type: 'category',
+        boundaryGap: false,
+        data: [
+          '6:00',
+          '7:00',
+          '8:00',
+          '9:00',
+          '10:00',
+          '11:00',
+          '12:00',
+          '13:00',
+          '14:00',
+          '15:00',
+          '16:00',
+          '17:00',
+          '18:00',
+          '19:00',
+          '20:00',
+          '21:00',
+          '22:00',
+          '23:00',
+        ],
+        splitLine: {
+          show: true,
+          lineStyle: {
+            width: 1,
+            type: 'solid',
+            color: 'rgba(226,226,226,0.5)',
           },
-          yAxis: [
-            {
-              type: 'value',
-              max: 80000,
-              splitNumber: 4,
-              axisTick: {
-                show: false,
-              },
-              splitArea: {
-                show: true,
-                areaStyle: {
-                  color: ['rgba(255,255,255,0.2)', 'rgba(226,226,226,0.2)'],
-                },
-              },
+        },
+        axisTick: {
+          show: false,
+        },
+      },
+      yAxis: [
+        {
+          type: 'value',
+          max: 80000,
+          splitNumber: 4,
+          axisTick: {
+            show: false,
+          },
+          splitArea: {
+            show: true,
+            areaStyle: {
+              color: ['rgba(255,255,255,0.2)', 'rgba(226,226,226,0.2)'],
             },
+          },
+        },
+      ],
+      grid: { left: '1%', right: '1%', top: '2  %', bottom: 0, containLabel: true },
+      series: [
+        {
+          smooth: true,
+          data: [
+            111, 222, 4000, 18000, 33333, 55555, 66666, 33333, 14000, 36000, 66666, 44444, 22222,
+            11111, 4000, 2000, 500, 333, 222, 111,
           ],
-          grid: { left: '1%', right: '1%', top: '2  %', bottom: 0, containLabel: true },
-          series: [
-            {
-              smooth: true,
-              data: [
-                111, 222, 4000, 18000, 33333, 55555, 66666, 33333, 14000, 36000, 66666, 44444,
-                22222, 11111, 4000, 2000, 500, 333, 222, 111,
-              ],
-              type: 'line',
-              areaStyle: {},
-              itemStyle: {
-                color: '#5ab1ef',
-              },
-            },
-            {
-              smooth: true,
-              data: [
-                33, 66, 88, 333, 3333, 5000, 18000, 3000, 1200, 13000, 22000, 11000, 2221, 1201,
-                390, 198, 60, 30, 22, 11,
-              ],
-              type: 'line',
-              areaStyle: {},
-              itemStyle: {
-                color: '#019680',
-              },
-            },
+          type: 'line',
+          areaStyle: {},
+          itemStyle: {
+            color: '#5ab1ef',
+          },
+        },
+        {
+          smooth: true,
+          data: [
+            33, 66, 88, 333, 3333, 5000, 18000, 3000, 1200, 13000, 22000, 11000, 2221, 1201, 390,
+            198, 60, 30, 22, 11,
           ],
-        });
-      });
-      return { chartRef };
-    },
+          type: 'line',
+          areaStyle: {},
+          itemStyle: {
+            color: '#019680',
+          },
+        },
+      ],
+    });
   });
 </script>

+ 49 - 53
src/views/dashboard/analysis/components/VisitAnalysisBar.vue

@@ -1,62 +1,58 @@
 <template>
   <div ref="chartRef" :style="{ height, width }"></div>
 </template>
-<script lang="ts">
-  import { defineComponent, onMounted, ref, Ref } from 'vue';
-
+<script lang="ts" setup>
+  import { onMounted, ref, Ref } from 'vue';
   import { useECharts } from '/@/hooks/web/useECharts';
-
   import { basicProps } from './props';
-  export default defineComponent({
-    props: basicProps,
-    setup() {
-      const chartRef = ref<HTMLDivElement | null>(null);
-      const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);
 
-      onMounted(() => {
-        setOptions({
-          tooltip: {
-            trigger: 'axis',
-            axisPointer: {
-              lineStyle: {
-                width: 1,
-                color: '#019680',
-              },
-            },
-          },
-          grid: { left: '1%', right: '1%', top: '2  %', bottom: 0, containLabel: true },
-          xAxis: {
-            type: 'category',
-            data: [
-              '1月',
-              '2月',
-              '3月',
-              '4月',
-              '5月',
-              '6月',
-              '7月',
-              '8月',
-              '9月',
-              '10月',
-              '11月',
-              '12月',
-            ],
-          },
-          yAxis: {
-            type: 'value',
-            max: 8000,
-            splitNumber: 4,
+  defineProps({
+    ...basicProps,
+  });
+
+  const chartRef = ref<HTMLDivElement | null>(null);
+  const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);
+  onMounted(() => {
+    setOptions({
+      tooltip: {
+        trigger: 'axis',
+        axisPointer: {
+          lineStyle: {
+            width: 1,
+            color: '#019680',
           },
-          series: [
-            {
-              data: [3000, 2000, 3333, 5000, 3200, 4200, 3200, 2100, 3000, 5100, 6000, 3200, 4800],
-              type: 'bar',
-              barMaxWidth: 80,
-            },
-          ],
-        });
-      });
-      return { chartRef };
-    },
+        },
+      },
+      grid: { left: '1%', right: '1%', top: '2  %', bottom: 0, containLabel: true },
+      xAxis: {
+        type: 'category',
+        data: [
+          '1月',
+          '2月',
+          '3月',
+          '4月',
+          '5月',
+          '6月',
+          '7月',
+          '8月',
+          '9月',
+          '10月',
+          '11月',
+          '12月',
+        ],
+      },
+      yAxis: {
+        type: 'value',
+        max: 8000,
+        splitNumber: 4,
+      },
+      series: [
+        {
+          data: [3000, 2000, 3333, 5000, 3200, 4200, 3200, 2100, 3000, 5100, 6000, 3200, 4800],
+          type: 'bar',
+          barMaxWidth: 80,
+        },
+      ],
+    });
   });
 </script>

+ 83 - 89
src/views/dashboard/analysis/components/VisitRadar.vue

@@ -3,104 +3,98 @@
     <div ref="chartRef" :style="{ width, height }"></div>
   </Card>
 </template>
-<script lang="ts">
-  import { defineComponent, Ref, ref, watch } from 'vue';
-
+<script lang="ts" setup>
+  import { Ref, ref, watch } from 'vue';
   import { Card } from 'ant-design-vue';
   import { useECharts } from '/@/hooks/web/useECharts';
 
-  export default defineComponent({
-    components: { Card },
-    props: {
-      loading: Boolean,
-      width: {
-        type: String as PropType<string>,
-        default: '100%',
-      },
-      height: {
-        type: String as PropType<string>,
-        default: '300px',
-      },
+  const props = defineProps({
+    loading: Boolean,
+    width: {
+      type: String as PropType<string>,
+      default: '100%',
+    },
+    height: {
+      type: String as PropType<string>,
+      default: '300px',
     },
-    setup(props) {
-      const chartRef = ref<HTMLDivElement | null>(null);
-      const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);
-      watch(
-        () => props.loading,
-        () => {
-          if (props.loading) {
-            return;
-          }
-          setOptions({
-            legend: {
-              bottom: 0,
-              data: ['访问', '购买'],
+  });
+
+  const chartRef = ref<HTMLDivElement | null>(null);
+  const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);
+  watch(
+    () => props.loading,
+    () => {
+      if (props.loading) {
+        return;
+      }
+      setOptions({
+        legend: {
+          bottom: 0,
+          data: ['访问', '购买'],
+        },
+        tooltip: {},
+        radar: {
+          radius: '60%',
+          splitNumber: 8,
+          indicator: [
+            {
+              text: '电脑',
+              max: 100,
             },
-            tooltip: {},
-            radar: {
-              radius: '60%',
-              splitNumber: 8,
-              indicator: [
-                {
-                  text: '电脑',
-                  max: 100,
-                },
-                {
-                  text: '充电器',
-                  max: 100,
-                },
-                {
-                  text: '耳机',
-                  max: 100,
-                },
-                {
-                  text: '手机',
-                  max: 100,
-                },
-                {
-                  text: 'Ipad',
-                  max: 100,
-                },
-                {
-                  text: '耳机',
-                  max: 100,
-                },
-              ],
+            {
+              text: '充电器',
+              max: 100,
             },
-            series: [
+            {
+              text: '耳机',
+              max: 100,
+            },
+            {
+              text: '手机',
+              max: 100,
+            },
+            {
+              text: 'Ipad',
+              max: 100,
+            },
+            {
+              text: '耳机',
+              max: 100,
+            },
+          ],
+        },
+        series: [
+          {
+            type: 'radar',
+            symbolSize: 0,
+            areaStyle: {
+              shadowBlur: 0,
+              shadowColor: 'rgba(0,0,0,.2)',
+              shadowOffsetX: 0,
+              shadowOffsetY: 10,
+              opacity: 1,
+            },
+            data: [
               {
-                type: 'radar',
-                symbolSize: 0,
-                areaStyle: {
-                  shadowBlur: 0,
-                  shadowColor: 'rgba(0,0,0,.2)',
-                  shadowOffsetX: 0,
-                  shadowOffsetY: 10,
-                  opacity: 1,
+                value: [90, 50, 86, 40, 50, 20],
+                name: '访问',
+                itemStyle: {
+                  color: '#b6a2de',
+                },
+              },
+              {
+                value: [70, 75, 70, 76, 20, 85],
+                name: '购买',
+                itemStyle: {
+                  color: '#5ab1ef',
                 },
-                data: [
-                  {
-                    value: [90, 50, 86, 40, 50, 20],
-                    name: '访问',
-                    itemStyle: {
-                      color: '#b6a2de',
-                    },
-                  },
-                  {
-                    value: [70, 75, 70, 76, 20, 85],
-                    name: '购买',
-                    itemStyle: {
-                      color: '#5ab1ef',
-                    },
-                  },
-                ],
               },
             ],
-          });
-        },
-        { immediate: true }
-      );
-      return { chartRef };
+          },
+        ],
+      });
     },
-  });
+    { immediate: true }
+  );
 </script>

+ 66 - 74
src/views/dashboard/analysis/components/VisitSource.vue

@@ -3,86 +3,78 @@
     <div ref="chartRef" :style="{ width, height }"></div>
   </Card>
 </template>
-<script lang="ts">
-  import { defineComponent, Ref, ref, watch } from 'vue';
-
+<script lang="ts" setup>
+  import { Ref, ref, watch } from 'vue';
   import { Card } from 'ant-design-vue';
   import { useECharts } from '/@/hooks/web/useECharts';
-
-  export default defineComponent({
-    components: { Card },
-    props: {
-      loading: Boolean,
-      width: {
-        type: String as PropType<string>,
-        default: '100%',
-      },
-      height: {
-        type: String as PropType<string>,
-        default: '300px',
-      },
+  const props = defineProps({
+    loading: Boolean,
+    width: {
+      type: String as PropType<string>,
+      default: '100%',
     },
-    setup(props) {
-      const chartRef = ref<HTMLDivElement | null>(null);
-      const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);
-      watch(
-        () => props.loading,
-        () => {
-          if (props.loading) {
-            return;
-          }
-          setOptions({
-            tooltip: {
-              trigger: 'item',
+    height: {
+      type: String as PropType<string>,
+      default: '300px',
+    },
+  });
+  const chartRef = ref<HTMLDivElement | null>(null);
+  const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);
+  watch(
+    () => props.loading,
+    () => {
+      if (props.loading) {
+        return;
+      }
+      setOptions({
+        tooltip: {
+          trigger: 'item',
+        },
+        legend: {
+          bottom: '1%',
+          left: 'center',
+        },
+        series: [
+          {
+            color: ['#5ab1ef', '#b6a2de', '#67e0e3', '#2ec7c9'],
+            name: '访问来源',
+            type: 'pie',
+            radius: ['40%', '70%'],
+            avoidLabelOverlap: false,
+            itemStyle: {
+              borderRadius: 10,
+              borderColor: '#fff',
+              borderWidth: 2,
             },
-            legend: {
-              bottom: '1%',
-              left: 'center',
+            label: {
+              show: false,
+              position: 'center',
             },
-            series: [
-              {
-                color: ['#5ab1ef', '#b6a2de', '#67e0e3', '#2ec7c9'],
-                name: '访问来源',
-                type: 'pie',
-                radius: ['40%', '70%'],
-                avoidLabelOverlap: false,
-                itemStyle: {
-                  borderRadius: 10,
-                  borderColor: '#fff',
-                  borderWidth: 2,
-                },
-                label: {
-                  show: false,
-                  position: 'center',
-                },
-                emphasis: {
-                  label: {
-                    show: true,
-                    fontSize: '12',
-                    fontWeight: 'bold',
-                  },
-                },
-                labelLine: {
-                  show: false,
-                },
-                data: [
-                  { value: 1048, name: '搜索引擎' },
-                  { value: 735, name: '直接访问' },
-                  { value: 580, name: '邮件营销' },
-                  { value: 484, name: '联盟广告' },
-                ],
-                animationType: 'scale',
-                animationEasing: 'exponentialInOut',
-                animationDelay: function () {
-                  return Math.random() * 100;
-                },
+            emphasis: {
+              label: {
+                show: true,
+                fontSize: '12',
+                fontWeight: 'bold',
               },
+            },
+            labelLine: {
+              show: false,
+            },
+            data: [
+              { value: 1048, name: '搜索引擎' },
+              { value: 735, name: '直接访问' },
+              { value: 580, name: '邮件营销' },
+              { value: 484, name: '联盟广告' },
             ],
-          });
-        },
-        { immediate: true }
-      );
-      return { chartRef };
+            animationType: 'scale',
+            animationEasing: 'exponentialInOut',
+            animationDelay: function () {
+              return Math.random() * 100;
+            },
+          },
+        ],
+      });
     },
-  });
+    { immediate: true }
+  );
 </script>

+ 6 - 20
src/views/dashboard/analysis/index.vue

@@ -2,38 +2,24 @@
   <div class="p-4">
     <GrowCard :loading="loading" class="enter-y" />
     <SiteAnalysis class="!my-4 enter-y" :loading="loading" />
-
     <div class="md:flex enter-y">
       <VisitRadar class="md:w-1/3 w-full" :loading="loading" />
-
       <VisitSource class="md:w-1/3 !md:mx-4 !md:my-0 !my-4 w-full" :loading="loading" />
       <SalesProductPie class="md:w-1/3 w-full" :loading="loading" />
     </div>
   </div>
 </template>
-<script lang="ts">
-  import { defineComponent, ref } from 'vue';
+<script lang="ts" setup>
+  import { ref } from 'vue';
   import GrowCard from './components/GrowCard.vue';
   import SiteAnalysis from './components/SiteAnalysis.vue';
   import VisitSource from './components/VisitSource.vue';
   import VisitRadar from './components/VisitRadar.vue';
   import SalesProductPie from './components/SalesProductPie.vue';
 
-  export default defineComponent({
-    components: {
-      GrowCard,
-      SiteAnalysis,
-      VisitRadar,
-      VisitSource,
-      SalesProductPie,
-    },
-    setup() {
-      const loading = ref(true);
+  const loading = ref(true);
 
-      setTimeout(() => {
-        loading.value = false;
-      }, 1500);
-      return { loading };
-    },
-  });
+  setTimeout(() => {
+    loading.value = false;
+  }, 1500);
 </script>

+ 4 - 11
src/views/dashboard/workbench/components/DynamicInfo.vue

@@ -3,7 +3,7 @@
     <template #extra>
       <a-button type="link" size="small">更多</a-button>
     </template>
-    <List item-layout="horizontal" :data-source="items">
+    <List item-layout="horizontal" :data-source="dynamicInfoItems">
       <template #renderItem="{ item }">
         <ListItem>
           <ListItemMeta>
@@ -21,18 +21,11 @@
     </List>
   </Card>
 </template>
-<script lang="ts">
-  import { defineComponent } from 'vue';
-
+<script lang="ts" setup>
   import { Card, List } from 'ant-design-vue';
   import { dynamicInfoItems } from './data';
-  import headerImg from '/@/assets/images/header.jpg';
   import { Icon } from '/@/components/Icon';
 
-  export default defineComponent({
-    components: { Card, List, ListItem: List.Item, ListItemMeta: List.Item.Meta, Icon },
-    setup() {
-      return { items: dynamicInfoItems, headerImg };
-    },
-  });
+  const ListItem = List.Item;
+  const ListItemMeta = List.Item.Meta;
 </script>

+ 0 - 1
src/views/dashboard/workbench/components/ProjectCard.vue

@@ -21,7 +21,6 @@
 </template>
 <script lang="ts">
   import { defineComponent } from 'vue';
-
   import { Card } from 'ant-design-vue';
   import { Icon } from '/@/components/Icon';
   import { groupItems } from './data';

+ 4 - 11
src/views/dashboard/workbench/components/QuickNav.vue

@@ -1,6 +1,6 @@
 <template>
   <Card title="快捷导航" v-bind="$attrs">
-    <template v-for="item in items" :key="item">
+    <template v-for="item in navItems" :key="item">
       <CardGrid>
         <span class="flex flex-col items-center">
           <Icon :icon="item.icon" :color="item.color" size="20" />
@@ -10,17 +10,10 @@
     </template>
   </Card>
 </template>
-<script lang="ts">
-  import { defineComponent } from 'vue';
-
+<script lang="ts" setup>
   import { Card } from 'ant-design-vue';
-  import { Icon } from '/@/components/Icon';
   import { navItems } from './data';
+  import { Icon } from '/@/components/Icon';
 
-  export default defineComponent({
-    components: { Card, CardGrid: Card.Grid, Icon },
-    setup() {
-      return { items: navItems };
-    },
-  });
+  const CardGrid = Card.Grid;
 </script>

+ 83 - 89
src/views/dashboard/workbench/components/SaleRadar.vue

@@ -3,104 +3,98 @@
     <div ref="chartRef" :style="{ width, height }"></div>
   </Card>
 </template>
-<script lang="ts">
-  import { defineComponent, Ref, ref, watch } from 'vue';
-
+<script lang="ts" setup>
+  import { Ref, ref, watch } from 'vue';
   import { Card } from 'ant-design-vue';
   import { useECharts } from '/@/hooks/web/useECharts';
 
-  export default defineComponent({
-    components: { Card },
-    props: {
-      loading: Boolean,
-      width: {
-        type: String as PropType<string>,
-        default: '100%',
-      },
-      height: {
-        type: String as PropType<string>,
-        default: '400px',
-      },
+  const props = defineProps({
+    loading: Boolean,
+    width: {
+      type: String as PropType<string>,
+      default: '100%',
+    },
+    height: {
+      type: String as PropType<string>,
+      default: '400px',
     },
-    setup(props) {
-      const chartRef = ref<HTMLDivElement | null>(null);
-      const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);
-      watch(
-        () => props.loading,
-        () => {
-          if (props.loading) {
-            return;
-          }
-          setOptions({
-            legend: {
-              bottom: 0,
-              data: ['Visits', 'Sales'],
+  });
+
+  const chartRef = ref<HTMLDivElement | null>(null);
+  const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);
+  watch(
+    () => props.loading,
+    () => {
+      if (props.loading) {
+        return;
+      }
+      setOptions({
+        legend: {
+          bottom: 0,
+          data: ['Visits', 'Sales'],
+        },
+        tooltip: {},
+        radar: {
+          radius: '60%',
+          splitNumber: 8,
+          indicator: [
+            {
+              text: '2017',
+              max: 100,
             },
-            tooltip: {},
-            radar: {
-              radius: '60%',
-              splitNumber: 8,
-              indicator: [
-                {
-                  text: '2017',
-                  max: 100,
-                },
-                {
-                  text: '2017',
-                  max: 100,
-                },
-                {
-                  text: '2018',
-                  max: 100,
-                },
-                {
-                  text: '2019',
-                  max: 100,
-                },
-                {
-                  text: '2020',
-                  max: 100,
-                },
-                {
-                  text: '2021',
-                  max: 100,
-                },
-              ],
+            {
+              text: '2017',
+              max: 100,
             },
-            series: [
+            {
+              text: '2018',
+              max: 100,
+            },
+            {
+              text: '2019',
+              max: 100,
+            },
+            {
+              text: '2020',
+              max: 100,
+            },
+            {
+              text: '2021',
+              max: 100,
+            },
+          ],
+        },
+        series: [
+          {
+            type: 'radar',
+            symbolSize: 0,
+            areaStyle: {
+              shadowBlur: 0,
+              shadowColor: 'rgba(0,0,0,.2)',
+              shadowOffsetX: 0,
+              shadowOffsetY: 10,
+              opacity: 1,
+            },
+            data: [
               {
-                type: 'radar',
-                symbolSize: 0,
-                areaStyle: {
-                  shadowBlur: 0,
-                  shadowColor: 'rgba(0,0,0,.2)',
-                  shadowOffsetX: 0,
-                  shadowOffsetY: 10,
-                  opacity: 1,
+                value: [90, 50, 86, 40, 50, 20],
+                name: 'Visits',
+                itemStyle: {
+                  color: '#b6a2de',
+                },
+              },
+              {
+                value: [70, 75, 70, 76, 20, 85],
+                name: 'Sales',
+                itemStyle: {
+                  color: '#67e0e3',
                 },
-                data: [
-                  {
-                    value: [90, 50, 86, 40, 50, 20],
-                    name: 'Visits',
-                    itemStyle: {
-                      color: '#b6a2de',
-                    },
-                  },
-                  {
-                    value: [70, 75, 70, 76, 20, 85],
-                    name: 'Sales',
-                    itemStyle: {
-                      color: '#67e0e3',
-                    },
-                  },
-                ],
               },
             ],
-          });
-        },
-        { immediate: true }
-      );
-      return { chartRef };
+          },
+        ],
+      });
     },
-  });
+    { immediate: true }
+  );
 </script>

+ 5 - 12
src/views/dashboard/workbench/components/WorkbenchHeader.vue

@@ -22,19 +22,12 @@
     </div>
   </div>
 </template>
-<script lang="ts">
-  import { computed, defineComponent } from 'vue';
-
+<script lang="ts" setup>
+  import { computed } from 'vue';
   import { Avatar } from 'ant-design-vue';
   import { useUserStore } from '/@/store/modules/user';
-
   import headerImg from '/@/assets/images/header.jpg';
-  export default defineComponent({
-    components: { Avatar },
-    setup() {
-      const userStore = useUserStore();
-      const userinfo = computed(() => userStore.getUserInfo);
-      return { userinfo, headerImg };
-    },
-  });
+
+  const userStore = useUserStore();
+  const userinfo = computed(() => userStore.getUserInfo);
 </script>

+ 6 - 24
src/views/dashboard/workbench/index.vue

@@ -18,9 +18,8 @@
     </div>
   </PageWrapper>
 </template>
-<script lang="ts">
-  import { defineComponent, ref } from 'vue';
-
+<script lang="ts" setup>
+  import { ref } from 'vue';
   import { Card } from 'ant-design-vue';
   import { PageWrapper } from '/@/components/Page';
   import WorkbenchHeader from './components/WorkbenchHeader.vue';
@@ -29,26 +28,9 @@
   import DynamicInfo from './components/DynamicInfo.vue';
   import SaleRadar from './components/SaleRadar.vue';
 
-  export default defineComponent({
-    components: {
-      PageWrapper,
-      WorkbenchHeader,
-      ProjectCard,
-      QuickNav,
-      DynamicInfo,
-      SaleRadar,
-      Card,
-    },
-    setup() {
-      const loading = ref(true);
-
-      setTimeout(() => {
-        loading.value = false;
-      }, 1500);
+  const loading = ref(true);
 
-      return {
-        loading,
-      };
-    },
-  });
+  setTimeout(() => {
+    loading.value = false;
+  }, 1500);
 </script>

+ 89 - 199
yarn.lock

@@ -1576,17 +1576,6 @@
     source-map "^0.6.1"
     write-file-atomic "^3.0.0"
 
-"@jest/types@^26.6.2":
-  version "26.6.2"
-  resolved "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz#bef5a532030e1d88a2f5a6d933f84e97226ed48e"
-  integrity sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==
-  dependencies:
-    "@types/istanbul-lib-coverage" "^2.0.0"
-    "@types/istanbul-reports" "^3.0.0"
-    "@types/node" "*"
-    "@types/yargs" "^15.0.0"
-    chalk "^4.0.0"
-
 "@jest/types@^27.0.2":
   version "27.0.2"
   resolved "https://registry.npmjs.org/@jest/types/-/types-27.0.2.tgz#e153d6c46bda0f2589f0702b071f9898c7bbd37e"
@@ -1978,13 +1967,13 @@
   dependencies:
     "@types/istanbul-lib-report" "*"
 
-"@types/jest@^27.0.0":
-  version "27.0.0"
-  resolved "https://registry.yarnpkg.com/@types/jest/-/jest-27.0.0.tgz#f1c28f741371739c7cd0e8edb5ed8e67acfa6c35"
-  integrity sha512-IlpQZVpxufe+3qPaAqEoSPHVSxnJh1cf0BqqWHJeKiAUbwnHdmNzjP3ZCWSZSTbmAGXQPNk9QmM3Bif0pR54rg==
+"@types/jest@^27.0.1":
+  version "27.0.1"
+  resolved "https://registry.yarnpkg.com/@types/jest/-/jest-27.0.1.tgz#fafcc997da0135865311bb1215ba16dba6bdf4ca"
+  integrity sha512-HTLpVXHrY69556ozYkcq47TtQJXpcWAWfkoqz+ZGz2JnmZhzlRjprCIyFnetSy8gpDWwTTGBcRVv1J1I1vBrHw==
   dependencies:
-    jest-diff "^26.0.0"
-    pretty-format "^26.0.0"
+    jest-diff "^27.0.0"
+    pretty-format "^27.0.0"
 
 "@types/json-schema@^7.0.7":
   version "7.0.7"
@@ -2040,10 +2029,10 @@
   resolved "https://registry.npmjs.org/@types/node/-/node-14.17.3.tgz#6d327abaa4be34a74e421ed6409a0ae2f47f4c3d"
   integrity sha512-e6ZowgGJmTuXa3GyaPbTGxX17tnThl2aSSizrFthQ7m9uLGZBXiGhgE55cjRZTF5kjZvYn9EOPOMljdjwbflxw==
 
-"@types/node@^16.6.0":
-  version "16.6.0"
-  resolved "https://registry.yarnpkg.com/@types/node/-/node-16.6.0.tgz#0d5685f85066f94e97f19e8a67fe003c5fadacc4"
-  integrity sha512-OyiZPohMMjZEYqcVo/UJ04GyAxXOJEZO/FpzyXxcH4r/ArrVoXHf4MbUrkLp0Tz7/p1mMKpo5zJ6ZHl8XBNthQ==
+"@types/node@^16.6.1":
+  version "16.6.1"
+  resolved "https://registry.yarnpkg.com/@types/node/-/node-16.6.1.tgz#aee62c7b966f55fc66c7b6dfa1d58db2a616da61"
+  integrity sha512-Sr7BhXEAer9xyGuCN3Ek9eg9xPviCF2gfu9kTfuU2HkTVAMYSDeX40fvpmo72n5nansg3nsBjuQBrsS28r+NUw==
 
 "@types/normalize-package-data@^2.4.0":
   version "2.4.0"
@@ -2138,13 +2127,6 @@
   resolved "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.0.tgz#dd3e6699ba3237f0348cd085e4698780204842f9"
   integrity sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA==
 
-"@types/yargs@^15.0.0":
-  version "15.0.13"
-  resolved "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.13.tgz#34f7fec8b389d7f3c1fd08026a5763e072d3c6dc"
-  integrity sha512-kQ5JNTrbDv3Rp5X2n/iUu37IJBDU2gsZ5R/g1/KHOOEc5IKfUFjXT6DENPGduh08I/pamwtEq4oul7gUqKTQDQ==
-  dependencies:
-    "@types/yargs-parser" "*"
-
 "@types/yargs@^16.0.0":
   version "16.0.3"
   resolved "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.3.tgz#4b6d35bb8e680510a7dc2308518a80ee1ef27e01"
@@ -2295,45 +2277,58 @@
   resolved "https://registry.yarnpkg.com/@vitejs/plugin-vue/-/plugin-vue-1.4.0.tgz#962ae01b7fd16ad4007898c64ed639136e12215b"
   integrity sha512-RkqfJHz9wdLKBp5Yi+kQL8BAljdrvPoccQm2PTZc/UcL4EjD11xsv2PPCduYx2oV1a/bpSKA3sD5sxOHFhz+LA==
 
-"@volar/code-gen@^0.26.6":
-  version "0.26.6"
-  resolved "https://registry.yarnpkg.com/@volar/code-gen/-/code-gen-0.26.6.tgz#9dd048c6feb878c9a5e1909bc44dd7626d34538a"
-  integrity sha512-7xSND3hcHmPGvTL5MHekQZ8ORVj4cCbBstUm6JdsNwjFNIaaQtUPxpSfAUKprZMgIE3ya2jDzH2g4iq0e3VuNg==
+"@volar/code-gen@^0.27.1":
+  version "0.27.1"
+  resolved "https://registry.yarnpkg.com/@volar/code-gen/-/code-gen-0.27.1.tgz#5fbf3808b000a1e3966b4916689c55958efaf70d"
+  integrity sha512-tN7Rxa7mAfd8GQceKxHjjDjfRo3S4OBIEtv4GpmO75IrodjMVkZEZR/v6EY3yn52ffTh3SuAvjiCSRRcHhvDqg==
   dependencies:
-    "@volar/shared" "^0.26.6"
-    "@volar/source-map" "^0.26.6"
+    "@volar/shared" "^0.27.1"
+    "@volar/source-map" "^0.27.1"
 
-"@volar/html2pug@^0.26.6":
-  version "0.26.6"
-  resolved "https://registry.yarnpkg.com/@volar/html2pug/-/html2pug-0.26.6.tgz#82ab7a9ac0723f97d075c3bd34ffae7e3c49b208"
-  integrity sha512-tJoXNr//ENegJK7/2QrvHqt2CHYowwdMIhqf0sXHZbyFHQq5OBv8S1TTQdejBV+w790l1NqG5Wi4kq7kFl66gA==
+"@volar/html2pug@^0.27.1":
+  version "0.27.1"
+  resolved "https://registry.yarnpkg.com/@volar/html2pug/-/html2pug-0.27.1.tgz#9c996c189859e002a2e016b25ea04022fa321890"
+  integrity sha512-4192qerpj+fuzmaduT8l9qoY7620oh4LNEK2GN8V9l7+LNAuPRr9kN0BNrow2j1WO9lklhtNqDlCSOmPCmcoPA==
   dependencies:
     domelementtype "^2.2.0"
     domhandler "^4.2.0"
     htmlparser2 "^6.1.0"
     pug "^3.0.2"
 
-"@volar/shared@^0.26.6":
-  version "0.26.6"
-  resolved "https://registry.yarnpkg.com/@volar/shared/-/shared-0.26.6.tgz#ea40995048b443747ace80b9247e05bc4eeb35e7"
-  integrity sha512-b3dvEnhaYHnJb8qibL4NzWvu6YX3Qi7soN25EXtHnHaCtASw3/3uGcMqH4aBLGPE3YilPWVT1TI8PFKKevzSuA==
+"@volar/shared@^0.27.1":
+  version "0.27.1"
+  resolved "https://registry.yarnpkg.com/@volar/shared/-/shared-0.27.1.tgz#004933283d1c479e46c33534f6b52b594728eaac"
+  integrity sha512-PvoD6cp3ICaZXsLcuEB14FkrQuJnQVuhtAiss6BLGFfq4vOhJPMZihfoSZtQYkspkZ1/r8IgidMZqTtuAxYBzA==
   dependencies:
     upath "^2.0.1"
     vscode-jsonrpc "^8.0.0-next.1"
+    vscode-uri "^3.0.2"
 
-"@volar/source-map@^0.26.6":
-  version "0.26.6"
-  resolved "https://registry.yarnpkg.com/@volar/source-map/-/source-map-0.26.6.tgz#38cada2cab5f94977f7b739714b5b21a73363e96"
-  integrity sha512-ArmmaOM08EYWw40VjjSGrQSg89cCktbs//yQxxNowWZYe7gsTQvS27jO2534vKWdmnulNhsLeWN1BphnNrGDeg==
+"@volar/source-map@^0.27.1":
+  version "0.27.1"
+  resolved "https://registry.yarnpkg.com/@volar/source-map/-/source-map-0.27.1.tgz#1e0fd73f4bfc46f9e70e7d3f8a1b1c03b816ce6d"
+  integrity sha512-Y4cJjAIfMhoHg0jsO8uUZ4YvJAxDYSwWRD9corm+2W/4Km5AKSF7hhVwFSGy2WvODTRLZY2jjlL3eu88m1eg/g==
   dependencies:
-    "@volar/shared" "^0.26.6"
+    "@volar/shared" "^0.27.1"
 
-"@volar/transforms@^0.26.6":
-  version "0.26.6"
-  resolved "https://registry.yarnpkg.com/@volar/transforms/-/transforms-0.26.6.tgz#680f7faf8a9a3bf92509447e011f43245d4916a6"
-  integrity sha512-gkz9HhzFf7szcQiOcb4sQ8970oNH6AR1veyl1fzwwF3oC2rWF7CEXIdkDgf+jRmYit4SU5Pnrij6tX4BXoKCug==
+"@volar/transforms@^0.27.1":
+  version "0.27.1"
+  resolved "https://registry.yarnpkg.com/@volar/transforms/-/transforms-0.27.1.tgz#117a7cd5d12ca1bf0c83715201f93e630b4211bd"
+  integrity sha512-jEWYXFQL+KUVS85qrYYsaQYtwdLZLs3koNFEMEQMnDMad3jEBDqd3IKgDGePI6jQ5Vq3jFneNwX1GGCFJeKvJA==
   dependencies:
-    "@volar/shared" "^0.26.6"
+    "@volar/shared" "^0.27.1"
+
+"@vscode/emmet-helper@^2.7.0":
+  version "2.7.0"
+  resolved "https://registry.yarnpkg.com/@vscode/emmet-helper/-/emmet-helper-2.7.0.tgz#3db485f6a650196ff8bbd38ba1b9e468ec8d22f8"
+  integrity sha512-LL7MoKNLUQASacQROO7hBdx5IAxsEnA0UdJFd9xXyf3sBQgz8NE3QEfo3IezE7uin8W2fkG2+EXMst3oqK6+KQ==
+  dependencies:
+    emmet "^2.3.0"
+    jsonc-parser "^2.3.0"
+    vscode-languageserver-textdocument "^1.0.1"
+    vscode-languageserver-types "^3.15.1"
+    vscode-nls "^5.0.0"
+    vscode-uri "^2.1.2"
 
 "@vue/babel-helper-vue-transform-on@^1.0.2":
   version "1.0.2"
@@ -2355,17 +2350,6 @@
     html-tags "^3.1.0"
     svg-tags "^1.0.0"
 
-"@vue/compiler-core@3.2.0-beta.3":
-  version "3.2.0-beta.3"
-  resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.2.0-beta.3.tgz#3a10628c6bb4d4b5df28bcdb6522a6c7702fc152"
-  integrity sha512-Uyu7xT3z3D8+1ZWDuFtoMoRIPj665Vp7BlULi4TuthXTteKtDy8rygqCV2TAuKJS6APY96NZxRyWd3wlO2qDOw==
-  dependencies:
-    "@babel/parser" "^7.12.0"
-    "@babel/types" "^7.12.0"
-    "@vue/shared" "3.2.0-beta.3"
-    estree-walker "^2.0.1"
-    source-map "^0.6.1"
-
 "@vue/compiler-core@3.2.2":
   version "3.2.2"
   resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.2.2.tgz#8d3e29f129579ed9b14f48af735fd8d95f248504"
@@ -2377,15 +2361,7 @@
     estree-walker "^2.0.1"
     source-map "^0.6.1"
 
-"@vue/compiler-dom@3.2.0-beta.3", "@vue/compiler-dom@^3.2.0-beta.3":
-  version "3.2.0-beta.3"
-  resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.2.0-beta.3.tgz#4fc64ad7ce708e2821800200d58f089aa4481b41"
-  integrity sha512-scpBC68ZLGSU61W8xUJE97kZFZsrBZwaZtUy59dXFGrlIQtRd2HzyjCrXgLFgvYnlQLXPqaYpo5dJ1z1yNo2GQ==
-  dependencies:
-    "@vue/compiler-core" "3.2.0-beta.3"
-    "@vue/shared" "3.2.0-beta.3"
-
-"@vue/compiler-dom@3.2.2":
+"@vue/compiler-dom@3.2.2", "@vue/compiler-dom@^3.2.2":
   version "3.2.2"
   resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.2.2.tgz#26e198498746c53047c3744d26fc95e670692ab7"
   integrity sha512-ggcc+NV/ENIE0Uc3TxVE/sKrhYVpLepMAAmEiQ047332mbKOvUkowz4TTFZ+YkgOIuBOPP0XpCxmCMg7p874mA==
@@ -2393,7 +2369,7 @@
     "@vue/compiler-core" "3.2.2"
     "@vue/shared" "3.2.2"
 
-"@vue/compiler-sfc@3.2.2":
+"@vue/compiler-sfc@3.2.2", "@vue/compiler-sfc@^3.2.2":
   version "3.2.2"
   resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.2.2.tgz#5b7b13b07689be8e4880d856f72d1be500785be9"
   integrity sha512-hrtqpQ5L6IPn5v7yVRo7uvLcQxv0z1+KBjZBWMBOcrXz4t+PKUxU/SWd6Tl9T8FDmYlunzKUh6lcx+2CLo6f5A==
@@ -2416,37 +2392,6 @@
     postcss-selector-parser "^6.0.4"
     source-map "^0.6.1"
 
-"@vue/compiler-sfc@^3.2.0-beta.3":
-  version "3.2.0-beta.3"
-  resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.2.0-beta.3.tgz#8199e8166a6721e7554d0d8446f8ff3752a45492"
-  integrity sha512-M50steBwRJiAYvCvVe1kFiab9Gj+NBZTpO6rRaXSWEvptv9blIdpdFiPFzGUhKB65/xGbdj3fyUN9fzXkIjrwA==
-  dependencies:
-    "@babel/parser" "^7.13.9"
-    "@babel/types" "^7.13.0"
-    "@types/estree" "^0.0.48"
-    "@vue/compiler-core" "3.2.0-beta.3"
-    "@vue/compiler-dom" "3.2.0-beta.3"
-    "@vue/compiler-ssr" "3.2.0-beta.3"
-    "@vue/shared" "3.2.0-beta.3"
-    consolidate "^0.16.0"
-    estree-walker "^2.0.1"
-    hash-sum "^2.0.0"
-    lru-cache "^5.1.1"
-    magic-string "^0.25.7"
-    merge-source-map "^1.1.0"
-    postcss "^8.1.10"
-    postcss-modules "^4.0.0"
-    postcss-selector-parser "^6.0.4"
-    source-map "^0.6.1"
-
-"@vue/compiler-ssr@3.2.0-beta.3":
-  version "3.2.0-beta.3"
-  resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.2.0-beta.3.tgz#88106c28f915a17131652eace2032f8d70b05734"
-  integrity sha512-FVE9RfuNG6YyIo8vTO2yy4ibAkK+Ks+6qcLS2bzuoQbMHNXxWwI041ll8crHR9jlRjPF0u/Ng3Blf1PbT1+yRA==
-  dependencies:
-    "@vue/compiler-dom" "3.2.0-beta.3"
-    "@vue/shared" "3.2.0-beta.3"
-
 "@vue/compiler-ssr@3.2.2":
   version "3.2.2"
   resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.2.2.tgz#633bb8e01f00a969c35ca12db32be7fe4c7185a9"
@@ -2465,20 +2410,13 @@
   resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-6.0.0-beta.15.tgz#ad7cb384e062f165bcf9c83732125bffbc2ad83d"
   integrity sha512-quBx4Jjpexo6KDiNUGFr/zF/2A4srKM9S9v2uHgMXSU//hjgq1eGzqkIFql8T9gfX5ZaVOUzYBP3jIdIR3PKIA==
 
-"@vue/reactivity@3.2.2":
+"@vue/reactivity@3.2.2", "@vue/reactivity@^3.2.2":
   version "3.2.2"
   resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.2.2.tgz#d37011a68395e038a3cf5256af52d48c591b06b6"
   integrity sha512-IHjhtmrhK6dzacj/EnLQDWOaA3HuzzVk6w84qgV8EpS4uWGIJXiRalMRg6XvGW2ykJvIl3pLsF0aBFlTMRiLOA==
   dependencies:
     "@vue/shared" "3.2.2"
 
-"@vue/reactivity@^3.2.0-beta.3":
-  version "3.2.0-beta.3"
-  resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.2.0-beta.3.tgz#0255cbedbb03f269ee03edbe8af71d9f77a095e7"
-  integrity sha512-Q+7cOgc5gHtY6I+0A6VXNOvOtuKQPHBLIGfGek3LwVDG5MpCY5Wt50u4mMEgiJafjKSgiGYctycWEBzmcI/Jtg==
-  dependencies:
-    "@vue/shared" "3.2.0-beta.3"
-
 "@vue/runtime-core@3.2.2":
   version "3.2.2"
   resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.2.2.tgz#b9a7250783de19dd8dd6febf008084b0f9144586"
@@ -2496,12 +2434,7 @@
     "@vue/shared" "3.2.2"
     csstype "^2.6.8"
 
-"@vue/shared@3.2.0-beta.3", "@vue/shared@^3.2.0-beta.3":
-  version "3.2.0-beta.3"
-  resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.2.0-beta.3.tgz#043c5a4d3bc9676508557e9199c625995cf14929"
-  integrity sha512-IzJBLNwh2CDTbVqQt979f5rczw9Uib97RkaGckmUGuC9bAG1sw/EXskrxc87p8xxaiI70LdVHnOhriprfKjmMw==
-
-"@vue/shared@3.2.2":
+"@vue/shared@3.2.2", "@vue/shared@^3.2.2":
   version "3.2.2"
   resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.2.2.tgz#6104185ebd57af5a14ac51c1f491b2205fc24054"
   integrity sha512-dvYb318tk9uOzHtSaT3WII/HscQSIRzoCZ5GyxEb3JlkEXASpAUAQwKnvSe2CudnF8XHFRTB7VITWSnWNLZUtA==
@@ -4380,11 +4313,6 @@ diff-match-patch@^1.0.5:
   resolved "https://registry.npmjs.org/diff-match-patch/-/diff-match-patch-1.0.5.tgz#abb584d5f10cd1196dfc55aa03701592ae3f7b37"
   integrity sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw==
 
-diff-sequences@^26.6.2:
-  version "26.6.2"
-  resolved "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz#48ba99157de1923412eed41db6b6d4aa9ca7c0b1"
-  integrity sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==
-
 diff-sequences@^27.0.6:
   version "27.0.6"
   resolved "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.6.tgz#3305cb2e55a033924054695cc66019fd7f8e5723"
@@ -6869,19 +6797,9 @@ jest-config@^27.0.6:
     micromatch "^4.0.4"
     pretty-format "^27.0.6"
 
-jest-diff@^26.0.0:
-  version "26.6.2"
-  resolved "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz#1aa7468b52c3a68d7d5c5fdcdfcd5e49bd164394"
-  integrity sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==
-  dependencies:
-    chalk "^4.0.0"
-    diff-sequences "^26.6.2"
-    jest-get-type "^26.3.0"
-    pretty-format "^26.6.2"
-
-jest-diff@^27.0.6:
+jest-diff@^27.0.0, jest-diff@^27.0.6:
   version "27.0.6"
-  resolved "https://registry.npmjs.org/jest-diff/-/jest-diff-27.0.6.tgz#4a7a19ee6f04ad70e0e3388f35829394a44c7b5e"
+  resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-27.0.6.tgz#4a7a19ee6f04ad70e0e3388f35829394a44c7b5e"
   integrity sha512-Z1mqgkTCSYaFgwTlP/NUiRzdqgxmmhzHY1Tq17zL94morOHfHu3K4bgSgl+CR4GLhpV8VxkuOYuIWnQ9LnFqmg==
   dependencies:
     chalk "^4.0.0"
@@ -6932,11 +6850,6 @@ jest-environment-node@^27.0.6:
     jest-mock "^27.0.6"
     jest-util "^27.0.6"
 
-jest-get-type@^26.3.0:
-  version "26.3.0"
-  resolved "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz#e97dc3c3f53c2b406ca7afaed4493b1d099199e0"
-  integrity sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==
-
 jest-get-type@^27.0.6:
   version "27.0.6"
   resolved "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz#0eb5c7f755854279ce9b68a9f1a4122f69047cfe"
@@ -9089,17 +9002,7 @@ pretty-bytes@^5.3.0, pretty-bytes@^5.6.0:
   resolved "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb"
   integrity sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==
 
-pretty-format@^26.0.0, pretty-format@^26.6.2:
-  version "26.6.2"
-  resolved "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz#e35c2705f14cb7fe2fe94fa078345b444120fc93"
-  integrity sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==
-  dependencies:
-    "@jest/types" "^26.6.2"
-    ansi-regex "^5.0.0"
-    ansi-styles "^4.0.0"
-    react-is "^17.0.1"
-
-pretty-format@^27.0.6:
+pretty-format@^27.0.0, pretty-format@^27.0.6:
   version "27.0.6"
   resolved "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.6.tgz#ab770c47b2c6f893a21aefc57b75da63ef49a11f"
   integrity sha512-8tGD7gBIENgzqA+UBzObyWqQ5B778VIFZA/S66cclyd5YkFLYs2Js7gxDKf0MXtTc9zcS7t1xhdfcElJ3YIvkQ==
@@ -11373,18 +11276,6 @@ vscode-css-languageservice@^5.1.4:
     vscode-nls "^5.0.0"
     vscode-uri "^3.0.2"
 
-vscode-emmet-helper@^2.6.4:
-  version "2.6.4"
-  resolved "https://registry.npmjs.org/vscode-emmet-helper/-/vscode-emmet-helper-2.6.4.tgz#bea47f17649bba26b412f3d1fac18aaee43eba25"
-  integrity sha512-fP0nunW1RUWEKGf4gqiYLOVNFFGXSRHjCl0pikxtwCFlty8WwimM+RBJ5o0aIiwerrYD30HqeaVyvDW027Sseg==
-  dependencies:
-    emmet "^2.3.0"
-    jsonc-parser "^2.3.0"
-    vscode-languageserver-textdocument "^1.0.1"
-    vscode-languageserver-types "^3.15.1"
-    vscode-nls "^5.0.0"
-    vscode-uri "^2.1.2"
-
 vscode-html-languageservice@^4.0.7:
   version "4.0.7"
   resolved "https://registry.yarnpkg.com/vscode-html-languageservice/-/vscode-html-languageservice-4.0.7.tgz#94f2ed22c821965f828222d13b5aa541b358d992"
@@ -11446,25 +11337,25 @@ vscode-nls@^5.0.0:
   resolved "https://registry.npmjs.org/vscode-nls/-/vscode-nls-5.0.0.tgz#99f0da0bd9ea7cda44e565a74c54b1f2bc257840"
   integrity sha512-u0Lw+IYlgbEJFF6/qAqG2d1jQmJl0eyAGJHoAJqr2HT4M2BNuQYSEiSE75f52pXHSJm8AlTjnLLbBFPrdz2hpA==
 
-vscode-pug-languageservice@^0.26.6:
-  version "0.26.6"
-  resolved "https://registry.yarnpkg.com/vscode-pug-languageservice/-/vscode-pug-languageservice-0.26.6.tgz#0cd99da7f60420b98dc1a9449c73132c7da12661"
-  integrity sha512-o9wsSOewFTrG/eGA/6aQ0JAcyEE1JLIfONTECORkHeqNo9iS3PuqWnNvg7Z5iHrReAXnJZTEjdogX14muRMBRA==
+vscode-pug-languageservice@^0.27.1:
+  version "0.27.1"
+  resolved "https://registry.yarnpkg.com/vscode-pug-languageservice/-/vscode-pug-languageservice-0.27.1.tgz#5570b935e0cf13bca80fba7aa32ac98ed9604dc2"
+  integrity sha512-zUrcrcizqxxP7UIplzkdpdhU6bS458Vf9MS+fFaaR1WI/rVJOsXh5ETMrVeHTD0FHqAIstikuNoKEpuaaHkEXA==
   dependencies:
-    "@volar/code-gen" "^0.26.6"
-    "@volar/shared" "^0.26.6"
-    "@volar/source-map" "^0.26.6"
-    "@volar/transforms" "^0.26.6"
+    "@volar/code-gen" "^0.27.1"
+    "@volar/shared" "^0.27.1"
+    "@volar/source-map" "^0.27.1"
+    "@volar/transforms" "^0.27.1"
     pug-lexer "^5.0.1"
     pug-parser "^6.0.0"
     vscode-languageserver "^8.0.0-next.1"
 
-vscode-typescript-languageservice@^0.26.6:
-  version "0.26.6"
-  resolved "https://registry.yarnpkg.com/vscode-typescript-languageservice/-/vscode-typescript-languageservice-0.26.6.tgz#1581c06cfe9bbdfdaf6fae4f8e484cbee37ee0c9"
-  integrity sha512-b7JEg72/dyJvv9ND/Q5B5Hjy70v+MBVAlTfreKAG0E5u5JHLEm+Kh4AXrlJU/Vb1jpK1/rhDGAYO3RWYikJh+A==
+vscode-typescript-languageservice@^0.27.1:
+  version "0.27.1"
+  resolved "https://registry.yarnpkg.com/vscode-typescript-languageservice/-/vscode-typescript-languageservice-0.27.1.tgz#373db91da714bba0983b85daa46f12362afbaa6e"
+  integrity sha512-lIXLyYpcO4+9mzFrgTkRgrWYDLlV+kv+3/vmipEvF4QbiKHWcA0l5AOSJcPR/IUeZz6mu9eoawpOjPsbp9HKqw==
   dependencies:
-    "@volar/shared" "^0.26.6"
+    "@volar/shared" "^0.27.1"
     upath "^2.0.1"
     vscode-languageserver "^8.0.0-next.1"
     vscode-languageserver-textdocument "^1.0.1"
@@ -11479,31 +11370,30 @@ vscode-uri@^3.0.2:
   resolved "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.2.tgz#ecfd1d066cb8ef4c3a208decdbab9a8c23d055d0"
   integrity sha512-jkjy6pjU1fxUvI51P+gCsxg1u2n8LSt0W6KrCNQceaziKzff74GoWmjVG46KieVzybO1sttPQmYfrwSHey7GUA==
 
-vscode-vue-languageservice@^0.26.6:
-  version "0.26.6"
-  resolved "https://registry.yarnpkg.com/vscode-vue-languageservice/-/vscode-vue-languageservice-0.26.6.tgz#b533612bf33385370579b81db9f9e0cac155c3e4"
-  integrity sha512-NLOwk3X4cQSDICUlNtRHUkO9kFpQQROjmoOdWbg55j3aw2Ouew3t6spnKMQfc3LCVCjGMr3+qMMCzpdBfzYxCA==
-  dependencies:
-    "@volar/code-gen" "^0.26.6"
-    "@volar/html2pug" "^0.26.6"
-    "@volar/shared" "^0.26.6"
-    "@volar/source-map" "^0.26.6"
-    "@volar/transforms" "^0.26.6"
-    "@vue/compiler-dom" "^3.2.0-beta.3"
-    "@vue/compiler-sfc" "^3.2.0-beta.3"
-    "@vue/reactivity" "^3.2.0-beta.3"
-    "@vue/shared" "^3.2.0-beta.3"
-    jsonc-parser "^3.0.0"
+vscode-vue-languageservice@^0.27.0:
+  version "0.27.1"
+  resolved "https://registry.yarnpkg.com/vscode-vue-languageservice/-/vscode-vue-languageservice-0.27.1.tgz#1be63445437a12cd75bfcc956b5624eee3dfc51c"
+  integrity sha512-32I6OCEvgxQpRW/Txod2+5xNKpae1BS+EFXjXpxK0TMFT3NYrJYXo0xVaddlV9+IZcVmH5KdoBia7J3CO4H74Q==
+  dependencies:
+    "@volar/code-gen" "^0.27.1"
+    "@volar/html2pug" "^0.27.1"
+    "@volar/shared" "^0.27.1"
+    "@volar/source-map" "^0.27.1"
+    "@volar/transforms" "^0.27.1"
+    "@vscode/emmet-helper" "^2.7.0"
+    "@vue/compiler-dom" "^3.2.2"
+    "@vue/compiler-sfc" "^3.2.2"
+    "@vue/reactivity" "^3.2.2"
+    "@vue/shared" "^3.2.2"
     request-light "^0.5.4"
     upath "^2.0.1"
     vscode-css-languageservice "^5.1.4"
-    vscode-emmet-helper "^2.6.4"
     vscode-html-languageservice "^4.0.7"
     vscode-json-languageservice "^4.1.5"
     vscode-languageserver "^8.0.0-next.1"
     vscode-languageserver-textdocument "^1.0.1"
-    vscode-pug-languageservice "^0.26.6"
-    vscode-typescript-languageservice "^0.26.6"
+    vscode-pug-languageservice "^0.27.1"
+    vscode-typescript-languageservice "^0.27.1"
 
 vue-demi@*:
   version "0.9.1"
@@ -11550,12 +11440,12 @@ vue-router@^4.0.11:
   dependencies:
     "@vue/devtools-api" "^6.0.0-beta.14"
 
-vue-tsc@^0.2.2:
-  version "0.2.2"
-  resolved "https://registry.yarnpkg.com/vue-tsc/-/vue-tsc-0.2.2.tgz#e7fd5e5c789beb31840ad26082cfc8bb6356e733"
-  integrity sha512-91mzfGneWCuF83WTGRI9HA67IBUh5lrhujnFaHKWHQlpQFcBadkmz0BVoGAuJLQILetC5/CrY3is6FGiWFuY4w==
+vue-tsc@^0.2.3:
+  version "0.2.3"
+  resolved "https://registry.yarnpkg.com/vue-tsc/-/vue-tsc-0.2.3.tgz#12bf48e3c9b1e553d31aad0c641722d5d15841d8"
+  integrity sha512-0ahxAnQolmv6EOnv5zxeMi4vCpM4PkhjU70i/EI44OzMWq4OErjLZhEh8EXOLtMx6FBRuuqS5fiBXcuqLpoL7Q==
   dependencies:
-    vscode-vue-languageservice "^0.26.6"
+    vscode-vue-languageservice "^0.27.0"
 
 vue-types@^3.0.0:
   version "3.0.2"