Vue新手指引

Vue3网站用户引导功能【Intro.js】 Intro.js是一个用于创建网站用户引导、功能介绍和教程的 JavaScript 库。它允许开发者通过步骤和提示突出显示网站上的特定元素,以帮助用户更好地了解和使用网站的功能。以下是Intro.js的一些关键特点和用法介绍:更多Intro.js。 阅读详情

WEB

driver.js

npm install driver.js --save

utils / driver.js

export default [
    {
        element: '#some-element1',
        popover: {
          title: '第一项',
          description: '第一项的描述',
          position: 'bottom',
        }
    },
    {
        element: '#some-element2',
        popover: {
          title: '第二项',
          description: '第二项的描述',
          position: 'top',
        }
    },
]

挂载

import Driver from 'driver.js'
import 'driver.js/dist/driver.min.css'
import Vue from 'vue'
Vue.prototype.$driver = new Driver()
import Driver from 'driver.js';
import 'driver.js/dist/driver.min.css'
import Vue from 'vue'
Vue.prototype.$driver = new Driver({  
    allowClose: false, //禁止点击外部关闭
    doneBtnText: '完成', // 完成按钮标题
    closeBtnText: '关闭', // 关闭按钮标题
    stageBackground: '#fff', // 引导对话的背景色
    nextBtnText: '下一步', // 下一步按钮标题
    prevBtnText: '上一步', // 上一步按钮标题
})

.vue

<div id="some-element1">第一个</div>
<div id="some-element2">第二个</div>
import driverStep from "@/utils/driver"
// 在mounted生命周期或方法中执行下述代码
this.$driver.defineSteps(driverStep)
this.$driver.start()
// 方法
start () {
  this.$nextTick(() => {
    this.$driver.defineSteps(driverStep)
    this.$driver.start()
  })
}

Vue3.0 compositionAPI

<!--
 * @Author: zhang gen yuan
 * @Date: 2021-09-17 11:01:54
 * @Descripttion: 
-->
<template>
  <h1 id="div1">1111111111</h1>
  <h1 id="div2">2222222222</h1>
</template>

<script setup>
import Driver from "driver.js";
import driverStep from "/@/utils/driver";
import { onMounted, nextTick } from "vue";
import { useRouter } from 'vue-router'
let router = useRouter()
let $driver = new Driver({
  allowClose: false, //禁止点击外部关闭
  doneBtnText: "完成", // 完成按钮标题
  closeBtnText: "关闭", // 关闭按钮标题
  stageBackground: "#fff", // 引导对话的背景色
  nextBtnText: "下一步", // 下一步按钮标题
  prevBtnText: "上一步", // 上一步按钮标题
  onHighlightStarted: (Element) => {
    // 监听当前高亮DOM
  },
  onHighlighted: (Element) => {
    // 监听当前高亮DOM
  },     
  onDeselected: (Element) => {
    // 监听关闭按钮
  },
  onReset: (Element) => {
    // 监听完成按钮
  },          
  onNext: (Element) => {
    // 监听下一步
  },           
  onPrevious: (Element) => {
    //监听上一步按钮
  },  
});
onMounted(() => {
  $driver.defineSteps(driverStep);
  $driver.start();
});
</script>

<style>
</style>

uniAPP

index.vue

<template>
	<view class="content">
		<!-- <image class="logo" src="/static/logo.png" id="testid1"></image>
		<view class="text-area" id="testid2">
			<text class="title">Hello</text>
		</view>
		<view id="testid3">测试行1</view>
		<view id="testid4"><button>测试按钮1</button></view> -->
		<view id="testid1">111</view>
		<view id="testid2">222</view>
		<view id="testid3">333</view>
		<view id="testid4">444</view>
		<!-- 新手引导 -->
		<guide :show="showGuide" :width="cWidth" :height="cHeight" :left="cLeft" :top="cTop"
			:showMessage='cShowMsg' :currentIndex="currentIndex" :noticeArray="noticeArray" @click="clicktoNext">
		</guide>
	</view>
</template>

<script>
	import guide from '@/components/guide/guide.vue'
	export default {
		data() {
			return {
				showGuide: true, //引导是否显示 
				cShowMsg: '', // 展示的解释语
				cWidth: '',
				cHeight: '',
				cLeft: '',
				cTop: '',
				currentIndex: 0,
				//配置需要显示引导的view以及引导显示的msg
				noticeArray: [{
						"showID": "testid1", // 对应的id
						"showMessage": "测试文本1", // 对应的解释文本
						"type": "left" // 解释框的气泡类型
					},
					{
						"showID": "testid2",
						"showMessage": "测试文本2",
						"type": "right"
					},
					{
						"showID": "testid3",
						"showMessage": "测试多行文本测试多行文本测试多行文本测试多行文本测试多行文本测试多行文本测试多行文本测试多行文本测试多行文本测试多行文本",
						"type": "top"
					},
					{
						"showID": "testid4",
						"showMessage": "测试文本4",
						"type": "bottom"
					}
				]
			}
		},
		components: {
			guide
		},
		onLoad() {
			let _this = this;
			this.$nextTick(function() {
				if (_this.currentIndex >= _this.noticeArray.length) {
					_this.showGuide = false;
					return;
				}
				_this.showGuide = true;
				_this.cShowMsg = _this.noticeArray[_this.currentIndex].showMessage;
				var idS = '#' + _this.noticeArray[_this.currentIndex].showID;
				console.log(idS)
				//根据布局信息显示引导框位置
				const query = uni.createSelectorQuery().in(_this);
				query.select(idS).boundingClientRect(data => {
					console.log("得到布局位置信息" + JSON.stringify(data));
					_this.cWidth = data.width;
					_this.cHeight = data.height;
					_this.cLeft = data.left;
					_this.cTop = data.top;
				}).exec();
			});
		},
		methods: {
			clicktoNext() {
				if (this.currentIndex >= this.noticeArray.length) {
					this.showGuide = false;
					return;
				}
				this.noticeArray[this.currentIndex].zindex = 0;
				this.cShowMsg = '';
				this.currentIndex++;
				if (this.currentIndex >= this.noticeArray.length) {
					this.showGuide = false;
					return;
				}
				this.cShowMsg = this.noticeArray[this.currentIndex].showMessage;
				var idS = '#' + this.noticeArray[this.currentIndex].showID;
				console.log(idS)
				const query = uni.createSelectorQuery().in(this);
				query.select(idS).boundingClientRect(data => {
					this.cWidth = data.width;
					this.cHeight = data.height;
					this.cLeft = data.left;
					this.cTop = data.top;
				}).exec();

			},
		}
	}
</script>

guide.vue

<!-- guide.vue -->
<template>
	<view v-show="show" class="main" @touchmove.stop>
		<view class="rect-shadow" :style="{'width':width+'px','height':height+'px','left':left+'px',top:top+'px','border-radius': noticeArray[currentIndex].radius?noticeArray[currentIndex].radius+'rpx':'' }"></view>
		<template v-if="noticeArray[currentIndex].type == 'left' ">
			<view  class="show-message_left" :style="{'top': top +'px', 'right': winWidth-right+width+20+'px' }">
				<view style="padding: 12rpx 18rpx;">{{showMessage}}</view>
			</view>			
		</template>
		<template v-if="noticeArray[currentIndex].type == 'top' ">
			<view :class="left<(winWidth/2)?'show-message_top_left':'show-message_top_right'" :style="{'top': (top-height-topMsgHeght) +'px', 'left': left<(winWidth/2)?left+'px':'' , 'right': left>(winWidth/2)?(winWidth-right)+'px':''  }">
				<view style="padding: 12rpx 18rpx;">{{showMessage}}</view>
			</view>			
		</template>
		<template v-if="noticeArray[currentIndex].type == 'right' ">
			<view  class="show-message_right" :style="{'top': top +'px', 'left': (left+width+20) +'px' }">
				<view style="padding: 12rpx 18rpx;">{{showMessage}}</view>
			</view>			
		</template>
		<template v-if="noticeArray[currentIndex].type == 'bottom' ">
			<view :class="left<(winWidth/2)?'show-message_bottom_left':'show-message_bottom_right'" :style="{'top': (top+height+15) +'px', 'left': left<(winWidth/2)?left+'px':'' , 'right': left>(winWidth/2)?(winWidth-right) +'px':'' }">
				<view style="padding: 12rpx 18rpx;">{{showMessage}}</view>
			</view>			
		</template>
		<view class="cover-wrap" >
			<view class="guide-next" @tap="click" :style="{color: currentIndex==noticeArray.length-1? '#EA3E4F':'#000000'}">{{nextText}}</view>
		</view>
	</view>
</template>

<script>
	export default {
		name: "guide",
		props: {
			show: {
				type: Boolean,
				default: false
			},
			left: {
				type: [Number, String],
				default: ''
			},
			right: {
				type: [Number, String],
				default: ''
			},
			top: {
				type: [Number, String],
				default: ''
			},
			width: {
				type: [Number, String],
				default: ''
			},
			height: {
				type: [Number, String],
				default: ''
			},
			showMessage: {
				type: String,
				default: ''
			},
			currentIndex: {
				type: Number,
				default: 0
			},
			noticeArray: {
				type: Array,
				default: []
			}
		},
		data() {
			return {
				topMsgHeght: 0,
				winWidth: 0,
				nextText: '下一步'
			}
		},
		watch: {
			show(n) {},
			currentIndex(value) {
				if (value != this.noticeArray.length&&this.noticeArray[value].type == 'top') {
					const className = this.left<(this.winWidth/2) ? '.show-message_top_left' : '.show-message_top_right'
					const query = uni.createSelectorQuery().in(this);
					query.select(className).boundingClientRect(data => {
						this.topMsgHeght = data.height - 29
					}).exec();
				}
				if (value == this.noticeArray.length-1) {
					this.nextText = '知道了,关闭说明'
				}
			}
		},
		methods: {
			click() {
				this.$emit('click');
			}
		},
		created() {
			setTimeout(() => {
				uni.getSystemInfo({
					success: (res) => {
						this.winWidth = res.windowWidth;
					}
				});	
			}, 60)
		}
	}
</script>

<style lang="scss" scoped>
	.main {
		position: fixed;
		top: 0;
		left: 0;
		right: 0;
		bottom: 0;
		z-index: 99999;
	}
	.rect-shadow {
		position: absolute;
		border-radius: 12rpx;
		box-shadow: 0 0 0 3000px rgba(0, 0, 0, 0.5);
		pointer-events: none;
	}
	.show-message_left,
	.show-message_top_left,
	.show-message_top_right,
	.show-message_right,
	.show-message_bottom_left,
	.show-message_bottom_right {
		position: absolute;
		border-radius: 12rpx;
		background-color: rgba(0,0,0,.5);
		text-align: center;
		pointer-events: none;
		color: #fff;
		font-size: 24rpx;
		max-width: 50%;
		text-align: left;
	}
	.show-message_left::after {
		content: '';
		border-left: 12rpx solid rgba(0,0,0,.5);
		border-top: 12rpx solid transparent;
		border-right: 12rpx solid transparent;
		border-bottom: 12rpx solid transparent;
		width: 0;
		height: 0;
		position: absolute;
		top: 25%;
		right: -22rpx;
	}
	
	.show-message_top_left::after,.show-message_top_right::after {
		content: '';
		border-left: 12rpx solid transparent;
		border-top: 12rpx solid rgba(0,0,0,.5);
		border-right: 12rpx solid transparent;
		border-bottom: 12rpx solid transparent;
		width: 0;
		height: 0;
		position: absolute;
		top: 100%;
	}
	.show-message_top_left::after {
		left: 20%;
	}
	.show-message_top_right::after {
		right: 20%;
	}
	
	.show-message_right::after {
		content: '';
		border-left: 12rpx solid transparent;
		border-top: 12rpx solid transparent;
		border-right: 12rpx solid rgba(0,0,0,.5);
		border-bottom: 12rpx solid transparent;
		width: 0;
		height: 0;
		position: absolute;
		top: 25%;
		left: -24rpx;
	}
	.show-message_bottom_left::after, .show-message_bottom_right::after {
		content: '';
		border-left: 12rpx solid transparent;
		border-top: 12rpx solid transparent;
		border-right: 12rpx solid transparent;
		border-bottom: 12rpx solid rgba(0,0,0,.5);
		width: 0;
		height: 0;
		position: absolute;
		top: -22rpx;
	}
	
	.show-message_bottom_left::after {
		left: 20%;
	} 
	.show-message_bottom_right::after {
		right: 20%;
	}
	
	.cover-wrap {
		width: 100vw;
		height: 100vh;
		top: 0;
		left: 0;
		position: absolute;
		
		.guide-next {
			background-color: #FFFFFF;
			font-size: 28rpx;
			border-radius: 38rpx;
			position: absolute;
			bottom: 372rpx;
			left: 50%;
			transform: translate(-50%,0);
			padding: 16rpx 32rpx;
		}
	}
</style>
vue_guide:这是Vue.js指南页面的地方 vue_guide 介绍 该存储库是基于Vue.js的前端项目。 并且它通过github页面提供了Vue.js指南。 立即下载

相关推荐

一款简洁的新手引导控件

简洁的新手引导控件,带遮盖层 高亮层,代码不到200行,直接运行demo中的jsp即可观看效果,直接自定义位置,自定义回调函数等。

Vue + intro.js 实现页面新手引导流程功能

Vue + intro.js 实现页面新手引导流程功能

小破孩的博客 1万+

农业AI避坑指南:用YOLO11做叶片病害检测时遇到的5个典型问题

本文分享了使用YOLO11模型进行农业叶片病害检测时常见的五个典型问题及解决方案。针对田间多变光照、病害样本不均衡、标注歧义、背景干扰和边缘部署等挑战,提供了包括场景自适应数据增强、解耦训练、软标签与鲁棒损失函数、困难负样本构建以及模型轻量化部署在内的实战经验,旨在帮助开发者提升农业AI项目的落地效果。

ujm56789012的博客 205

原生js实现新手引导功能(vue项目)

基于原生js实现“新手引导”功能

weixin_43695002的博客 3216

生信入门第七课:使用FastQC软件进行测序原始fastq数据质控

从实验到数据:RNA定量、文库片段长度、fastqc质控和fastp去接头

微生信 486

超详细YOLOv8实例分割全程概述:环境、训练、验证与预测详解

这篇博客提供了一个全面的指南,介绍了如何使用 Ultralytics YOLOv8-seg 系列模型进行对象检测和分割任务。内容从环境搭建、模型选择、训练、验证到预测的完整流程都有详细说明。为想要使用 YOLOv8-seg 系列模型的开发者提供了一站式的解决方案。它不仅涵盖了从环境配置到模型部署的详细步骤,还解释了如何解读和使用模型输出,使得用户能够根据自己的需求选择合适的模型,并能够有效地训练和评估它们。

CDBmax的博客 6万+

vue+intro.js开发新手指引功能

定义intro全局样式文件:intro.css/* 跳过按钮 */important;important;important;/* 弹窗div *//* 弹窗提示按钮 */*//* 弹窗提示中的文字样式 */important;important;/* 框出来的区域的框框颜色 */important;/* 下一步按钮,鼠标focus时候 */

qq_43679365的博客 1057

一条龙开发指南:MCP AI Agent 理论+项目实战开发你的MCP Server

MCP(Model Connection Protocol)是Anthropic于2024年推出的AI模型连接协议,旨在为AI模型提供开放、通用的标准化接口,类似于“USB-C”接口,使AI模型能够无缝连接各种数据源和工具。MCP通过标准化协议解决了AI系统集成中的碎片化问题,提升了开发效率和系统可靠性。开发者可以通过简单的配置,快速接入不同的MCP Server,实现AI模型的多样化应用。MCP支持多种协议,如Stdio、SSE等,并通过JSON-RPC格式进行数据传输。文章还以腾讯云代码助手为例,展示了

杨不易呀 3043

《在 React/Vue 项目中引入 Supademo 实现交互式新手指引》

Supademo是一款基于Web的互动式新手引导工具,帮助用户快速熟悉应用功能。它提供动态指引、自定义内容和简单集成,支持创建符合品牌形象的引导流程。使用方法:注册账号后编辑内容,通过API集成到项目,实现点击触发指引。适用于需要用户教育的产品,能显著提升用户体验。官网:https://app.supademo.com/

qq_70172010的博客 621

Perplexity AI 高效使用培训手册

Perplexity AI 是一款革命性的 AI 搜索引擎,提供免费版和专业版两种选择。免费版支持基础搜索、每日3次Pro搜索、3个文件上传和初步深度研究功能;Pro版则解锁无限次Pro搜索、无限制文件上传、AI图像生成等高级功能,适合专业用户深度研究。该工具能整合网络信息、分析本地文档、生成创意内容,并提供知识库管理功能,显著提升信息检索和内容创作效率。用户可根据需求选择合适版本,免费版已能满足日常使用,而Pro版则更适合专业场景。

conquer_qgw的博客 1205

保姆级避坑指南:用Keil和J-Flash搞定凌思微LE5010蓝牙芯片的首次程序下载

本文提供了一份详细的保姆级避坑指南,帮助开发者使用Keil和J-Flash工具完成凌思微LE5010蓝牙芯片的首次程序下载。文章重点解决了算法文件混淆、协议栈漏烧和仿真器连接异常等常见问题,并详细介绍了开发环境配置、协议栈烧录和下载接口的物理层奥秘,助力开发者高效完成蓝牙开发任务。

weixin_28739079的博客 466

vue 新手指引_Vue的新手引导组件,微信小程序适用

基于Vue开发了一个种水果偷水果的微信小游戏,游戏系统相对一般应用来说稍显复杂。所以需要一个完善的新手引导来帮助用户快速上手。微信搜索:神奇小花盆我期望的新手引导需要实现以下几个特性:1、基于用户流程,按顺序的指引。 2、指引时仅允许点击指引目标。而一个好用的新手引导组件在完成功能特性的基础上还需要提供简单易用的配置和丰富可自由定义的风格。基于这些理念,我开发了一个ezguider组件,可以非常简...

weixin_39527078的博客 1361

YOLOv11改进 | 主干/Backbone篇 | 利用目标检测轻量化网络MobileNetV2替换Backbone(yolov11系列全系轻量化)

本文给大家带来的改进机制是,其是专为移动和嵌入式视觉应用设计的轻量化网络结构。其在MobilNetV1的基础上采用反转残差结构和线性瓶颈层。这种结构通过轻量级的深度卷积和线性卷积过滤特征,同时去除狭窄层中的非线性,以维持表征能力。MobileNetV2在性能上和精度上都要比V1版本强很多,其在多种应用(如对象检测、细粒度分类、面部属性识别和大规模地理定位)中都展现了一定的有效性。YOLOv11改进系列专栏——本专栏持续复习各种顶会内容——科研必备目录一、本文介绍二、MobileNetV2的框架原理。

Snu77的博客 2841

vue + element 新手指引

直接上代码 template-(Guide.vue) <template> <div> <!-- 新手指引 --> <div id="mask"></div> <div id="searchTip"> <div class="stepA"> <el-button type="primary" size="sm

summer_cloudy的博客 722

【图像超分】论文精读:Residual Dense Network for Image Super-Resolution(RDN)

一个非常深的卷积神经网络 (CNN) 最近在图像分类 (SR) 方面取得了巨大成功,并提供了分层特征。然而,大多数基于深度 CNN 的 SR 模型没有充分利用原始低分辨率 (LR) 图像中的层次特征,从而实现相对较低的性能。在本文中,我们提出了一种新的残差密集网络(RDN)来解决图像SR中的这个问题。我们充分利用所有卷积层的分层特征。具体来说,我们提出了残差密集块(RDB)通过密集连接的卷积层提取丰富的局部特征。RDB 进一步允许将前一个 RDB 的状态与当前 RDB 的所有层直接连接,从而产生连续的内存

主要更新底层视觉(去噪、超分等)相关的科研内容,形式为【论文精读】+【论文复现】 7256

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

vue2实现新手指引功能

vue2组件使用shepherd实现新手指引

qq_62861688的博客 1528

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

在vue中熟练使用新手指引

方式一 driver.js 安装 npm install driver.js --save 代码 1:定义每一步的提示信息 创建 utils - driver.js export default [ { element: '#some-element1', popover: { title: '第一项', desc...

monthover的博客 1634

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

vue项目引入并使用新手指引功能

vue新手指引

weixin_68067009的博客 1421

vue + Intro.js 新手指引

vue 中 新手指引introjs插件的使用

我叫陈小皮。 880

Vue使用intro.js新手指引

引入 npm下载:npm install intro.js --save 在main.js中引入: import IntroJs from 'intro.js' import 'intro.js/introjs.css'; Vue.use(IntroJs); 参数详解 页面 在需要引导说明的标签上加入如下属性,插件就自动将当前标签区域高亮选中: <div data-step="1" da...

菜鸟启程 1万+

introJs去实现新手指引

示例代码:

qq_38295468的博客 470

新手指引(vue-tour)

在开发一个用户系统项目时,为了指引用户操作,常常需要做一下第一次进入的用户引导,这里用到了vue-tour,方便实用。

记录工作 903

前端新手指引插件,vue-tour

vue-tour官网 vue-tour API

qq_40047198的博客 6095

如何使用 vue + intro 实现后台管理系统的引导_vue使用intro

为了让用户更好的适应新版,或更方便使用公司内部系统,可以加入新手指引功能。如果你也想在自己的网页加入用户指引,那就试试在vue中使用 Intro.js 吧,它能够很轻松的制作出新手指引的效果。库,用于创建一步一步的产品引导,支持使用键盘的前后方向键导航,使用 Enter 和 ESC 键推出引导,您可以通过几个简单的步骤安装。那激动人心的时刻到了,我们如何vue中使用 Intro.js 在呢?感觉如何,是不是很简单,接下来我们学习如何在VUE项目中使用。找到需要加新手引导的组件,导入。首先我们引入下述文件。

2401_89285764的博客 636

如何使用 vue + intro 实现后台管理系统的新手引导_vue intro 新手指引

最后我们加入JS代码就可以通过浏览器运行查看效果啦(* ̄︶ ̄)感觉如何,是不是很简单,接下来我们学习如何在VUE项目中使用。最后就是给需要加引导的盒模型加属性就大功告成了。接着在HTML文件中加入基本结构。找到需要加新手引导的组件,导入。

2401_85124764的博客 624

vue-tour快速入门:VUE项目中如何使用vue-tour新手引导指引插件?怎样使用?包含具体实例

Vue Tour | A lightweight and customizable tour plugin for use with Vue.jshttps://pulsardev.github.io/vue-tour/ Vue Tour是轻巧、简单且可自定义的新手指引插件,可与Vue.js一起使用。它提供了一种快速简便的方法来指导用户使用您的应用程序。Npm Yarn 使用 在应用程序中的任何模板中(通常在App.vue中),放置一个组件,并传递给它一系列步骤。每个步骤的目标属性都可以将应

南北极之间 6742
上一篇: Elementui树状结构表格 树局部刷新
下一篇: 轮播一页显示多少条数据
一天28小时
博客等级 码龄7年 23粉丝 135原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值