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 @   古墩古墩  Views(668)  Comments(0Edit  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示