zoukankan      html  css  js  c++  java
  • vue基础 Vue.extend

     Vue.extend 属于 Vue 的全局 API,在实际业务开发中我们很少使用,因为相比常用的 Vue.component 写法使用 extend 步骤要更加繁琐一些。但是在一些独立组件开发场景中,Vue.extend + $mount 这对组合是我们需要去关注的。

    官方文档:https://cn.vuejs.org/v2/api/index.html#Vue-extend

    参数:{Object} options

    用法:使用基础 Vue 构造器,创建一个“子类”。参数是一个包含组件选项的对象。

    data 选项是特例,需要注意 - 在 Vue.extend() 中它必须是函数

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.11/vue.min.js"></script>
    </head>
    <body>
        <div id="mount-point"></div>
        <script>
    
            //创建构造器函数
            var profile = Vue.extend({
                template:`<p>{{fisrstName}} ----  {{lastName}}</p>`,
                data:function(){
                    return {
                        fisrstName:"第一个名字",
                        lastName:"第二个名字"
                    }
                }
            });
            // 创建 Profile 实例,并挂载到一个元素上。
            new profile().$mount("#mount-point");
        </script>
    </body>
    </html>

    渲染结果:

    <p>第一个名字 ----  第二个名字</p>

    可以看到,extend 创建的是 Vue 构造器,而不是我们平时常写的组件实例,所以不可以通过

    new Vue({ components: testExtend }) 来直接使用,需要通过 new Profile().$mount('#mount-point') 来挂载到指定的元素上。

    为什么使用 extend

    在 vue 项目中,我们有了初始化的根实例后,所有页面基本上都是通过 router 来管理,组件也是通过 import 来进行局部注册,所以组件的创建我们不需要去关注,相比 extend 要更省心一点点。但是这样做会有几个缺点:

    1. 组件模板都是事先定义好的,如果我要从接口动态渲染组件怎么办?
    2. 所有内容都是在 #app 下渲染,注册组件都是在当前位置渲染。如果我要实现一个类似于 window.alert() 提示组件要求像调用 JS 函数一样调用它,该怎么办?

    这时候,Vue.extend + vm.$mount 组合就派上用场了。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.11/vue.min.js"></script>
    </head>
    <body>
        <script>
    
            const testComponent = Vue.extend({
                template: '<div>{{ text }}</div>',
                data: function () {
                    return {
                        text: 'extend test'
                    }
                }
            })
            // 然后我们将它手动渲染:
            const extendComponent = new testComponent().$mount();
            // 这时候,我们就将组件渲染挂载到 body 节点上了。
            // 我们可以通过 $el 属性来访问 extendComponent 组件实例:
            document.body.appendChild(extendComponent.$el)
        </script>
    </body>
    </html>

    完。

    再看个神操作:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.11/vue.min.js"></script>
    </head>
    <body>
        <script>
    
            const testComponent = Vue.extend({
                template: `<div>
                    <span v-show="aa == true">{{ text }}{{aa}}{{cc}}</span>
                </div>`,
                data: function () {
                    return {
                        text: 'extend test',
                        aa : false
                    }
                },
                methods: {
                    hide(booleanVal){
                        this.aa = booleanVal;
                    }
                },
            })
            //取到实例对象
            let instance = new testComponent();
            instance.hide(true)
            instance.cc= "哈哈";
            // 然后我们将它手动渲染:
            const extendComponent = instance.$mount();
            // 这时候,我们就将组件渲染挂载到 body 节点上了。
            // 我们可以通过 $el 属性来访问 extendComponent 组件实例:
            document.body.appendChild(extendComponent.$el)
        </script>
    </body>
    </html>

    可以看到我们可以在渲染之前 通过操作实例对象的值和方法来控制渲染的结果!!!

    另外,在渲染之前 我们可以对实例对象进行混入操作:

    比如:

    instance = Object.assign(instance,{key,val})

    这些key会 混入到 实例的data对象里!!!

    另外,在创建实例对象的时候,我们可以传入一些data值以及方法:

    比如:

    //取到实例对象
            let instance = new testComponent({
                data:function(){
                    return{
                        dd:"dsdds"
                    }
                }
            });

    !!!真强大

    来个综合例子:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.11/vue.min.js"></script>
    </head>
    <body>
        <script>
    
            const testComponent = Vue.extend({
                template: `<div>
                    <span v-show="aa == true">{{ text }}{{aa}}{{cc}}{{dd}}{{ee}}</span>
                </div>`,
                data: function () {
                    return {
                        text: 'extend test',
                        aa : false
                    }
                },
                methods: {
                    hide(booleanVal){
                        this.aa = booleanVal;
                    }
                },
            })
            //取到实例对象
            let instance = new testComponent({
                data:function(){
                    return{
                        dd:"dsdds"
                    }
                }
            });
            instance.hide(true)
            instance.cc= "哈哈";
            instance = Object.assign(instance,{ee:"asign"})
            // 然后我们将它手动渲染:
            const extendComponent = instance.$mount();
            // 这时候,我们就将组件渲染挂载到 body 节点上了。
            // 我们可以通过 $el 属性来访问 extendComponent 组件实例:
            document.body.appendChild(extendComponent.$el)
        </script>
    </body>
    </html>

     挂载实例也可以这样写:

    // 然后我们将它手动渲染:
    instance.vm = instance.$mount();
    // 这时候,我们就将组件渲染挂载到 body 节点上了。
    // 我们可以通过 $el 属性来访问instance组件实例: 
    document.body.appendChild(instance.$el)

  • 相关阅读:
    链表详解自带代码
    队列
    单词翻转
    表达式求值
    一元多项式
    循环链表
    学生成绩管理系统
    双向循环链表
    双向链表
    静态链表
  • 原文地址:https://www.cnblogs.com/fqh123/p/13113588.html
Copyright © 2011-2022 走看看