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自定义组件 (两种之二)弹窗为例的主要内容,如果未能解决你的问题,请参考以下文章

Vue 之 父组件给子组件传参实现自定义弹窗组件

Vue 之 父组件给子组件传参实现自定义弹窗组件

Vue 之 父组件给子组件的传参的另类方式实现自定义弹窗组件

VsCode编辑器如何自定义代码片段

React 如何设计一个弹窗组件

封装Vue组件的一些技巧