vue的全局API : vue.extend(component)_sunny327的博客-程序员宅基地

技术标签: vue.extend  vue.js  render  

vue.extend(component)

vue.extend我们在开发中较少用到,相比于vue.component,它的使用会比较复杂些。但是在一些独立组件开发中,比如弹框组件,需要挂载到body中,而不是#app中,这时就需要用到vue.extend+$mount了。

 

vue.extend()的官方定义:

vue.extend(options)

  • 参数:{object} options
  • 用法:

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

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

    <div id="mount-point"></div>
    // 创建构造器
    var Profile = Vue.extend({
      template: '<p>{
         {firstName}} {
         {lastName}} aka {
         {alias}}</p>',
      data: function () {
        return {
          firstName: 'Walter',
          lastName: 'White',
          alias: 'Heisenberg'
        }
      }
    })
    // 创建 Profile 实例,并挂载到一个元素上。
    new Profile().$mount('#mount-point')

    结果如下:

    <p>Walter White aka Heisenberg</p>

    注:可以看到vue.extend创建的是Vue构造器,而不是我们平时写的组件实例,所以不可以通过new Vue({ components: testExtend })  来直接使用,需要用new Profile().$mount('#mount-point')来挂载到#mount-point'元素上。

为什么使用extend

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

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

所以这时候就需要用到extend。它可以实现在body上挂载组件,使用document.body.appendChild(Profile.$el)。

下面的例子是用extend和render两种方式创建的弹框提示组件:

Notice.vue组件:

<template>
  <div class="box" v-if="isShow">
    <h3>{
   {title}}</h3>
    <p class="box-content">{
   {message}}</p>
  </div>
</template>

<script>
export default {
  props: {
    title: {
      type: String,
      default: ""
    },
    message: {
      type: String,
      default: ""
    },
    duration: {
      type: Number,
      default: 2000
    }
  },
  data() {
    return {
      isShow: false
    };
  },
  methods: {
    show() {
      this.isShow = true;
      setTimeout(this.hide, this.duration);
    },
    hide() {
      this.isShow = false;
      this.remove();
    }
  }
};
</script>

<style>
.box {
  position: fixed;
  width: 100%;
  top: 16px;
  left: 0;
  text-align: center;
  pointer-events: none;
  background-color: #fff;
  border: grey 3px solid;
  box-sizing: border-box;
}
.box-content {
  width: 200px;
  margin: 10px auto;
  font-size: 14px;
  padding: 8px 16px;
  background: #fff;
  border-radius: 3px;
  margin-bottom: 8px;
}
</style>

 

src/utils/create.js

import Vue from 'vue';
// import Notice from '@/components/Notice.vue';

//create方法最终的目标是把组件实例返回
function create(component, props) {
  //组件构造函数如何获取?
  //1、Vue.extend()

  const Ctor = Vue.extend(component)
  //创建组件实例
  const comp = new Ctor({ propsData: props })
  comp.$mount()
  document.body.appendChild(comp.$el)
  comp.remove = function () {
    document.body.removeChild(comp.$el)
    comp.$destroy()
  }




  /* //2、render
  const vm = new Vue({
    //h是createElement,返回的是vNode,是虚拟dom,需要挂载才能变成真实dom
    render: h => h(component, { props })
  }).$mount() //不指定宿主元素,则会创建真实dom,但是不会做追加dom操作,切记这里不能把body作为宿主元素

  //vm.$el是获取真实dom,把真实dom放到body中
  document.body.appendChild(vm.$el)
  const comp = vm.$children[0]

  //删除弹框组件,不能一直往body中追加弹框,这样程序会崩
  comp.remove = function () {
    document.body.removeChild(vm.$el)
    vm.$destroy()
  } */
  return comp

}
// export default create
export default {
  install(Vue) {
    Vue.prototype.$notice = function (options) {

      return create(Notice, options)
    }
  }
}

main.js中注册成全局组件

import create from './utils/create';
// Vue.prototype.$create = create
Vue.use(create)    //create已经是组件对象了,进行全局注册

在页面中调用弹框提示组件:index.vue

import Notice from "@/components/Notice.vue";


login() {
      this.$refs["kLoginForm"].validate(valid => {
        /* const notice = this.$create(Notice, {
          title: "社会你杨哥喊你来搬砖",
          message: valid ? "请求登录!" : "校验失败!",
          duration: 3000
        });
        notice.show(); */

        //这种用法更好,因为不用再在用的时候引和Notice组件了,create.js中已经有了,利用install
        console.log("this.$notice():===", this.$notice());
        const notice = this.$notice({
          title: "社会你杨哥喊你来搬砖",
          message: valid ? "请求登录!" : "校验失败!",
          duration: 2000
        });
        notice.show();

        
      });
    }

 

至此,一个全局的弹框组件就写好了。

总结:

1、component中写一个Notice.vue的组件的dom结构。src/component/Notice.vue

2、把Notice写成一个全局的工具函数,返回一个组件,并挂载到body上。src/utils/create.js

3、在main.js中注册成全局组件。

4、在页面中使用这个全局弹框组件。index.vue

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/sunny327/article/details/104208679

智能推荐

Linux安装JDK完整步骤-程序员宅基地

Linux安装JDK完整步骤出自https://www.cnblogs.com/Dylansuns/p/6974272.html1、检查一下系统中的jdk版本[root@localhost software]# java -version显示:openjdk version "1.8.0_102"OpenJDK Runtime Environment (build 1.8...

switch case后接枚举(用于判断字符串常量)_switch中的case能用枚举吗-程序员宅基地

c/c++ 语言不允许后面直接接字符串。c/c++ 语言case后面只允是整型、常量或表达式,例如:int k=3;switch(k){ case 'd'-'a': printf("d-a\n"); break; case 4 : printf("4\n"); break_switch中的case能用枚举吗

决策树之ID3 ,C4.5 ,CART,理论+实例_基尼指数o(nlogn)-程序员宅基地

不同算法特征选择依据信息熵信息熵(entropy)度量信息不确定性的量化问题。在信息论中,熵是表示随机变量不确定性的度量。熵的取值越大,随机变量的不确定性也越大。单位,比特(bit)即:对于样本集合D来说,随机变量X是样本的类别,即,假设样本有k个类别,每个类别的概率是,其中|Ck|表示类别k的样本个数,|D|表示样本总数 则对于样本集合D来说熵(经验熵)为:..._基尼指数o(nlogn)

MFC中ListCtrl的subItem0添加图标_mfc listctrl图标-程序员宅基地

1.新建MFC对话框应用程序 2.在对话框中添加一个ListCtrl控件,并将其属性中的view改为Report 3.准备两张Icon图标,然后添加到资源ICON中 4.为ListCtrl添加一个控制变量m_ListIcon,并添加一个CImageList类型的变量m_ImageList,在OnDialogInit中进行初始化void CListSubItem0IconDlg::O_mfc listctrl图标

win7安装oracle提示程序异常终止,win7系统安装oracle10g提示程序异常终止的解决方法..._刘昌睿的博客-程序员宅基地

很多小伙伴都遇到过win7系统安装oracle10g提示程序异常终止的困惑吧,一些朋友看过网上零散的win7系统安装oracle10g提示程序异常终止的处理方法,并没有完完全全明白win7系统安装oracle10g提示程序异常终止是如何解决的,今天小编准备了简单的解决办法,只需要按照1、在安装包install目录中找到“oraparam.ini”文件,单击右键选择“用记事本打开”; 2、打开后我们..._win7 oracle10 程序异常终止.

PCB LAYOUT三种特殊走线技巧-程序员宅基地

面从直角走线,差分走线,蛇形线三个方面来阐述PCB LAYOUT的走线:一、直角走线(三个方面)直角走线的对信号的影响就是主要体现在三个方面:一是拐角可以等效为传输线上的容性负载,减缓上升时间;二是阻抗不连续会造成信号的反射;三是直角尖端产生的EMI,到10GHz以上的RF设计领域,这些小小的直角都可能成为高速问题的重点对象。二、差分走线(“等长、等距、参考平面”)何为差分信号(D

随便推点

nuget 服务器 自动化,脚本 – 使用.NetCore RC2自动化Nuget包推送-程序员宅基地

我目前正在开发一个.NET Core库,我将在另一个项目中用作NuGet包.我已经能够使用项目目录中的“dotnet pack”命令成功打包项目,并将该程序包上传到MyGet.我更喜欢使用“nuget push”命令自动执行推送NuGet包的过程.我的问题是project.json文件中定义的“scripts”属性似乎不在包或构建上执行.我预计这些脚本会在相应的事件发生时执行,但它们似乎没有任何效..._nuget push

VNC如何连接远程服务器_vnc远程连接_woaisjm的博客-程序员宅基地

所有VPS均同时支持MSTSC、VNC和手机远程控制,本篇为VNC Viewer连接教程1、运行已安装好的VNC Viewer,输入连接地址(如果没特别指定,那么连接地址一般是VPS地址的端口号+1,比如VPS地址是111.112.113.114:10001,那么这里的VNC连接地址就是111.112.113.114:10002),点击Connect进入下一步2、地址正确的话会弹出确认窗口,点击Continue进入下一步3、然后再输入VNC的用户名和密码,如果没特别指定,就..._vnc远程连接

win8、server 2012 清除winsxs文件夹-程序员宅基地

使用系统自带的文件清理工具1、组合键win+x ,选择“命令提示符(管理员)”复制“dism /online /Cleanup-Image /StartComponentCleanup” 到dos窗口执行。2、检查系统盘的windows/winsxs文件夹是否变小。 也可以通过系统自带的操作界面来清理空间,如下:http://www.tweakhound.com/2013/...

JavaScript:表单基础知识_表单与javascript基础-程序员宅基地

1、表单引用var form=document.getElementById("from1");//取得id为from1的表单引用var firstForm=document.forms[0];//取得页面中的第一个表单var myForm=document.forms["form2"];//取得页面中名称为“form2”的表单2、提交表单var form=document.g_表单与javascript基础

Spring(Spring,Spring MVC,Spring Boot)基本概念-程序员宅基地

Spring Boot 是用于简化创建 Spring 项目配置流程,快速构建 Spring 应用程序的辅助工具。Spring 的基本设计思想是利用 IOC(依赖注入)和 AOP (面向切面)解耦应用组件,降低应用程序各组件之间的耦合度。在这两者的基础上,Spring 逐渐衍生出了其他的高级功能:如 Security,JPA 等。Spring 是用于开发 Java 应用程序的开源框架,为解决企业应用开发的复杂性而创建。Spring MVC 是 Spring 的子功能模块,专用于 Web 开发。

Linux向进程发送信号及执行信号处理函数的时机-程序员宅基地

Linux内核中由于不同原因(例如非法地址、按下Ctrl+C、用户进程系统调用等等)向进程发送信号的函数调用路径最后公用的函数是send_signal(),这个函数位于linux-3.13/kernel/signal.c文件中。这个函数接下来的调用链为complete_signal()->signal_wake_up()->signal_wake_up_state()->wake_up_state