Vue弹窗用也可以直接调用Js方法了
问题描述
在前端开发中,弹窗开发是一个不可避免的场景。然而,按照正常的逻辑,通过在template模板中先引用组件,然后通过v-if
指令控制显隐,进而达到弹窗的效果。然而,这种方法却有一个严重的缺陷,即有较强的代码入侵。如果当前组件存在多个不同的弹框,那么会定义相等数量的显隐变量,给代码维护增加了心智负担。
细心的人会发现,在使用element-ui
等前端框架中,我们可以直接调用方法,弹框就会出现,接下来执行不同的逻辑。那么我们的弹框能否可以借鉴一下呢?
解决思路
我们知道,vue
的component的本质是js
对象,我们可以通过javascript
创建组将实例,并渲染到页面上。下面我就基于vue2
和vue3
两种版本实现一个地图选点的弹窗式组件。
vue2的封装方式
封装地图组件
<template><div class="main"><div id="container" class="map"></div><div class="tools"><div class="ok-button" @click="submit">确定</div><div class="ok-button" @click="exits">取消</div></div><div class="info"><span>经度:{{ resultPoint[0] }};维度:{{ resultPoint[1] }}</span></div></div>
</template><script>
import "ol/ol.css";
import { Map, View, control } from "ol";
import TileLayer from "ol/layer/Tile";
import XYZ from "ol/source/XYZ";
import TileGrid from "ol/tilegrid/TileGrid";
import { defaults as defaultControls } from "ol/control";
import Position from "@/assets/position.png";
import Style from "ol/style/Style";
import Icon from "ol/style/Icon";
import VectorSource from "ol/source/Vector";
import VectorLayer from "ol/layer/Vector";
import Feature from "ol/Feature";
import Point from "ol/geom/Point";
import { tranMktTo84, trans84ToMkt } from "@/utils/protransform";export default {props: {lon: {type: Number,default: 119.407428,},lat: {type: Number,default: 33.904198,},},data() {return {resultPoint:[this.lon,this.lat],vectorFeature: null,};},mounted() {let initMkt = trans84ToMkt(this.resultPoint)let map = new Map({target: "container",layers: [],controls: defaultControls({ attribution: false, zoom: false }), // 禁用默认的控件view: new View({center: initMkt, zoom: 16,projection: "EPSG:3857",}),});const iconStyle = new Style({image: new Icon({anchor: [0.55, 1.1],src: Position,}),});let vectorFeature = new VectorSource({ features: [] });let vector = new VectorLayer({source: vectorFeature,style: iconStyle,id: "point",});this.loadGdLayer(map)let that = this;map.on("click", function (event) {// 获取点击位置的坐标,并推入 points 数组let coord = event.coordinate;that.resultPoint = tranMktTo84(coord)that.renderPoint(coord,vectorFeature)});map.addLayer(vector);this.renderPoint(initMkt,vectorFeature)this.map = map;},methods: {loadGdLayer(map){//影像map.addLayer(this.createGdLayer("6", true));//影像路网注记`map.addLayer(this.createGdLayer("8", true));},//创建高德地图图层createGdLayer(layer,visible){return new TileLayer({title: "高德地图",source: new XYZ({url: `https://webst0{1-4}.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scale=1&style=${layer}`,wrapX: false}),projection: "EPSG:3857",visible});},submit() {this.$emit("click", this.resultPoint[0], this.resultPoint[1]);},exits() {this.$emit("close");},createPointFeature(point) {return new Feature({geometry: new Point(point),name: "position",});},renderPoint(point,vectorFeature){vectorFeature.clear();vectorFeature.addFeature(this.createPointFeature(point));}},
};
</script><style lang="less" scoped>
.main {position: fixed;width: 100vw;height: 100vh;left: 0;bottom: 0;background-color: #ffffff;
}
#container {width: 100%;height: 100%;
}
.ok-button {text-align: center;line-height: 0.36rem;height: 0.36rem;width: 0.7rem;background: #4b74ff;border-radius: 15%;font-size: 0.2rem;font-family: PingFangSC-Regular, PingFang SC;font-weight: 400;color: #ffffff;&:hover {cursor: pointer;}
}
.info {position: absolute;left: 0.1rem;bottom: 0.2rem;background-color: rgba(150, 150, 150, 0.1);font-size: 0.2rem;
}
.tools {position: absolute;right: 0.1rem;top: 0.1rem;display: flex;justify-content: space-evenly;width: 1.5rem;
}
</style>
这个组件有两个地方需要注意以下:
- 定义了属性,便于被调用着传递。这里主要传递显示坐标,如果不传递,则显示默认坐标。
- 对于
submit
和close
方法,通过this.$emit
调用父类的方法,这里的方法名分别为click
、close
。记主这两个方法名。
封装组件方法
这也是封装的核心
import GetPosition from "@/components/GetPosition.vue";
import { getPoint } from "@/utils/calDistance";
import Vue from "vue";
function createDiv(uuid) {const div = document.createElement("div");div.style.position = "absolute";div.style.zIndex = "1000";div.style.backgroundColor = "rbg(255,255,255)"div.id = uuid;document.body.appendChild(div);const childDiv = document.createElement("div");div.appendChild(childDiv);return childDiv;
}export const selectPoint= (lon,lat,onClick)=>{let uuid = Math.random().toString(36).substring(2);const div = createDiv(uuid);const app = new Vue({render: (h) =>h(GetPosition, {props: { lon: lon, lat: lat },on: {click(lon, lat) {app.$destroy();let div = document.getElementById(uuid);div.remove();onClick(lon, lat);},close() {app.$destroy();let div = document.getElementById(uuid);div.remove();},},}),}).$mount(div);
}
createDiv
创建一个渲染的组件,这个组件要作为body的子组件,至于样式要根据设计情况而定。此组件要设置id,这里使用随机ID,便于document.getElementById(uuid)
查询。selectPoint
是其他组件调用的核心方法。此方面有传入参数和一个回调函数onClick
。- 通过
createDiv
方法创建vue过载的节点。 - 创建vue实例,并定义
render
函数。 - 回调父组件的emit方法要定义到
on
中。 - 在点击确认或者取消按钮,弹窗消失的时候,需要将vue实例销毁
app.$destroy()
,并将div移除。
- 通过
调用方式
clickMap(item) {let lon = this.longitude || 117.633757let lat = this.latitude || 29.558668selectPointInfo(lon,lat,(lon,lat)=>{this.longitude = lonthis.latitude = latitem.model = `${lon},${lat}`})
}
vue3的封装方式
vue3
与vue2
的不同之处在于创建vue
实例上。所以这里只展示调用方法的实例:
export function selectPointInfo(pointInfo:PointInfo,onClick:(item:PointInfo)=>void){const div = createDiv()const app = createApp(SelectPointVue,{pointInfo,onClick(item:PointInfo){app.unmount();div.remove()onClick(item)},onClose(){app.unmount();div.remove()}})app.mount(div)
}
这里需要注意的地方如下:
- props直接传递一个对象即可。
emit
的方法名前要追加on,方法名首字母要大写。例如,在vue组件中有代码this.$emit("click", lon,lat);
,那么此处方法应该定义为onClick
。
vue2和vue3的这两段代码出于不同的项目,所以vue3的核心代码不能直接使用上面的组件。核心逻辑已经列处,需要按需调整。
相关文章:
Vue弹窗用也可以直接调用Js方法了
问题描述 在前端开发中,弹窗开发是一个不可避免的场景。然而,按照正常的逻辑,通过在template模板中先引用组件,然后通过v-if指令控制显隐,进而达到弹窗的效果。然而,这种方法却有一个严重的缺陷࿰…...
【c语言测试】
1. C语言中,逻辑“真”等价于( ) 题目分析: “逻辑真”在C语言中通常指的是非零数。 A. 大于零的数B. 大于零的整数C. 非零的数 (正确答案)D. 非零的整数 正确答案:C 2. 若定义了数组 int a[3][4];,则对…...

一种将树莓派打造为游戏机的方法——Lakka
什么是Lakka? Lakka是一款Linux发行版,轻量级的,可将小型计算机转变为一台复古游戏机。 图1-Lakka官网,见参考链接[1] Lakka是RetroArch和libretro生态系统下的官方操作系统,前者RetroArch是模拟器、游戏引擎和媒体播…...
如何在 MySQL 中创建一个完整的数据库备份?
在MySQL数据库中创建一个完整的数据库备份通常不是通过编程语言直接实现的,而是借助MySQL提供的命令行工具mysqldump来完成。 作为Java开发者,我们可以编写脚本来调用这些工具,从而实现自动化备份。 下面我们将详细介绍如何使用Java来调度m…...
京准电钟HR-901GB双GPS北斗卫星时钟服务器
京准电钟HR-901GB双GPS北斗卫星时钟服务器 京准电钟HR-901GB双GPS北斗卫星时钟服务器 作为国家电力系统最重要的设备之一,卫星时间同步装置随着电力行业的发展不断有了新的要求,从单纯的具备时间数据输出能力,发展到装置状态信息上送、对用时设备的对时质量进行监测,确保站点内…...
uniapp使用websocket
后端java websoket中的 onOpen 中。依赖注入为null 引用:https://blog.csdn.net/qq_63431773/article/details/132389555 https://blog.csdn.net/weixin_43961117/article/details/123989515 https://cloud.tencent.com/developer/article/2107954 https://blog.c…...

基于Pycharm和Django模型技术的数据迁移
1.配置数据库 在trip_server/settings.py中修改配置: 其格式可访问官网:Settings | Django documentation | Django 1.1 配置数据库 文件地址:trip_server/settings.py 配置前需要创建(NaviCat)个人数据库 "…...

乐尚代驾-----Day10(订单三)
hi UU 们!!!我又来跟辛辣!感谢你们的观看,话不多说!~ 司机到达代驾终点,代驾结束了。结束代驾之后, – 获取额外费用(高速费、停车费等) – 计算订单实际里程…...

105. 聚光源SpotLight
入门部分给大家介绍过平行光DirectionalLight、点光源PointLight、环境光AmbientLight,下面给大家介绍一个新的光源对象,也就是聚光源SpotLight。 创建聚光源SpotLight 聚光源可以认为是一个沿着特定方会逐渐发散的光源,照射范围在三维空间中构成一个圆…...
系统接口权限拦截器,获取用户信息存储
UserInfo 类 这是一个表示用户信息的 Java 类,使用了 Lombok 注解来简化代码编写。 import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString;import java.io.Serializable; import java.util.List;Data ToString EqualsAndHashCode public…...
Chromium HTML5 新的 Input 类型color 对应c++
一、Input 类型: color color 类型用在input字段主要用于选取颜色,如下所示: <!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>菜鸟教程(runoob.com)</title> </head> <body&…...
问:SQL中的通用函数及用法?
SQL函数是在SQL语句中使用的预定义的计算工具,可以对一列数据进行操作并返回一个单一的结果。这些函数大致可以分为两类:Aggregate函数和Scalar函数。Aggregate函数对一组值执行计算,并返回单个值,如求和、平均值、最大值和最小值…...

.NET Core WebApi第6讲:WebApi的前端怎么派人去拿数据?(区别MVC)
一、前端界面小基础 head:引入CSS, 引入JS是写在head里面。 body:眼睛肉眼能看到的用户展示的界面是写在body里面。 二、前端怎么派人去拿数据? 1、MVC:前后端不分离,MVC相比WebApi只是多了一个views的文件夹 &am…...
Chromium HTML5 新的 Input 类型date 对应c++
一、Input 类型: date date 类型允许你从一个日期选择器选择一个日期。 <!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>test</title> </head> <body><form action"demo-form.php"…...
ZooKeeper的应用场景:深入探讨分布式系统中的多样化应用
Apache ZooKeeper 是一个开源的分布式协调服务,专为确保分布式系统中的高可用性和一致性而设计。在现代分布式应用程序中,协调、同步和管理是实现高效和可靠服务的关键部分,而 ZooKeeper 通过提供这些基础功能而成为许多分布式系统不可或缺的…...

【Vue3】第四篇
Vue3学习第四篇 01. 插槽Slots02. 插槽Slots(续集)03. 插槽Slots(再续集)04. 组件生命周期05. 生命周期应用06. 动态组件07. 组件保持存活08. 异步组件09. 依赖注入10. Vue应用 01. 插槽Slots 模板内容:html结构&#…...

Chromium HTML5 新的 Input 类型tel对应c++
一、Input 类型: tel <!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>test</title> </head> <body><form action"demo-form.php">电话号码: <input type"tel" name…...

JVM—类加载器、双亲委派机制
目录 什么是类加载器 类加载器的分类 Bootstrap启动类加载器 通过启动类加载器加载用户jar包 Extension扩展类加载器和Application应用程序类加载器 通过扩展类加载器加载用户jar包 双亲委派机制 打破双亲委派机制 自定义类加载器 线程上下文类加载器 Osgi框架的类加…...
笔试题 求空格分割的英文句子中,最大单词长度。
求空格分割的英文句子中,最大单词长度。例如:“this is a word”,最大单词长度为4。要求:不能用 split 函数对字符串进行切分,算法复杂度为o(n) public class MaxWordLength { public static int maxWordLength(String sentence) { if (se…...

【笔记】大模型长度外推技术 NTK-Aware Scaled RoPE
NTK-Aware Scaled RoPE 正弦编码(Sinusoidal)旋转位置编码RoPE编码步骤:旋转位置编码的优势 NTK-Aware Scaled RoPE直接外推线性内插进制转换高频外推、低频内插的理解位置编码 总结参考: 长度外推技术是自然语言处理(NLP)领域中&…...

铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...

简易版抽奖活动的设计技术方案
1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...

大型活动交通拥堵治理的视觉算法应用
大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动(如演唱会、马拉松赛事、高考中考等)期间,城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例,暖城商圈曾因观众集中离场导致周边…...
【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)
要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况,可以通过以下几种方式模拟或触发: 1. 增加CPU负载 运行大量计算密集型任务,例如: 使用多线程循环执行复杂计算(如数学运算、加密解密等)。运行图…...

SpringTask-03.入门案例
一.入门案例 启动类: package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...

Redis数据倾斜问题解决
Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中,部分节点存储的数据量或访问量远高于其他节点,导致这些节点负载过高,影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...

如何在最短时间内提升打ctf(web)的水平?
刚刚刷完2遍 bugku 的 web 题,前来答题。 每个人对刷题理解是不同,有的人是看了writeup就等于刷了,有的人是收藏了writeup就等于刷了,有的人是跟着writeup做了一遍就等于刷了,还有的人是独立思考做了一遍就等于刷了。…...
Mobile ALOHA全身模仿学习
一、题目 Mobile ALOHA:通过低成本全身远程操作学习双手移动操作 传统模仿学习(Imitation Learning)缺点:聚焦与桌面操作,缺乏通用任务所需的移动性和灵活性 本论文优点:(1)在ALOHA…...

深度学习习题2
1.如果增加神经网络的宽度,精确度会增加到一个特定阈值后,便开始降低。造成这一现象的可能原因是什么? A、即使增加卷积核的数量,只有少部分的核会被用作预测 B、当卷积核数量增加时,神经网络的预测能力会降低 C、当卷…...
【前端异常】JavaScript错误处理:分析 Uncaught (in promise) error
在前端开发中,JavaScript 异常是不可避免的。随着现代前端应用越来越多地使用异步操作(如 Promise、async/await 等),开发者常常会遇到 Uncaught (in promise) error 错误。这个错误是由于未正确处理 Promise 的拒绝(r…...