• Vue挂载(mount)和继承(extend)


    vue.$mount 挂载

    //index.html文件
    <body>
      <div id="app"></div>
    </body>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    //index.js文件
    //1. 先看看普通的绑定
    new Vue({
      el: '#app',
      // el: document.getElementById('app') 
      template: `
    如果new Vue时候的option的el属性存在,那么它会自动的绑定并渲染到页面上
    `
    }) //2. vm.$mount( [elementOrSelector] ) 元素或者选择器(类'#app') /*如果没有提供 elementOrSelector 参数,模板将被渲染为文档之外的的元素,并且你必须使用原生 DOM API 把它插入文档中*/ //2.1 var vm = new Vue({ //没有el选项 template: `
    如果new Vue时候的option的el属性存在,那么它会自动的绑定并渲染到页面上
    `
    }) vm.$mount('#app') //自动创建渲染在DOM外并绑定渲染 //2.2 var vm = new Vue({ //没有el选项 template: `
    如果new Vue时候的option的el属性存在,那么它会自动的绑定并渲染到页面上
    `
    }) vm.$mount() //自动创建渲染在DOM外,可以打印vm.$el => myapp的元素 注意是根据template生成了DOM树,但是还在内存里 document.body.appendChild(vm.$el)
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    Vue.extend
    它其实就是类的继承的意思,它其实是一种寄生组合式的继承如果你把Vue.extend(someClass)看成Vue的子类,其实你已经理解了一半了
    我们再来看一个官方的例子

    <div id="mount-point"></div>
    
    
    • 1
    • 2
    //创建构造函数
    var Profile=vue.extend({
       template: '

    {{firstName}} {{lastName}} aka {{alias}}

    '
    , data: function () { return { firstName: 'Walter', lastName: 'White', alias: 'Heisenberg' } } }) //创建Profile实例,并挂载到一个元素上 var profile1=new Profile().$mount('#mount-point')
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    使用基础Vue构造器,创建一个"子类"。参数是一个包含组件选项的对象。
    data选项是特例,需要注意,在Vue.extend()中它必须是函数。
    可以看到,extend 创建的是 Vue 构造器,而不是我们平时常写的组件实例,所以不可以通过 new Vue({ components: testExtend }) 来直接使用,需要通过 new Profile().$mount(’#mount-point’) 来挂载到指定的元素上。
    我个人的理解来看,extend提供了一个能够构造组件的函数(也就是构造器)。在一些特定的应用场景(如自己构建一个复杂弹窗)下,我们使用这种函数式的构造组件的方法,会更灵活一些。

    Vue.extend实现加载效果

    <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: '
    {{msg}}
    '
    , 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('正在加载,请稍等...') setTimeout(() => { hide() }, 2000) } } }) </script> </body> </html>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60

    Vue.extend()实现MessageBox弹窗
    (1)新建一个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:'标题',
              msg:'这是一个弹出框组件',
              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>
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94

    (2) 新建messageBox.js

    import Vue from 'vue'
    import Confirm from './MessageBox.vue'
    
    let confirmStructor=Vue.extend(Confirm)   //返回一个实例创建的构造器,但实例构造器需要进行挂载到页面中
    
    let theConfirm=function(text){
        return new Promise((res,rej)=>{       //返回一个promise,进行异步操作,成功时返回,失败时返回
            let confirmDom=new confirmStructor({
                el:document.createElement('div')
            })
            //在body中动态创建一个div元素,之后此div将会替换成整个vue文件的内容
            //此时的confirmDom通俗讲就是相当于是整个组件对象,通过对象调用属性的方法来进行组件中数据的使用
            //可以通过$el属性来访问创建的组件实例
            document.body.appendChild(confirmDom.$el)
    
            //此时进行创建组件的逻辑处理
            confirmDom.text=text       //将需要传入的文本内容传给组件实例
            confirmDom.ok=()=>{     //箭头函数,在()和{}之间增加=>,且去掉function
                res()   //正确时返回的操作
                confirmDom.flag=false;
            }
            confirmDom.no=()=>{
                rej()   //失败时返回的操作
                confirmDom.flag=false;
            }    
        })
    }
    
    //将逻辑函数进行导出和暴露
    export default theConfirm
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    (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')
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    (4)页面使用

        this.$Myconfirm({
          title:'标题',
          msg:'内容',
          btn:{ ok:'确定', no:'取消'}
        }).then(()=>{
          console.log('ok')
        }).catch(()=>{
          console.log('no')
        })
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    (5)效果如下:
    在这里插入图片描述

  • 相关阅读:
    CAS:183896-00-6 (Biotin-PEG3-C3-NH2) PEG衍生物
    MySQL数据库简单安装
    Arcgis克里金插值报错:ERROR 999999: 执行函数时出错。 表名无效。 空间参考不存在。 ERROR 010429: GRID IO 中存在错误
    轻量级的低级线程和任务框架---Argobots
    模拟实现【哈希】
    数据库系统原理与应用教程(080)—— MySQL 练习题:操作题 186-193(二十四):综合练习
    【Android 屏幕适配】异形屏适配 ① ( 异形屏类型:刘海屏、水滴屏、挖孔屏 | 沉浸式布局刘海屏适配 | 华为手机异形屏适配注意点 )
    一文搞懂static(一)
    Windows与网络基础-23-传输介质-双绞线
    记录--基于Vue2.0实现后台系统权限控制
  • 原文地址:https://blog.csdn.net/m0_49515138/article/details/127979805