Parcourir la source

feat: 添加基于`ElTour`实现的漫游式引导 (#958)

* feat: 添加基于ElTour实现的引导
wzc520pyfm il y a 1 an
Parent
commit
d83f28dbd3
2 fichiers modifiés avec 73 ajouts et 48 suppressions
  1. 2 1
      src/style/element-plus.scss
  2. 71 47
      src/views/guide/index.vue

+ 2 - 1
src/style/element-plus.scss

@@ -64,7 +64,7 @@
   }
 }
 
-/* 全局覆盖element-plus的el-dialog、el-drawer、el-message-box、el-notification组件右上角关闭图标和el-upload上传文件列表右侧关闭图标的样式,表现更鲜明 */
+/* 全局覆盖element-plus的el-tour、el-dialog、el-drawer、el-message-box、el-notification组件右上角关闭图标和el-upload上传文件列表右侧关闭图标的样式,表现更鲜明 */
 .el-dialog__headerbtn,
 .el-message-box__headerbtn {
   &:hover {
@@ -75,6 +75,7 @@
 }
 
 .el-icon {
+  &.el-tour__close,
   &.el-dialog__close,
   &.el-drawer__close,
   &.el-message-box__close,

+ 71 - 47
src/views/guide/index.vue

@@ -1,63 +1,75 @@
 <script setup lang="ts">
+import { ref } from "vue";
 import intro from "intro.js";
 import "intro.js/minified/introjs.min.css";
 
+type GuideStep = {
+  element: string | HTMLElement;
+  title: string;
+  intro: string;
+  position: "left" | "right" | "top" | "bottom";
+};
+
 defineOptions({
   name: "Guide"
 });
 
+const GUIDE_STEPS = [
+  {
+    element: document.querySelector(".sidebar-logo-container") as
+      | string
+      | HTMLElement,
+    title: "项目名称和Logo",
+    intro: "您可以在这里设置项目名称和Logo",
+    position: "left"
+  },
+  {
+    element: document.querySelector("#header-search") as string | HTMLElement,
+    title: "搜索菜单",
+    intro: "您可以在这里搜索想要查看的菜单",
+    position: "left"
+  },
+  {
+    element: document.querySelector("#header-notice") as string | HTMLElement,
+    title: "消息通知",
+    intro: "您可以在这里查看管理员发送的消息",
+    position: "left"
+  },
+  {
+    element: document.querySelector("#header-translation") as
+      | string
+      | HTMLElement,
+    title: "国际化",
+    intro: "您可以在这里进行语言切换",
+    position: "left"
+  },
+  {
+    element: document.querySelector(".set-icon") as string | HTMLElement,
+    title: "项目配置",
+    intro: "您可以在这里查看项目配置",
+    position: "left"
+  },
+  {
+    element: document.querySelector(".tags-view") as string | HTMLElement,
+    title: "多标签页",
+    intro: "这里是您访问过的页面的历史",
+    position: "bottom"
+  }
+] as Partial<GuideStep>[];
+
+const tourOpen = ref(false);
+
 const onGuide = () => {
   intro()
     .setOptions({
-      steps: [
-        {
-          element: document.querySelector(".sidebar-logo-container") as
-            | string
-            | HTMLElement,
-          title: "项目名称和Logo",
-          intro: "您可以在这里设置项目名称和Logo",
-          position: "left"
-        },
-        {
-          element: document.querySelector("#header-search") as
-            | string
-            | HTMLElement,
-          title: "搜索菜单",
-          intro: "您可以在这里搜索想要查看的菜单",
-          position: "left"
-        },
-        {
-          element: document.querySelector("#header-notice") as
-            | string
-            | HTMLElement,
-          title: "消息通知",
-          intro: "您可以在这里查看管理员发送的消息",
-          position: "left"
-        },
-        {
-          element: document.querySelector("#header-translation") as
-            | string
-            | HTMLElement,
-          title: "国际化",
-          intro: "您可以在这里进行语言切换",
-          position: "left"
-        },
-        {
-          element: document.querySelector(".set-icon") as string | HTMLElement,
-          title: "项目配置",
-          intro: "您可以在这里查看项目配置",
-          position: "left"
-        },
-        {
-          element: document.querySelector(".tags-view") as string | HTMLElement,
-          title: "多标签页",
-          intro: "这里是您访问过的页面的历史",
-          position: "bottom"
-        }
-      ]
+      steps: GUIDE_STEPS
     })
     .start();
 };
+
+const onTour = () => {
+  tourOpen.value = true;
+};
 </script>
 
 <template>
@@ -69,6 +81,18 @@ const onGuide = () => {
         </span>
       </div>
     </template>
-    <el-button @click="onGuide"> 打开引导页 </el-button>
+    <el-button @click="onGuide"> 打开引导页 (intro.js) </el-button>
+    <el-button @click="onTour"> 打开引导页 (el-tour) </el-button>
+
+    <el-tour v-model="tourOpen">
+      <el-tour-step
+        v-for="step in GUIDE_STEPS"
+        :key="step.title"
+        :target="() => step.element"
+        :title="step.title"
+        :description="step.intro"
+        :placement="step.position"
+      />
+    </el-tour>
   </el-card>
 </template>