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);//注释 这样的调用组件内的方法会在组件内created里最后被执行
        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)

 

 

 

 

 

 

 

posted @ 2020-06-13 12:58  古墩古墩  Views(576)  Comments(0Edit  收藏  举报