手机版

手写Vue弹出Modal实现代码

时间:2021-08-20 来源:互联网 编辑:宝哥软件园 浏览:

作为最近最火的前端框架,Vue简单的入口方式和强大的API是它的优势。同时,由于其API的多样性和丰富性,他的许多开发方法不同于所有基于组件的React。如果你对Vue的API没有一个全面的了解(有些甚至没有在文档中提到),那么在开发和设计一个组件的时候,你可能会绕一个大圈。所以我强烈建议大家在学习Vue的时候,首先要对Vue的所有核心API有一个了解。这篇文章从实践出发,我会顺便总结一些知识点。文章很长,看一遍就可以先收藏。如果你是vue的新手,相信这篇文章一定会对你以后的提高有所帮助

言归正传,我相信几乎任何项目都会有一个必不可少的功能,那就是用户操作反馈,或者提醒,就像这样(一个简单的演示)

事实上,这些类似的小功能在vue的中大型项目中会更丰富、更严谨。在以Vue为核心框架的前端项目中,由于Vue本身是一个组件化的、虚拟的Dom框架,显示一个通知组件当然非常简单。但是由于通知组件的使用特点,直接在模板中编写组件,通过v-show或者道具来控制通知组件的显示,显然是非常不方便的,这意味着你的代码结构会发生变化。当弹性层的种类很多的时候,我们把它们装在APP或者一个组件下面,显然是不合理的。此外,如果要在动作或其他非组件场景中使用通知,则无法实现纯组件模式的使用。那么,有没有办法利用Vue的组件化特性,方便地显示一个通知组件,能否用一种方法来控制炸弹层组件的显示和隐藏?

目标一

实现一个简单的反馈通知,可以通过方法在组件中直接调用该通知。比如Vue。$ confirm({ 0.obj})

首先,让我们实现通知组件。我相信大多数人都能写出像样的组件,不用担心,直接编码就行了

模板div : class=' type ' class=' eqc-notifier ' I : class=' icon class ' class=' icon fl '/span { { msg } }/span!-span class=' close fr eqf-no ' @ click=' close '/span-/div/templates export default { name : ' Notification },prop s : { type : String,default: '' },msg: { type: String,default: '' },computed 3: { icon class(){ switch(this . type){ case ' success ' : return ' eqf 'eqc-notifier { position:固定;top: 68px左侧:50%;height: 36px填充-右: 10px;线高: 36px;box-shadow: 0 0 16px 0 rgba(0,0,0,0.16);border-radius : 3px;背景# fffz-index : 100;//最高级别为transform : translateX(-50%);animation:淡入0.3s。图标{ margin: 10pxfont-size : 16px;} .关闭{ margin: 8pxfont-size : 20px;color: # 666transition:全部0.3scursor:指针; hover { color : # ff 296 a;} } .成功{ color : # 1 BC 7 b 1;} .失败{ color: # ff296a} .信息{ color: # 1593ff} .warn { color: # f89300} .关闭{ animation:淡出0.3s} }/style我们这里需要注意。我们已经定义了一个close方法,但是它的内容是空的。虽然用在模板中,但似乎没有意义。我将在以后扩展组件时讨论为什么我们应该这样做。

创建此组件后,我们可以使用通知类型=' XXX '消息=' XXX'/

实现通过方法调用通知组件

事实上,我们需要在通过方法实现调用之前扩展这个组件,因为这些属性不足以让我们使用。使用方法调用时,我们需要考虑几个问题:

显示反馈的定位组件的出现和自动消失控制连续多次调用通知方法。在这个前提下,我们需要扩展组件,但是这些扩展的属性不能直接放在原始组件中,因为这些可能会影响组件在模板中的使用。我们做什么呢此时,我们需要使用一个在Vue中非常容易使用的API,extend,来继承原始组件的属性并对其进行扩展。

看看代码

从“”导入通知程序。/Notifier . Vue ' function install(Vue){ Vue . Notifier=Vue . prototype . Notifier={ success,fail,info,warn }}function open(type,msg){ let UiNotifier=Vue . extend(Notifier)let VM=new UiNotifier({ propstata : { type,msg },methods 3360 { close : function(){ let dialog=this。$ El dialog . addeventlistener(' animation end ',()={ document . body . remove child(dialog)this。$ destroy()})dialog . class name=` $ { this . type } eqc-notifier close ` dialog=null } } })。$ mount()document . body . appendchild(VM。$ El)}函数成功(msg) { open('success ',msg)}函数失败(msg) { open('fail ',msg)}函数信息(msg) {open ('info ',Msg)}函数警告(msg) {open ('warn,msg)} vue。使用(install)导出默认安装您可以看到这里已经实现了close方法,那么为什么要将这些方法的定义添加到原始组件中呢?因为模板需要绑定,不能扩展,只能覆盖。如果要覆盖再重新实现,扩展的意义不大。其实这只是一个消息弹出组件,可以在模板中实现,如何注入插件由大家决定。

同时,使用extend时要注意:

方法和属性的定义是,直接覆盖的生命周期方法类似于mixin,将会合并,即同时调用原始组件和继承组件。首先,通过let ui notifier=Vue调用原始组件。扩展(通知程序),我们得到一个类似Vue的子类。然后我们可以通过新的UiNotifier创建vue的实例({ 0.选项})。同时,通过这种方式,

创建实例后。$mount()手动将组件挂载在DOM上,这样我们就可以不依赖Vue组件树输出DOM片段,达到自由显示通知的效果。

展开:

让我们谈谈$mount。我们可能有许多像这样的项目的主要文件

Newvue ({router,store,el:' # app ',render:h=h (app)})在el和$mount之间的使用效果没有区别,后者是在指定的dom元素中挂载实例化的vue。如果在实例化一个vue时指定了一个el,那么vue将在与这个el对应的dom中呈现。相反,如果没有指定el,vue实例将处于“卸载”状态,此时可以通过$mount手动装载它。值得注意的是,如果$mount不提供参数,那么模板会呈现为文档外的元素,必须使用原生DOM API将其插入到文档中,所以你应该理解我上面写的内容!

这是一个$mount的源代码片段。事实上,$mount的方法支持传入两个参数。第一个是el,它指示挂载的元素,可以是字符串或DOM对象。如果是字符串,将调用查询方法将其转换为浏览器环境中的DOM对象。第二个参数与服务器端渲染有关,在浏览器环境中不需要传递第二个参数。

好了,我们现在可以在组件中使用3360了

这样称呼方便吗.通知人[状态](msg)?先进的

我们刚刚通过Vue中的方法实现了用户反馈的提醒,增加了:的另一个难度

我们某视频剪辑软件项目中应该也遇到过这种情况,弹出一个对话框或是选择框?不但要求用方法弹出,并且能接收到对话框交互所返回的结果。

这里就不详细的分析了直接上代码说(之前的代码,用提出来写的组件,懒得改了,直接拿来用.),先创建一个对话框组件-确认

脚本让__this=null导出默认值{ name: ' Confirm,data(){ return { config : { msg : ' ',ifBtn: ' ',top: null } },created() { __this=this },方法: { create box(h){ let config={ } config。attrs={ id : ' _ _ Confirm ' }让孩子=[]个孩子。推(这个。createcontainer(h))子级。推(这个。createBg(this).$cancel } }),创建容器(h){ let config={ } config。class={ ' box-container ' : true } if(_ this。配置。top){ config。style={ ' top ' : _ _ this。配置。top ' px ',' transform': 'translate(-50%,0)' } }让children=[]children。推(这个。createContentBox(h))子级。推(这个。创建close(h))if(_ this。配置。ifbtn){然后$cancel } }),createBtnBox(h) { return h('div ',{ class : { ' BTN-box ' : true } },[ __this.createBtn(h,' btn-cancel middle mr10 ','取消,_ _这个$cancel),__this.createBtn(h,' Btn-主中间mr10 ','确定,_ _这个$ confirm),createBtn(h,样式,内容,回调){ return h('button ',{ class: styles, { click: callBack } },content) },render(h){ return this。createbox(h)}/脚本样式范围# _ _确认{ position : fixed top : 0;左: 0;z指数: 10;宽度: 100%;高度: 100%;} # _ _确认bg {位置:固定;top : 0;左: 0;z-index : 0;宽度: 100%;高度: 100%;} # _ _确认箱式容器{位置:绝对值;宽度: 500像素;padd : 20pxpadding-top : 30px;边界半径: 3px背景# fffz-index : 1;盒影: 2px 2px 10px rgba(0,0,0,0.4);前:名50%;左侧: 50%;transform: translate(-50%,-50%);} # _ _确认。内容盒{ font-size : 14px线高: 20px边距-底部: 10px} # _ _确认BTN-box {页边距-top : 20px;文本对齐:右侧;} # _ _确认关闭-BTN {绝对位置:top : 15pxright : 20pxfont-size : 16px;color: # 666666} # _ _确认近距离-BTN :悬停{ color : # 1593 ff} # _ _确认bg {位置:固定;}/样式然后创建confirm.js

使用严格的"导入确认自"。/确认。vue ' const确认构造函数=vue。扩展(确认)常量确认视图样式=配置={常量确认实例=新的确认构造函数({ data(){ return { config } })确认实例。虚拟机=确认实例.$ mount()确认实例。DOM=确认实例。虚拟机。$ El文档。尸体。appendchild(确认实例。DOM)} const close=()={ let DOM=document。queryselector(' body .modelServe-container)DOM。移除()Vue。原型。$ receive=null } const close confirm=()={ let DOM=document。getelementbyid(_ _ confirm ')DOM。移除()Vue。原型。$ confirm=null }函数安装(Vue。原型。modelServe={ confirm :(obj)={ return new Promise(resolve={ Vue。原型。$ confirm=(数据)={ resolv(data)close confirm()} confirm style(obj)} } } Vue。原型思路很简单,在我们创建的时候同时返回一个答应我,同时将分解通行证暴露给某视频剪辑软件的一个全局方法也就是将控制权暴露给外部,这样我们就可以向这样,我上面的confiram.vue是直接把取消绑定成了$取消,把确定绑定成了$确认,所以点击确定会进入满的,也就是。然后中,当然你也可以传参数

这个。模特服务。确认({ msg : '返回后数据不会被保存,确认?',ifBtn: true}).然后(_={ this.goBack()}).catch()写的有点多,其实还可以扩展出好多技巧,比如模态框中传一个完整的组件,并展示出来,简单地写一下,其实只需改动一点

从""导入模型/型号。vue ' const Model构造函数=vue。extend(Model)const modelViewStyle=(obj)={ let component=obj。component const modelViewInstance=new Model构造函数({ data(){ return { disable click : obj。停止点击/是否禁止点击遮罩层关闭} }})让app=文档。getelementbyid(' container ')modelViewInstance。虚拟机=模型视图实例.$ mount()modelviewinstance。DOM=modelviewinstance。虚拟机。$ elapp。appendchild(modelviewinstance。DOM)新Vue({ El : ' # _ _ model _ _ ',mixin :[component],data(){ return { serveobj : obj。obj } } })}.vue。原型。model serve={ open :(obj)=}返回新的promise(resolve={ modelViewStyle(obj,resolve)vue。原型。$ receive=(数据)={ resolve(数据)close()} })} }调用:

send callback(){ this。模特服务。open({组件:添加回调,stopClick: true })。然后(数据=if(数据===1){ this。addinit()} else { this。goback()})这里我们用了mixins,最后最后再简单地介绍一下混合,扩展,扩展的区别

**- Vue.extend使用基础某视频剪辑软件构造器,创建一个"子类"。参数是一个包含组件选项的对象。

混入类选项接受一个混入对象的数组。这些混入实例对象可以像正常的实例对象一样包含选项,他们将在Vue.extend()里最终选择使用相同的选项合并逻辑合并。举例:如果你的混入包含一个钩子而创建组件本身也有一个,两个函数将被调用混合钩子按照传入顺序依次调用,并在调用组件自身的钩子之前被调用。

注意(数据混入组件数据优先钩子函数将混合为一个数组,混入对象的钩子将在组件自身钩子之前调用,值为对象的选项,例如方法、组件和指令,将被混合为同一个对象。两个对象键名冲突时,取组件对象的键值对。)

延伸允许声明扩展另一个组件(可以是一个简单的选项对象或构造函数),而无需使用Vue.extend。这主要是为了便于扩展单文件组件。这和混入类类似。**

概括

Extend用于创建vue实例。混合蛋白可以与多种混合蛋白混合。extends只能继承一个mixins,类似于AOP,extends类似于面向对象编程优先级Vue.extendextendsmixins的总结

在这一点上,关于如何通过方法调用一个Vue组件,和使用的一些API和原理几乎是一样的。如果代码什么都不知道,你可以随时提问。欢迎交流。

以上就是本文的全部内容。希望对大家的学习有帮助,支持我们。

版权声明:手写Vue弹出Modal实现代码是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。