方式: 利用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
使用方法:
在组件的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 ]