vue2中如何动态渲染组件

vue2中如何动态渲染组件

    • 动态渲染组件
      • 代码解读
      • 通过函数调用渲染组件
    • 封装一个函数调用的二次确认弹窗
      • 如何让外部知道用户点击了取消还是确定呢?
    • 思考
    • 小结

vue2 的项目中,main.js 文件中有一个挂载 App.vue 组件的方法:

new Vue({name: 'Root',render: h => h(App),
}).$mount('#app')

new Vue 创建了一个 Vue 实例,通过实例方法 $mount 方法将 App 组件挂载到 #app 上,这样就实现了App.vue 的渲染。

App.vue 渲染出来的模板会把 #app 替换掉。

App.vue 导出后是一个普通对象,没有 $mount 方法,而 Vue 实例有 $mount 方法。

问题:我们可以通过这样的方式动态地渲染一个组件吗?

答案是可以的。 通过 Vue.extend + $mount 动态挂载组件。

动态渲染组件

既然可动态渲染一个组件,把这个过程封装成一个函数,可通过函数调用的方式渲染组件。
下面的代码,当用户点击按钮时,会动态渲染一个 el-button 组件。

<script>import {Button} from 'element-ui'import Vue from 'vue'export default {name: 'DemoOne',methods: {showElButton() {const SubVue = Vue.extend(Button)const ButtonInstance = new SubVue({propsData: {type: 'primary'},})ButtonInstance.$slots = {default: 'el-button',}ButtonInstance.$mount(this.$refs.container)},},}
</script>
<template><div><h2>动态挂载组件</h2><button @click="showElButton">显示el-button</button><div><div ref="container"></div></div></div>
</template>

代码解读

Vue.extend 是什么作用?

Vue.extend 接收一个组件对象,用于创建一个 Vue 的子类。 Vue.extend 返回的是一个 Vue 的子类,而不是一个 Vue 的实例。

new SubVue 是什么作用?

new SubVue 创建了一个 Button 组件的实例 ButtonInstance ,方便调用实例方法。

ButtonInstance. m o u n t ( t h i s . mount(this. mount(this.refs.container) 是什么作用?

ButtonInstance 挂载到 this.$refs.container 上,即将 el-button 渲染到页面上。
通过 Vue.extend$mount 方法,实现了动态地渲染组件。
了解了动态渲染组件的原理,我们可以通过函数调用的方式,动态地渲染组件。

通过函数调用渲染组件

上面的例子中 showElButton 方法局限了在组件内部,我们可以将这个方法抽离出来,挂载到 Vue 原型上,就可以在全局调用。

类似这样调用: this.$showElButton(params)

// showElButton.js
import {Button
} from 'element-ui'
import Vue from 'vue'export function showElButton(target, {type = 'primary',label = 'el-button'
} = {}) {const SubVue = Vue.extend(Button)const ButtonInstance = new SubVue({propsData: {type},})ButtonInstance.$slots = {default: label,}ButtonInstance.$mount()target.appendChild(ButtonInstance.$el)
}

代码解读

没有给 $mount 方法传递挂载的目标元素,而是在挂载目标元素中追加了 ButtonInstance.$el ,实现每点击一次渲染一个。

在 main.js 中挂载方法:

Vue.prototype.$showElButton = showElButton

使用 this.$showElButton 方法:

<script>export default {name: 'DemoOne',methods: {showElButton() {this.$showElButton(this.$refs.container)},},}
</script><template><div><h2>动态挂载组件</h2><button @click="showElButton">显示el-button</button><div><div ref="container"></div></div></div>
</template>

效果
动态渲染组件

封装一个函数调用的二次确认弹窗

了解了如何通过函数调用渲染组件,可以封装一个二次确认弹窗, 用户确认后再进行下一步操作。

弹窗组件如下: ConfirmModal.vue

<template><div v-if="show" class="modal"><div ref="myModalContent" class="modal-content"><div>{{ title }}</div><slot name="default"><div>{{ content }}</div></slot><slot name="footer"><div class="footer"><button @click="onCancel">取消</button><button @click="onConfirm">确定</button></div></slot></div></div>
</template><script>export default {name: 'ConfirmModal',props: {title: {type: String,default: '确定操作吗?',},content: {type: String,default: '',},},data() {return {show: false,}},methods: {onCancel() {this.show = false},onConfirm() {this.show = false},},}
</script><style lang="less">.modal {position: fixed;left: 0;top: 0;z-index: 99; // 确保弹窗在顶层width: 100%;height: 100%;background-color: #e4e4e4c7;&-content {position: relative;left: 50%;top: 50%;width: 20vw;height: 100px;z-index: 999; //transform: translate(-50%, -50%);display: flex;flex-direction: column;justify-content: space-between;// align-items: flex-end;background-color: #fff;.footer {display: flex;justify-content: flex-end;}}}
</style>

showConfirm :

import Confirm from './ConfirmModal.vue'
import Vue from 'vue'const ConfirmClass = Vue.extend(Confirm)let confirmInstance = nullconst showConfirm = (content = '插槽内容', title = '弹窗标题', options = {}) => {if (!confirmInstance) {confirmInstance = new ConfirmClass({el: document.createElement('div'),propsData: {content: content,title,},})}// NOTE 设置组件 data 为 true,内部 div 渲染confirmInstance.show = true// console.log(confirmInstance)document.body.appendChild(confirmInstance.$el)return confirmInstance
}export default showConfirm

关键代码解读

// 设置 confirmInstance 的 data 为 true,内部 div 渲染
confirmInstance.show = true
// 将 confirmInstance.$el 挂载到 body 上
document.body.appendChild(confirmInstance.$el)

在 main.js 中挂载方法:

import showConfirm from './showConfirm'
Vue.prototype.$showConfirm = showConfirm

使用 this.$showConfirm 方法:

<template><div><el-button type="danger" @click="onRemoveSomething">删除</el-button></div>
</template><script>export default {name: 'Home',data() {return {}},methods: {onRemoveSomething() {this.$showConfirm('删除后不能恢复', '确定删除吗?')},},}
</script>

效果:
二次确认弹窗

如何让外部知道用户点击了取消还是确定呢?

还有一个关键问题,如何让外部知道用户点击了取消还是确定呢?

方法1:通过回调函数

showConfirm 函数传递一个回调函数,当用户点击确定时,执行回调函数。

改造 ConfirmModal.vue,内部的方法不要写死,而是在 showConfirm 函数中提供。

// ConfirmModal.vue 内部不提供 onCancel 和 onConfirm 方法
methods: {// onCancel() {//   console.log(this.$options)//   this.show = false//   return false// },// onConfirm() {//   return true// },
}
// showConfirm 提供 onCancel 和 onConfirm 方法
const showConfirm = (content = '插槽内容',title = '弹窗标题',options = {}
) => {if (!confirmInstance) {confirmInstance = new ConfirmClass({el: document.createElement('div'),propsData: {content: content,title,},})}// 设置组件 data 为 true,内部 div 渲染confirmInstance.show = true// onConfirm 和 onCancel 方法confirmInstance.onConfirm = () => {options.onConfirm()confirmInstance.show = false}confirmInstance.onCancel = () => {options.onCancel()confirmInstance.show = false}console.log(confirmInstance)document.body.appendChild(confirmInstance.$el)return confirmInstance
}

使用 showConfirm 函数:

this.$showConfirm('删除后不能恢复', '确定删除吗?', {onConfirm: () => {console.log('确定')},onCancel: () => {console.log('取消')},
})

方法2: showConfirm 返回一个 Promise

先看使用方式:

this.$showConfirm('删除后不能恢复', '确定删除吗?').then(isOk => {if (isOk) {console.log('确定')} else {console.log('取消')}
})

showConfirm 函数:

const showConfirm = (content = '插槽内容', title = '弹窗标题', options = {}) => {if (!confirmInstance) {confirmInstance = new ConfirmClass({el: document.createElement('div'),propsData: {content: content,title,},})}// 设置组件 data 为 true,内部 div 渲染confirmInstance.show = true// 返回一个 Promiseconst p = new Promise((resolve, reject) => {confirmInstance.onConfirm = () => {confirmInstance.show = falseresolve(true)}confirmInstance.onCancel = () => {confirmInstance.show = falseresolve(false)}})document.body.appendChild(confirmInstance.$el)return p
}

相比回调函数,Promise 更加直观,使用更加方便。

思考

element-ui 的 this.$message 方法,是如何实现调用后在页面上显示消息的?

小结

  1. 了解 new Vue 的作用;
  2. 结合 Vue.extend 和 $mount 方法,实现动态渲染组件;
  3. 通过函数调用的方式,动态渲染组件;
  4. 封装一个二次确认弹窗,用户确认后再进行下一步操作;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/25540.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

工程师 - 什么是EMI测试

一、EMC EMI EMS定义&#xff1a; EMC&#xff08;ElectromagneticCompatibility&#xff09; 电磁兼容&#xff0c;是指设备或系统在电磁环境中性能不降级的状态。电磁兼容&#xff0c;一方面要求系统内没有严重的干扰源&#xff0c;一方面要求设备或系统自身有较好的抗电磁…

5G发牌五周年丨移远通信:全面发力,加快推进5G技术服务社会发展

2024年6月6日&#xff0c;正值中国5G商用牌照发牌五周年。根据移动通信“十年一代”的规律&#xff0c;5G已走过一半征程。在过去的五年时间里&#xff0c;5G技术从萌芽到成熟&#xff0c;深刻改变了工业、农业、医疗及消费端等各个领域的发展脉络。无论是无人机配送、自动驾驶…

【LeetCode】两数相加(基于单向链表)难度:中等

目录 理清题目 解题思路 题目代码 运行结果 我们来看一下题目描述&#xff1a; 理清题目 首先题目要求链表中的节点的值必须在[0,9]之间也就是说我们要处理的数字必为正整数&#xff0c;因此就不会涉及到太复杂的计算&#xff0c;题目其实就是要求对两个链表中的节点的值分…

详解 Flink 的状态管理

一、Flink 状态介绍 1. 流处理的无状态和有状态 无状态的流处理&#xff1a;根据每一次当前输入的数据直接转换输出结果的过程&#xff0c;在处理中只需要观察每个输入的独立事件。例如&#xff0c; 将一个字符串类型的数据拆分开作为元组输出或将每个输入的数值加 1 后输出。…

台积电代工!Intel新AI PC芯片Lunar Lake发布:AI算力120TOPS!

根据英特尔披露的数据显示&#xff0c;Lunar Lake的GPU性能提升50%、NPU内核的AI算力增加了四倍、SoC耗电量减少40%、GPU AI算力增加3.5倍&#xff0c;整个SoC的算力超过了120TOPS。 6月4日&#xff0c;英特尔CEO帕特基辛格在COMPUTEX 2024上发表主题演讲&#xff0c;正式公布…

如何确保redis缓存中的数据与数据库一致

一、双写模式&#xff1a; 在写入数据库时&#xff0c;也写入缓存。 二&#xff1a;失效模式&#xff1a; 在写入新数据后&#xff0c;删除缓存中数据&#xff0c;下次请求时查询数据库&#xff0c;并把查到的最新数据写入缓存。 不管是双写模式还是失效模式&#xff0c;缓…

Letcode-Top 100二叉树专题

94. 二叉树的中序遍历 方法一&#xff1a;递归法 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val val; }* TreeNode(int val, TreeN…

SpringBoot的学习要点

目录 SpringBoot 创建项目 配置文件 注解 命名规范 SpringBoot整合第三方技术 …… 中文文档&#xff1a;Spring Boot 中文文档 SpringBoot Spring Boot 是基于 Spring 框架的一种快速构建微服务应用的方式它主要提供了自动配置、简化配置、运行时应用监控等功能它…

大水文之------端午练练JS好了

最近有点不太知道要干啥了&#xff0c;昨天看了集cocos的介绍&#xff0c;下载了个DashBoard&#xff0c;看了看里面的内容&#xff0c;确实有点小震惊&#xff0c;还有些免费的源码可以学习&#xff0c;挺好的。 昨天学习ts&#xff0c;感觉自己的js水平好像不太行&#xff0c…

Functional ALV系列 (10) - 将填充FieldCatalog封装成函数

在前面的博文中&#xff0c;已经讲了封装的思路和实现&#xff0c;主要是利用 cl_salv_data_descr>read_structdescr () 方法来实现。在这里&#xff0c;贴出代码方便大家参考。 编写获取内表组件的通用方法 form frm_get_fields using pt_data type any tablechanging…

C++期末复习提纲(血小板)

目录 1.this指针 2.静态成员变量 3.面向对象程序设计第一阶段 4.面向对象程序设计第二阶段 5.面向对象程序设计第三阶段 6.简答题 &#xff08;1&#xff09;拷贝构造函数执行的三种情况&#xff1a; &#xff08;2&#xff09;虚析构函数的作用&#xff1a; &#xff…

Python基础——字符串

一、Python的字符串简介 Python中的字符串是一种计算机程序中常用的数据类型【可将字符串看作是一个由字母、数字、符号组成的序列容器】&#xff0c;字符串可以用来表示文本数据。 通常使用一对英文的单引号&#xff08;&#xff09;或者双引号&#xff08;"&#xff09;…

html接口响应断言

接口响应值除类json格式&#xff0c;还有html格式 断言步骤 第一步&#xff1a;替换空格replace 原本返回的格式和网页内容一致&#xff0c;每行前面有很多空格&#xff0c;需要去除这些空格 第二步&#xff1a;分割split 因为行与行之前有回车符&#xff0c;所以把回车符替…

Spring之SpringMVC源码

SpringMVC源码 一、SpringMVC的基本结构 1.MVC简介 以前的纯Servlet的处理方式&#xff1a; Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String type req.getParameter(Constant.REQUEST_PA…

【Java面试】十六、并发篇:线程基础

文章目录 1、进程和线程的区别2、并行和并发的区别3、创建线程的四种方式3.1 Runnable和Callable创建线程的区别3.2 线程的run和start 4、线程的所有状态与生命周期5、新建T1、T2、T3&#xff0c;如何保证线程的执行顺序6、notify和notifyAll方法有什么区别7、wait方法和sleep方…

QT-轻量级的笔记软件MyNote

MyNote v2.0 一个轻量级的笔记软件&#x1f4d4; Github项目地址: https://github.com/chandlerye/MyNote/tree/main 应用简介 MyNote v2.0 是一款个人笔记管理软件&#xff0c;没有复杂的功能&#xff0c;旨在提供便捷的笔记记录、管理以及云同步功能。基于Qt 6.6.3 个人开…

MATLAB入门知识

目录 原教程链接&#xff1a;数学建模清风老师《MATLAB教程新手入门篇》https://www.bilibili.com/video/BV1dN4y1Q7Kt/ 前言 历史记录 脚本文件&#xff08;.m&#xff09; Matlab帮助系统 注释 ans pi inf无穷大 -inf负无穷大 i j虚数单位 eps浮点相对精度 0/&a…

Edge浏览器视频画中画可拉动进度条插件Separate Window

平时看一些视频的时候&#xff0c;一般需要编辑一些其他的东西&#xff0c;于是开启画中画&#xff0c;但是画中画没有进度条&#xff0c;需要大幅度的倒退前进得回到原视频&#xff0c;很麻烦。这里推荐插件Separate Window&#xff0c;可实现画中画进度条拉动和播放sudu的调节…

Transparent 且 Post-quantum zkSNARKs

1. 引言 前序博客有&#xff1a; SNARK原理示例SNARK性能及安全——Prover篇SNARK性能及安全——Verifier篇 上图摘自STARKs and STARK VM: Proofs of Computational Integrity。 上图选自&#xff1a;Dan Boneh 斯坦福大学 CS251 Fall 2023 Building a SNARK 课件。 SNARK…

工业通讯现场中关于EtherCAT转TCPIP网关的现场应用

在当今工业自动化的浪潮中&#xff0c;EtherCAT技术以其高效、实时的特性成为了众多制造业的首选。然而&#xff0c;随着工业互联网的发展&#xff0c;对于数据的远程访问和云平台集成的需求日益增长&#xff0c;这就需要将EtherCAT协议转化为更为通用的TCP/IP协议。于是开疆智…