惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

V
Visual Studio Blog
爱范儿
爱范儿
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
雷峰网
雷峰网
V
V2EX
博客园_首页
Engineering at Meta
Engineering at Meta
博客园 - 聂微东
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Apple Machine Learning Research
Apple Machine Learning Research
GbyAI
GbyAI
H
Help Net Security
A
About on SuperTechFans
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Blog — PlanetScale
Blog — PlanetScale
W
WeLiveSecurity
云风的 BLOG
云风的 BLOG
D
Docker
Security Archives - TechRepublic
Security Archives - TechRepublic
Help Net Security
Help Net Security
N
News and Events Feed by Topic
Simon Willison's Weblog
Simon Willison's Weblog
G
Google Developers Blog
A
Arctic Wolf
T
The Blog of Author Tim Ferriss
博客园 - 叶小钗
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Google DeepMind News
Google DeepMind News
博客园 - 三生石上(FineUI控件)
aimingoo的专栏
aimingoo的专栏
Hacker News: Ask HN
Hacker News: Ask HN
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
博客园 - 司徒正美
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
P
Privacy International News Feed
T
Troy Hunt's Blog
T
Tenable Blog
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Recorded Future
Recorded Future
F
Fortinet All Blogs
D
DataBreaches.Net
B
Blog
T
Threat Research - Cisco Blogs
MyScale Blog
MyScale Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
The GitHub Blog
The GitHub Blog
Security Latest
Security Latest
M
MIT News - Artificial intelligence

博客园 - 小虫1

AI 视频修复技术落地对比:四款去水印工具的技术路线解析 浏览器端本地视频处理实测:4 种去水印方案的技术原理与效果对比 前端开发者视角:一个视频去水印工具的技术猜想 记一次本地视频去水印踩坑经历——从本地部署到在线工具 前端实现视频去水印的几种技术方案对比 豆包视频去水印工具横向测评:麻雀 AI 工具箱与 3 款海外工具实测对比 视频去水印工具实战横评:少谈“黑科技”,多聊实际能用的 2026 在线视频去水印工具实测:4 种方案对比,本地处理首选麻雀AI工具箱 豆包生成的图片,怎么去水印? 2026年,GEO到底怎么做?-麻雀GEO Topaz Video AI的替代品 -麻雀AI视频修复工具,免费、安全、高效的Topaz替代选择 视频清晰度增强网站-麻雀AI视频修复工具 跟框架无关的前端换皮肤 前端请求跨域,解决方案 ssh2-sftp-client 上传文件至服务器 vue项目下自己封装上传文件功能 beego 注册路由失效404,commentsRouter.go没有生成 前端代码实现整体缩放网页,做到缩放分辨率的效果 前端 docker jenkins mkdocs生成的网站为何很慢 重新搞nginx vue公共布局组件Layout引入 重新认识布局:你真的懂flex吗 重新认识布局:html和body元素 重新认识布局:3d空间中的css盒子 重新认识布局:百分比单位 重新认识布局:标准流,浮动,定位的关系 微信小程序 等宽不等高瀑布流
vue2 函数式调用一个弹框组件
小虫1 · 2022-04-26 · via 博客园 - 小虫1

注册为组件的方式,做个弹框很容易。但是用过ant design vue 等框架,你会发现人家的弹框都是通过函数调用的,类似于这样:

this.$confirm({
            content: 'destroy all',
            onOk() {
              return new Promise((resolve, reject) => {
                setTimeout(Math.random() > 0.5 ? resolve : reject, 1000);
              }).catch(() => console.log('Oops errors!'));
            },
            cancelText: 'Click to destroy all',
            onCancel() {
              self.destroyAll();
            },
});

并且弹出后,在body底部,并不在业务的html中。

这个可以这么做的思路:做一个vue实例,把他挂载到body上。下面直接上代码:

src/components/Modal/index.vue

<template>
  <div class="mask" v-show="visiable" @click="cancel">
    <div class="modal" @click.stop="() => {}">
      <h2>{{ title }}</h2>
      <div class="content" v-html="content"></div>
      <footer>
        <div class="btn" @click="cancel">取消</div>
        <div class="btn" @click="ok">确定</div>
      </footer>
    </div>
  </div>
</template>

<script>
export default {
  props: {
    title: {
      type: String,
      default: "",
    },
    content: {
      type: String,
      default: "",
    },
    onCancel: {
      type: Function,
      default: () => {},
    },
    onOk: {
      type: Function,
      default: () => {},
    },
  },
  data() {
    return {
      visiable: false,
    };
  },
  methods: {
    open() {
      this.visiable = true;
    },
    cancel() {
      this.onCancel();
      this.visiable = false;
    },
    ok() {
      this.onOk();
      this.visiable = false;
    },
  },
};
</script>

<style lang="less" scoped>
.mask {
  position: fixed;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  z-index: 10000;
  background-color: rgba(0, 0, 0, 0.55);
}
.modal {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 600px;
  padding: 0 34px;
  background-color: #fff;
  border-radius: var(--btn-radius);
  h2 {
    height: 80px;
    font-size: 20px;
    font-family: PingFangSC-Medium, PingFang SC;
    font-weight: 500;
    color: #272727;
    line-height: 80px;
    border-bottom: 1px dashed rgba(151, 151, 151, 0.2);
  }
  .content {
    font-size: 16px;
    margin: 36px 0 50px;
  }
  footer {
    display: flex;
    justify-content: space-between;
    margin-bottom: 50px;
    .btn {
      width: 180px;
      height: 44px;
      border-radius: 2px;
      border: 1px solid rgba(102, 102, 102, 0.7);
      text-align: center;
      line-height: 44px;
      cursor: pointer;
      &:last-child {
        background: var(--btn-bg);
        color: #fff;
      }
    }
  }

  /deep/.price-num {
    font-size: 20px;
    font-family: PingFangSC-Medium, PingFang SC;
    font-weight: 500;
    color: var(--text-1);
  }
}
</style>

  src/components/Modal/index.js(核心代码)

import Vue from "vue";
import Modal from "./Index.vue"; // 引入弹窗组件

const ModalComponent = Vue.extend(Modal);
let app;
Modal.open = (options) => {
	if (options === 'cancel') {
		app && app.cancel();
		return;
	}
	app = new ModalComponent(
		{ propsData: options }
	).$mount();
	document.body.appendChild(app.$el);
	Vue.nextTick(() => {
		app.open();
	});
};

export default Modal; // 导出

  main.js

import $modal from '@/components/modal/index.js'
Vue.prototype.$modal = $modal.open;

组件里调用举例:

  this.$modal({
        title: "再租一台",
        content: "租用和目标机器,配置相同的一台机器,可选择GPU数量",
        onOk: () => {
          this.$router.push({
            path: "/store/hire",
            query: {
              gpuType: cObj.Gpu_type,
              node: "全部",
              mirrorImage: cObj.Image,
              mirrorImageLabel: cObj.Image,
              dateNum:
                cObj.Use_mode === 0
                  ? 0
                  : Math.round((cObj.Due_time - cObj.Ctime) / 24 / 3600),
              gpuNum: cObj.Gpu_num,
              os: cObj.ContainerType.includes("kvm") ? "kvm" : "docker",
              performance: cObj.Performance,
            },
          });
        },
      });

优化,vue是个单页面应用SPA。在路由变化时,应该隐藏弹框:

router.beforeEach(async (to, from, next) => {
     Vue.prototype.$modal('cancel');
})