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         ]

 

}})

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM