Vue中extend基本用法

1.Vue.extend(options)
  • 參數(shù):
    {Object} options
  • 用法:
    使用基礎(chǔ)Vue構(gòu)造器,創(chuàng)建一個(gè)"子類"。參數(shù)是一個(gè)包含組件選項(xiàng)的對(duì)象。
    data選項(xiàng)是特例,需要注意,在Vue.extend()中它必須是函數(shù)。
<html>
  <head>
    <title>Vue.extend 用法</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  </head>
  <body>
    <div id="mount-point"></div>
    <script>
      // 創(chuàng)建構(gòu)造器
      var Profile = Vue.extend({
        template: '<p>{{firstName}} {{lastName}} aka {{alias}}</p>',
        data: function () {
          return {
            firstName: 'Walter',
            lastName: 'White',
            alias: 'Heisenberg'
          }
        }
      })
      // 創(chuàng)建 Profile 實(shí)例,并掛載到一個(gè)元素上。
      new Profile().$mount('#mount-point')
    </script>
  </body>
</html>

結(jié)果顯示如下:


image.png

可以看到,extend 創(chuàng)建的是 Vue 構(gòu)造器,而不是我們平時(shí)常寫(xiě)的組件實(shí)例,所以不可以通過(guò) new Vue({ components: testExtend }) 來(lái)直接使用,需要通過(guò) new Profile().$mount('#mount-point') 來(lái)掛載到指定的元素上。
我個(gè)人的理解來(lái)看,extend提供了一個(gè)能夠構(gòu)造組件的函數(shù)(也就是構(gòu)造器)。在一些特定的應(yīng)用場(chǎng)景(如自己構(gòu)建一個(gè)復(fù)雜彈窗)下,我們使用這種函數(shù)式的構(gòu)造組件的方法,會(huì)更靈活一些。

2.Vue.extend實(shí)現(xiàn)加載效果
<html>
  <head>
    <title>Vue.extend 用法2</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <style>
      #loading-wrapper {
        position: fixed;
        top: 0;
        left: 0;
        display: flex;
        justify-content: center;
        align-items: center;
        width: 100%;
        height: 100%;
        background: rgba(0,0,0,.7);
        color: #fff;
      }
    </style>
  </head>
  <body>
    <div id="root">
      <button @click="showLoading">顯示Loading</button>
    </div>
    <script>
      function Loading(msg) {
        const LoadingComponent = Vue.extend({
          template: '<div id="loading-wrapper">{{msg}}</div>',
          props: {
            msg: {
              type: String,
              default: msg
            }
          },
          name: 'LoadingComponent'
        })
        const div = document.createElement('div')
        div.setAttribute('id', 'loading-wrapper')
        document.body.append(div)
        new LoadingComponent().$mount('#loading-wrapper')
        return () => {
          document.body.removeChild(document.getElementById('loading-wrapper'))
        }
      }
      Vue.prototype.$loading = Loading
      new Vue({
        el: '#root',
        methods: {
          showLoading() {
            const hide = this.$loading('正在加載,請(qǐng)稍等...')
            setTimeout(() => {
              hide()
            }, 2000)
          }
        }
      })
    </script>
  </body>
</html>

3.Vue.extend()實(shí)現(xiàn)MessageBox彈窗

(1)新建一個(gè)messageBox.vue

<template>
  <div id="confirm" v-if='flag'>
    <div class="contents" >
      <div class="content-top">{{text.title}}</div>
      <div class="content-center">{{text.msg}}</div>
      <div class="content-bottom">
        <button type='primary' @click='ok' class="left">{{text.btn.ok}}</button>
        <button type='info' @click='no' class="right">{{text.btn.no}}</button>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  data () {
    return {
      flag:true,
      text:{
          title:'標(biāo)題',
          msg:'這是一個(gè)彈出框組件',
          btn:{
              ok:'確定',
              no:'取消'
          }
      }
    }
  },
  methods: {
    ok(){
      this.flag=false;
    },
    no(){
      this.flag=false;
    }
  }
}
</script>

<style scoped>
 #confirm{
     position:fixed;
     left:0;
     top:0;
     right:0;
     bottom:0;
     background:rgba(0,0,0,0.3);   
 }
 .contents{
    width:250px;
    height:180px;
    border:1px solid #ccc;
    border-radius:10px;
    background-color:#fff;
    position:fixed;
    top:50%;
    left:50%;
    margin-top:-90px;
    margin-left:-125px;
}
.content-top{
    width:100%;
    height:40px;
    border-bottom:1px solid #ccc;
    text-align: center;
    font-size:20px;
    font-weight: 700;
    line-height:40px;
}
.content-center{
    width:90%;
    height:80px;
    margin:5px auto;
}
.content-bottom{
    width:85%;
    height:40px;
    margin:0 auto;
    /* border:1px solid red; */
    position:relative;
}
.left{
    position:absolute;
    left:0;
    width:40%;
}
.right{
    position:absolute;
    right:0;
    width:40%;
}
</style>

(2) 新建messageBox.js

import Vue from 'vue'
import Confirm from './MessageBox.vue'

let confirmStructor=Vue.extend(Confirm)   //返回一個(gè)實(shí)例創(chuàng)建的構(gòu)造器,但實(shí)例構(gòu)造器需要進(jìn)行掛載到頁(yè)面中

let theConfirm=function(text){
    return new Promise((res,rej)=>{       //返回一個(gè)promise,進(jìn)行異步操作,成功時(shí)返回,失敗時(shí)返回
        let confirmDom=new confirmStructor({
            el:document.createElement('div')
        })
        //在body中動(dòng)態(tài)創(chuàng)建一個(gè)div元素,之后此div將會(huì)替換成整個(gè)vue文件的內(nèi)容
        //此時(shí)的confirmDom通俗講就是相當(dāng)于是整個(gè)組件對(duì)象,通過(guò)對(duì)象調(diào)用屬性的方法來(lái)進(jìn)行組件中數(shù)據(jù)的使用
        //可以通過(guò)$el屬性來(lái)訪問(wèn)創(chuàng)建的組件實(shí)例
        document.body.appendChild(confirmDom.$el)

        //此時(shí)進(jìn)行創(chuàng)建組件的邏輯處理
        confirmDom.text=text       //將需要傳入的文本內(nèi)容傳給組件實(shí)例
        confirmDom.ok=()=>{     //箭頭函數(shù),在()和{}之間增加=>,且去掉function
            res()   //正確時(shí)返回的操作
            confirmDom.flag=false;
        }
        confirmDom.no=()=>{
            rej()   //失敗時(shí)返回的操作
            confirmDom.flag=false;
        }    
    })
}

//將邏輯函數(shù)進(jìn)行導(dǎo)出和暴露
export default theConfirm

(3)mian.js引入掛載到全局

import Vue from 'vue';
import store from './store/index'
import App from './App.vue';
import router from './router';
import theConfirm from './components/messageBox.js'
Vue.config.productionTip = false;

Vue.prototype.$Myconfirm=theConfirm


new Vue({
  router,
  store,
  render: h => h(App),
}).$mount('#app')

(4)頁(yè)面使用

    this.$Myconfirm({
      title:'標(biāo)題',
      msg:'內(nèi)容',
      btn:{ ok:'確定', no:'取消'}
    }).then(()=>{
      console.log('ok')
    }).catch(()=>{
      console.log('no')
    })

(5)效果如下:


image.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容