方式: 利用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 ]
}})