vue自定义组件 (两种之二)弹窗为例
Posted dangdanghepingping
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue自定义组件 (两种之二)弹窗为例相关的知识,希望对你有一定的参考价值。
方式: 利用js代码,在必要时候动态弹出组件, 而不需要Vue.use,也必在页面上写组件.
依据:
vm.$mount( [elementOrSelector] )
-
参数:
{Element | string} [elementOrSelector]
{boolean} [hydrating]
-
返回值:
vm
- 实例自身 -
用法:
如果 Vue 实例在实例化时没有收到 el 选项,则它处于“未挂载”状态,没有关联的 DOM 元素。可以使用
vm.$mount()
手动地挂载一个未挂载的实例。如果没有提供
elementOrSelector
参数,模板将被渲染为文档之外的的元素,并且你必须使用原生 DOM API 把它插入文档中。
vm.$el
-
类型:
Element
-
只读
-
详细:
Vue 实例使用的根 DOM 元素。
Vue.extend( options )
-
参数:
{Object} options
-
用法:
使用基础 Vue 构造器,创建一个“子类”。参数是一个包含组件选项的对象。
方法:
(一)用Vue.extend(vueComponent对象), 返回一个以参数对象为模板的vue组件实例的构造函数.
这个构造函数参数是{date,methods}这种形式,会覆盖在VueComponent里的相同数据值,
(二)定义一个函数, 函数执行做三件事:
1用这个构造函数创建vue的一个vue组件实例,
2 挂载它,挂载方法直接是 vm.$mount();参加$mount的Api
3 用原生方法将这个实例插到body里.
(三)将这个构造函数挂载在Vue.prototype上. 注意,让这个组件消失的方法是$el.remove();
代码: 在components文件夹下新建一个文件夹,里面有alert.vue和index.js两个文件
alert.vue模板的代码:
1 <template> 2 <div class="shade"> 3 <div class="mian"> 4 <div class="content"> 5 <span>{{ message }}</span> 6 </div> 7 <div class="btns"> 8 <div 9 class="btn" 10 v-for="(btn,index) in btns" 11 :key="index" 12 @click="()=>clickFn(btn)" 13 >{{btn.text}}</div> 14 </div> 15 </div> 16 </div> 17 </template> 18 <script> 19 export default { 20 name: "alert", 21 data() { 22 return { 23 // message: "this a alert", 24 // btns: [ 25 // { 26 // text: "yes", 27 // click: () => console.log("yes") 28 // }, 29 // { 30 // text: "no", 31 // click: () => console.log("no") 32 // } 33 // ] 34 }; 35 }, 36 methods: { 37 clickFn(btn) { 38 this.$el.remove(); // 移除DOM this.$el表示这个vm实例的根元素 39 const { click = () => console.warn("请传入回调函数") } = btn; //es6的结构赋值, btn.click如果有值,则赋值给click,否则赋值为匿名函数 40 click(); // 执行传递进来的click方法 41 } 42 } 43 }; 44 </script> 45 46 <style scoped> 47 .shade { 48 user-select: none; 49 width: 100vw; 50 height: 100vh; 51 position: fixed; 52 top: 0; 53 left: 0; 54 background-color: rgba(0, 0, 0, 0.03); 55 z-index: 998; 56 display: flex; 57 align-items: center; 58 justify-content: center; 59 } 60 61 .shade .mian { 62 background: white; 63 width: 80%; 64 border-radius: 5px; 65 overflow: hidden; 66 box-shadow: 0px 0px 5px 3px rgba(0, 0, 0, 0.04); 67 box-sizing: border-box; 68 animation: open 0.1s; 69 } 70 71 .shade .mian .content { 72 box-sizing: border-box; 73 width: 100%; 74 padding: 30px 20px; 75 } 76 77 .shade .mian .btns { 78 height: 45px; 79 box-sizing: border-box; 80 border-top: 1px solid rgba(0, 0, 0, 0.1); 81 display: flex; 82 justify-content: space-around; 83 align-items: center; 84 } 85 86 .shade .mian .btns .btn { 87 flex: 1 0 auto; 88 height: 100%; 89 display: flex; 90 align-items: center; 91 justify-content: center; 92 text-align: center; 93 border-right: 1px solid rgba(0, 0, 0, 0.1); 94 } 95 96 .shade .mian .btns .btn:last-child { 97 border-right: none; 98 } 99 100 .shade .mian .btns .btn:active { 101 color: white; 102 background-color: rgb(64, 169, 243); 103 } 104 105 @keyframes open { 106 0%, 100% { 107 transform: scale(1); 108 } 109 110 25%, 75% { 111 transform: scale(1.04); 112 } 113 114 50% { 115 transform: scale(1.06); 116 } 117 } 118 </style>
index.js的代码
1 import Vue from ‘vue‘; 2 import alert from ‘./alert.vue‘; 3 let MyAlertConstructor = Vue.extend(alert);//创建vm实例的构造函数 4 let instance; 5 const MyAlert = (option) => { //写一个重要的方法,里面有三个内容 6 // 创建实例并且过滤参数 7 8 instance = new MyAlertConstructor({ //1生成实例 9 data: option 10 }) 11 // 2 挂载实例 12 instance.$mount(); 13 document.body.appendChild(instance.$el);//3原生方法插入body 14 return instance; 15 } 16 export default MyAlert;
主文件main.js里, 挂载方法
1 import MyAlert from ‘./components/Toast1‘;//自定义弹框 2 Vue.prototype.$alert = MyAlert;
使用方法:
在组件的js文件里, 当需要弹出时候, 用this.$alert({data:{
1 message: "你今天开心吗?", 2 btns: [ 3 { 4 text: "开心", 5 click: () => { 6 // 测试是否可以拿到这边的this 7 console.log(this.msg); 8 } 9 }, 10 { 11 text: "不开心", 12 click: () => { 13 // 这里的event target 可能没用 因为已经移除DOM了 14 // 返回btn原来本身 15 console.log("不开心"); 16 } 17 }, 18 { 19 text: "无回调" 20 // 测试一下没有回调函数的时候 21 }, 22 { 23 text: "帮助", 24 click: this.isOK 25 } 26 ]
}})
以上是关于vue自定义组件 (两种之二)弹窗为例的主要内容,如果未能解决你的问题,请参考以下文章