feat(hooks): Add useIntro hook

feat: Add guide demo
master
陈凯龙 4 years ago
parent cb558f8af9
commit 0832194e61

@ -33,6 +33,7 @@
"echarts": "^5.2.2",
"echarts-wordcloud": "^2.0.0",
"element-plus": "1.3.0-beta.7",
"intro.js": "^4.3.0",
"lodash-es": "^4.17.21",
"mockjs": "^1.1.0",
"nprogress": "^0.2.0",
@ -50,6 +51,7 @@
"@iconify/json": "^1.1.459",
"@intlify/vite-plugin-vue-i18n": "^3.2.1",
"@purge-icons/generated": "^0.7.0",
"@types/intro.js": "^3.0.2",
"@types/lodash-es": "^4.17.5",
"@types/node": "^17.0.10",
"@types/nprogress": "^0.2.0",

@ -7,6 +7,7 @@ specifiers:
'@iconify/json': ^1.1.459
'@intlify/vite-plugin-vue-i18n': ^3.2.1
'@purge-icons/generated': ^0.7.0
'@types/intro.js': ^3.0.2
'@types/lodash-es': ^4.17.5
'@types/node': ^17.0.10
'@types/nprogress': ^0.2.0
@ -30,6 +31,7 @@ specifiers:
eslint-plugin-prettier: ^4.0.0
eslint-plugin-vue: ^8.3.0
husky: ^7.0.4
intro.js: ^4.3.0
less: ^4.1.2
lint-staged: ^12.2.2
lodash-es: ^4.17.21
@ -75,6 +77,7 @@ dependencies:
echarts: registry.npmmirror.com/echarts/5.2.2
echarts-wordcloud: registry.npmmirror.com/echarts-wordcloud/2.0.0_echarts@5.2.2
element-plus: registry.npmmirror.com/element-plus/1.3.0-beta.7_vue@3.2.26
intro.js: registry.npmmirror.com/intro.js/4.3.0
lodash-es: registry.nlark.com/lodash-es/4.17.21
mockjs: registry.npmmirror.com/mockjs/1.1.0
nprogress: registry.npmmirror.com/nprogress/0.2.0
@ -92,6 +95,7 @@ devDependencies:
'@iconify/json': registry.npmmirror.com/@iconify/json/1.1.459
'@intlify/vite-plugin-vue-i18n': registry.npmmirror.com/@intlify/vite-plugin-vue-i18n/3.2.1_vite@2.7.13+vue-i18n@9.1.9
'@purge-icons/generated': registry.nlark.com/@purge-icons/generated/0.7.0
'@types/intro.js': registry.npmmirror.com/@types/intro.js/3.0.2
'@types/lodash-es': registry.npmmirror.com/@types/lodash-es/4.17.5
'@types/node': registry.npmmirror.com/@types/node/17.0.10
'@types/nprogress': registry.npmmirror.com/@types/nprogress/0.2.0
@ -3910,25 +3914,6 @@ packages:
version: 1.4.0
dev: true
registry.nlark.com/needle/2.9.1:
resolution:
{
integrity: sha1-ItHf++NJDCuD4wH3cJtnNs2PJoQ=,
registry: https://registry.npm.taobao.org/,
tarball: https://registry.nlark.com/needle/download/needle-2.9.1.tgz
}
name: needle
version: 2.9.1
engines: { node: '>= 4.4.x' }
hasBin: true
requiresBuild: true
dependencies:
debug: registry.npmmirror.com/debug/3.2.7
iconv-lite: registry.nlark.com/iconv-lite/0.4.24
sax: registry.nlark.com/sax/1.2.4
dev: true
optional: true
registry.nlark.com/no-case/3.0.4:
resolution:
{
@ -7288,8 +7273,8 @@ packages:
vue-i18n:
optional: true
dependencies:
'@intlify/message-compiler': registry.npmmirror.com/@intlify/message-compiler/9.2.0-beta.28
'@intlify/shared': registry.npmmirror.com/@intlify/shared/9.2.0-beta.28
'@intlify/message-compiler': registry.npmmirror.com/@intlify/message-compiler/9.2.0-beta.29
'@intlify/shared': registry.npmmirror.com/@intlify/shared/9.2.0-beta.29
jsonc-eslint-parser: registry.npmmirror.com/jsonc-eslint-parser/1.4.1
source-map: registry.nlark.com/source-map/0.6.1
vue-i18n: registry.npmmirror.com/vue-i18n/9.1.9_vue@3.2.26
@ -7345,18 +7330,18 @@ packages:
source-map: registry.nlark.com/source-map/0.6.1
dev: false
registry.npmmirror.com/@intlify/message-compiler/9.2.0-beta.28:
registry.npmmirror.com/@intlify/message-compiler/9.2.0-beta.29:
resolution:
{
integrity: sha512-NBH9fZyitN2cijGt8bmU1W7ZPdhKbgW01L1RxJKFJW0cRaCmknJq63Aif1Q6xcxKt9ZhPbvIKHgPGzg1nWMfeA==,
integrity: sha512-FvMDwe57VvupujvNYUY90J8wv26wKu6j7I93dLwBOo/PTg7nQqFrmYQAF23UfDAdXO4FTdgHfFyb5ecYrN+n3g==,
registry: https://registry.npm.taobao.org/,
tarball: https://registry.npmmirror.com/@intlify/message-compiler/download/@intlify/message-compiler-9.2.0-beta.28.tgz
tarball: https://registry.npmmirror.com/@intlify/message-compiler/download/@intlify/message-compiler-9.2.0-beta.29.tgz
}
name: '@intlify/message-compiler'
version: 9.2.0-beta.28
version: 9.2.0-beta.29
engines: { node: '>= 12' }
dependencies:
'@intlify/shared': registry.npmmirror.com/@intlify/shared/9.2.0-beta.28
'@intlify/shared': registry.npmmirror.com/@intlify/shared/9.2.0-beta.29
source-map: registry.nlark.com/source-map/0.6.1
dev: true
@ -7400,15 +7385,15 @@ packages:
engines: { node: '>= 10' }
dev: false
registry.npmmirror.com/@intlify/shared/9.2.0-beta.28:
registry.npmmirror.com/@intlify/shared/9.2.0-beta.29:
resolution:
{
integrity: sha512-JBMcoj1D4kSAma7Vb0+d8z6lPLIn7hIdZJPxbU8bgeMMniwKLoIS/jGlEfrZihsB5+otckPeQp203z8skwVS0w==,
integrity: sha512-blMW14WBr3fiCEk/XO4IbSxM8WMAhQOzEgWzP1aqbkeXbIMiHeyFI0ZexwyTKsvDZz0wEWlhupQi+9udrJsozA==,
registry: https://registry.npm.taobao.org/,
tarball: https://registry.npmmirror.com/@intlify/shared/download/@intlify/shared-9.2.0-beta.28.tgz
tarball: https://registry.npmmirror.com/@intlify/shared/download/@intlify/shared-9.2.0-beta.29.tgz
}
name: '@intlify/shared'
version: 9.2.0-beta.28
version: 9.2.0-beta.29
engines: { node: '>= 12' }
dev: true
@ -7434,7 +7419,7 @@ packages:
optional: true
dependencies:
'@intlify/bundle-utils': registry.npmmirror.com/@intlify/bundle-utils/2.2.0_vue-i18n@9.1.9
'@intlify/shared': registry.npmmirror.com/@intlify/shared/9.2.0-beta.28
'@intlify/shared': registry.npmmirror.com/@intlify/shared/9.2.0-beta.29
'@rollup/pluginutils': registry.npmmirror.com/@rollup/pluginutils/4.1.2
debug: registry.npmmirror.com/debug/4.3.3
fast-glob: registry.nlark.com/fast-glob/3.2.7
@ -7572,6 +7557,17 @@ packages:
version: 0.0.39
dev: true
registry.npmmirror.com/@types/intro.js/3.0.2:
resolution:
{
integrity: sha1-y/m2nwVbd1gsws6+I26aQFsw770=,
registry: https://registry.npm.taobao.org/,
tarball: https://registry.npmmirror.com/@types/intro.js/download/@types/intro.js-3.0.2.tgz
}
name: '@types/intro.js'
version: 3.0.2
dev: true
registry.npmmirror.com/@types/json-schema/7.0.9:
resolution:
{
@ -10629,6 +10625,17 @@ packages:
through: registry.nlark.com/through/2.3.8
dev: true
registry.npmmirror.com/intro.js/4.3.0:
resolution:
{
integrity: sha512-F4LXM42QIXcO3/2myGBBFdbbUVUK0lBhK7pAxPLd082u+3HfvigFR+Rptqy05q3OzjG/O0vMFDedrnHdSPi2rQ==,
registry: https://registry.npm.taobao.org/,
tarball: https://registry.npmmirror.com/intro.js/download/intro.js-4.3.0.tgz
}
name: intro.js
version: 4.3.0
dev: false
registry.npmmirror.com/is-buffer/1.1.6:
resolution:
{
@ -10840,7 +10847,7 @@ packages:
image-size: registry.npmmirror.com/image-size/0.5.5
make-dir: registry.nlark.com/make-dir/2.1.0
mime: registry.npmmirror.com/mime/1.6.0
needle: registry.nlark.com/needle/2.9.1
needle: registry.npmmirror.com/needle/2.9.1
source-map: registry.nlark.com/source-map/0.6.1
dev: true
@ -11191,6 +11198,25 @@ packages:
engines: { node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1 }
hasBin: true
registry.npmmirror.com/needle/2.9.1:
resolution:
{
integrity: sha512-6R9fqJ5Zcmf+uYaFgdIHmLwNldn5HbK8L5ybn7Uz+ylX/rnOsSp1AHcvQSrCaFN+qNM1wpymHqD7mVasEOlHGQ==,
registry: https://registry.npm.taobao.org/,
tarball: https://registry.npmmirror.com/needle/download/needle-2.9.1.tgz
}
name: needle
version: 2.9.1
engines: { node: '>= 4.4.x' }
hasBin: true
requiresBuild: true
dependencies:
debug: registry.npmmirror.com/debug/3.2.7
iconv-lite: registry.nlark.com/iconv-lite/0.4.24
sax: registry.nlark.com/sax/1.2.4
dev: true
optional: true
registry.npmmirror.com/node-fetch/2.6.1:
resolution:
{

@ -0,0 +1,3 @@
import ContentWrap from './src/ContentWrap.vue'
export { ContentWrap }

@ -0,0 +1,35 @@
<script setup lang="ts">
import { ElCard, ElTooltip } from 'element-plus'
import { propTypes } from '@/utils/propTypes'
import { useDesign } from '@/hooks/web/useDesign'
const { getPrefixCls } = useDesign()
const prefixCls = getPrefixCls('content-wrap')
defineProps({
title: propTypes.string.def(''),
message: propTypes.string.def('')
})
</script>
<template>
<ElCard :class="prefixCls" shadow="never">
<template v-if="title" #header>
<div class="flex items-center">
{{ title }}
<ElTooltip v-if="message" effect="dark" placement="right">
<template #content>
<div class="max-w-200px">{{ message }}</div>
</template>
<Icon class="ml-5px" icon="bi:question-circle-fill" :size="14" />
</ElTooltip>
</div>
</template>
<div>
<slot></slot>
</div>
</ElCard>
</template>
<style lang="less" scoped></style>

@ -70,6 +70,7 @@ export default defineComponent({
return () => (
<div
id={prefixCls}
class={[
`${prefixCls} ${prefixCls}__${unref(menuMode)}`,
'h-[100%] overflow-hidden z-100 flex-col bg-[var(--left-menu-bg-color)]',

@ -12,7 +12,7 @@ import { cloneDeep } from 'lodash-es'
import { filterMenusPath, initTabMap, tabPathMap } from './helper'
import { useDesign } from '@/hooks/web/useDesign'
const { getPrefixCls } = useDesign()
const { getPrefixCls, variables } = useDesign()
const prefixCls = getPrefixCls('tab-menu')
@ -106,6 +106,7 @@ export default defineComponent({
return () => (
<div
id={`${variables.namespace}-menu`}
class={[
prefixCls,
'relative bg-[var(--left-menu-bg-color)] top-1px',

@ -148,7 +148,7 @@ watch(
</script>
<template>
<div :class="prefixCls" class="h-[var(--tags-view-height)] flex w-full relative">
<div :id="prefixCls" :class="prefixCls" class="h-[var(--tags-view-height)] flex w-full relative">
<span
:class="`${prefixCls}__tool`"
class="w-[var(--tags-view-height)] h-[var(--tags-view-height)] text-center leading-[var(--tags-view-height)] cursor-pointer"

@ -0,0 +1,41 @@
import introJs from 'intro.js'
import { IntroJs, Step, Options } from 'intro.js'
import 'intro.js/introjs.css'
import { useI18n } from '@/hooks/web/useI18n'
import { useDesign } from '@/hooks/web/useDesign'
export const useIntro = (setps?: Step[], options?: Options) => {
const { t } = useI18n()
const { variables } = useDesign()
const defaultSetps: Step[] = setps || [
{
element: `#${variables.namespace}-menu`,
title: t('common.menu'),
intro: t('common.menuDes'),
position: 'right'
},
{
element: `#${variables.namespace}-tags-view`,
title: t('common.tagsView'),
intro: t('common.tagsViewDes'),
position: 'bottom'
}
]
const defaultOptions: Options = options || {
prevLabel: t('common.prevLabel'),
nextLabel: t('common.nextLabel'),
skipLabel: t('common.skipLabel'),
doneLabel: t('common.doneLabel')
}
const introRef: IntroJs = introJs()
introRef.addSteps(defaultSetps).setOptions(defaultOptions)
return {
introRef
}
}

@ -11,7 +11,7 @@ import { useDesign } from '@/hooks/web/useDesign'
const { getPrefixCls } = useDesign()
const prefixCls = getPrefixCls('layout-content')
const prefixCls = getPrefixCls('layout')
const appStore = useAppStore()
@ -54,7 +54,7 @@ export const useRenderLayout = () => {
</div>
<div
class={[
prefixCls,
`${prefixCls}-content`,
'absolute top-0 h-[100%]',
{
'w-[calc(100%-var(--left-menu-min-width))] left-[var(--left-menu-min-width)]':
@ -69,7 +69,7 @@ export const useRenderLayout = () => {
<ElScrollbar
v-loading={pageLoading.value}
class={[
`${prefixCls}-scrollbar`,
`${prefixCls}-content-scrollbar`,
{
'!h-[calc(100%-var(--top-tool-height)-var(--tags-view-height))] mt-[calc(var(--top-tool-height)+var(--tags-view-height))]':
fixedHeader.value
@ -115,7 +115,7 @@ export const useRenderLayout = () => {
<Menu class="!h-full"></Menu>
<div
class={[
prefixCls,
`${prefixCls}-content`,
'h-[100%]',
{
'w-[calc(100%-var(--left-menu-min-width))] left-[var(--left-menu-min-width)]':
@ -129,7 +129,7 @@ export const useRenderLayout = () => {
<ElScrollbar
v-loading={pageLoading.value}
class={[
`${prefixCls}-scrollbar`,
`${prefixCls}-content-scrollbar`,
{
'!h-[calc(100%-var(--tags-view-height))] mt-[calc(var(--tags-view-height))]':
fixedHeader.value && tagsView.value
@ -168,11 +168,11 @@ export const useRenderLayout = () => {
<Menu class="flex-1 px-10px h-[var(--top-tool-height)]"></Menu>
<ToolHeader></ToolHeader>
</div>
<div class={[prefixCls, 'v-content h-full w-full']}>
<div class={[`${prefixCls}-content`, 'h-full w-full']}>
<ElScrollbar
v-loading={pageLoading.value}
class={[
`${prefixCls}-scrollbar`,
`${prefixCls}-content-scrollbar`,
{
'mt-[var(--tags-view-height)]': fixedHeader.value
}
@ -207,10 +207,9 @@ export const useRenderLayout = () => {
</div>
<div class="absolute top-[var(--logo-height)] left-0 w-full h-[calc(100%-var(--logo-height))] flex">
<TabMenu></TabMenu>
{/* <Menu class="!h-full"></Menu> */}
<div
class={[
prefixCls,
`${prefixCls}-content`,
'h-[100%]',
{
'w-[calc(100%-var(--tab-menu-min-width))] left-[var(--tab-menu-min-width)]':
@ -224,7 +223,7 @@ export const useRenderLayout = () => {
<ElScrollbar
v-loading={pageLoading.value}
class={[
`${prefixCls}-scrollbar`,
`${prefixCls}-content-scrollbar`,
{
'!h-[calc(100%-var(--tags-view-height))] mt-[calc(var(--tags-view-height))]':
fixedHeader.value && tagsView.value

@ -17,7 +17,17 @@ export default {
closeTheLeftTab: 'Close left',
closeTheRightTab: 'Close right',
closeOther: 'Close other',
closeAll: 'Close all'
closeAll: 'Close all',
prevLabel: 'Prev',
nextLabel: 'Next',
skipLabel: 'Jump',
doneLabel: 'End',
menu: 'Menu',
menuDes: 'Menu bar rendered in routed structure',
collapse: 'Collapse',
collapseDes: 'Expand and zoom the menu bar',
tagsView: 'Tags view',
tagsViewDes: 'Used to record routing history'
},
setting: {
projectSetting: 'Project setting',
@ -72,7 +82,8 @@ export default {
menu2: 'Menu2',
dashboard: 'Dashboard',
analysis: 'Analysis',
workplace: 'Workplace'
workplace: 'Workplace',
guide: 'Guide'
},
analysis: {
newUser: 'New user',
@ -173,5 +184,11 @@ export default {
timeSelect: 'Time Select',
inputPassword: 'input Password',
passwordStrength: 'Password Strength'
},
guideDemo: {
guide: 'Guide',
start: 'Start',
message:
'The guide page is very useful for some people who enter the project for the first time. You can briefly introduce the functions of the project. The boot page is based on intro js'
}
}

@ -17,7 +17,17 @@ export default {
closeTheLeftTab: '关闭左侧标签页',
closeTheRightTab: '关闭右侧标签页',
closeOther: '关闭其他标签页',
closeAll: '关闭全部标签页'
closeAll: '关闭全部标签页',
prevLabel: '上一步',
nextLabel: '下一步',
skipLabel: '跳过',
doneLabel: '结束',
menu: '菜单',
menuDes: '以路由的结构渲染的菜单栏',
collapse: '展开缩收',
collapseDes: '展开和缩放菜单栏',
tagsView: '标签页',
tagsViewDes: '用于记录路由历史记录'
},
setting: {
projectSetting: '项目配置',
@ -72,7 +82,8 @@ export default {
menu2: '菜单2',
dashboard: '首页',
analysis: '分析页',
workplace: '工作台'
workplace: '工作台',
guide: '引导'
},
analysis: {
newUser: '新增用户',
@ -173,5 +184,11 @@ export default {
timeSelect: '时间选择',
inputPassword: '密码输入框',
passwordStrength: '密码强度'
},
guideDemo: {
guide: '引导页',
start: '开始',
message:
'引导页对于一些第一次进入项目的人很有用,你可以简单介绍下项目的功能。引导页基于 intro.js'
}
}

@ -68,6 +68,23 @@ export const asyncRouterMap: AppRouteRecordRaw[] = [
}
]
},
{
path: '/guide',
component: Layout,
name: 'Guide',
meta: {},
children: [
{
path: 'index',
component: () => import('@/views/Guide/Guide.vue'),
name: 'GuideDemo',
meta: {
title: t('router.guide'),
icon: 'cib:telegram-plane'
}
}
]
},
{
path: '/level',
component: Layout,

@ -0,0 +1,20 @@
<script setup lang="ts">
import { ContentWrap } from '@/components/ContentWrap'
import { useI18n } from '@/hooks/web/useI18n'
import { useIntro } from '@/hooks/web/useIntro'
import { ElButton } from 'element-plus'
const { t } = useI18n()
const { introRef } = useIntro()
const guideStart = () => {
introRef.start()
}
</script>
<template>
<ContentWrap :title="t('guideDemo.guide')" :message="t('guideDemo.message')">
<ElButton type="primary" @click="guideStart">{{ t('guideDemo.start') }}</ElButton>
</ContentWrap>
</template>

@ -23,7 +23,12 @@
"paths": {
"@/*": ["src/*"]
},
"types": ["@intlify/vite-plugin-vue-i18n/client", "vite/client", "element-plus/global"],
"types": [
"@intlify/vite-plugin-vue-i18n/client",
"vite/client",
"element-plus/global",
"@types/intro.js"
],
"typeRoots": ["./node_modules/@types/", "./types"]
},
"include": ["src/**/*", "types/**/*.d.ts", "mock/**/*.ts"],

@ -132,7 +132,8 @@ export default ({ command, mode }: ConfigEnv): UserConfig => {
'axios',
'qs',
'echarts',
'echarts-wordcloud'
'echarts-wordcloud',
'intro.js'
]
}
}

Loading…
Cancel
Save