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

智能推荐

swagger2返回泛型_swagger2.0 泛型-程序员宅基地

第一步:返回Result加上泛型注解:Result<T>第二步:增加接口注释@ApiOperation(value="根据ID查找",notes="根据ID查询RTU设置数据")要注意没有response,加了就不管用了。下面加了response就是按照response返回了。@ApiOperation(value="根据ID查找",notes="根据ID查询RTU设置数据",response = Result.class)maven注解:..._swagger2.0 泛型

医疗行业专业术语知识-程序员宅基地

一、常用系统(1)HIS(医院信息系统) HIS全称Hospital Information System。 HIS是覆盖医院所有业务和业务全过程的信息管理系统。利用电子计算机和通讯设备,为医院所属各部门提供病人诊疗信息和行政管理信息的收集、存储、处理、提取和数据交换的能力并满足授权用户的功能需求的平台。 (2)LIS(检验信息系统) LIS全称Laboratory Inf

fork子进程时和父进程之间的文件描述符的问题-程序员宅基地

在C程序中,文件由文件指针或者文件描述符表示。ISO C的标准I/0库函数(fopen, fclose, fread, fwrite, fscanf, fprintf等)使用文件指针,UNIX的I/O函数(open, close, read, write, ioctl)使用文件描述符。下面重点来说下,文件描述符是如何工作的。文件描述符相当于一个逻辑句柄,而open,close等函数则是

MyBatis与Spring的整合-程序员宅基地

1.创建数据库CREATE DATABASE /!32312 IF NOT EXISTS/smbms /*!40100 DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci */;USE smbms;/*Table structure for table smbms_address */DROP TABLE IF EXISTS smbms_a...

考研数据结构之查找(9.8)——练习题之将关键字序列{7,8,30,11,18,9,14}散列存储到散列表中(C表示)-程序员宅基地

题目将关键字序列{7,8,30,11,18,9,14}散列存储到散列表中,散列表的存储空间是一个下标从0开始的一维数组,散列函数为H(key)=(key*3) Mod 7,处理冲突采用线性探测再散列法,要求装填因子为0.7.(1)请画出所构造的散列表。(2)分别计算等概率情况下,查找成功和查找不成功时的平均查找长度。分析...

android关于TextView的drawableLeft,drawableTop,drawableRight,drawableRight的drawable大小及位置问题_安卓按钮drawableright太靠右-程序员宅基地

经常在项目中我们会看到一个按钮采用图片及文字结合的方式来显示界面,我们如何设计布局了?第一种方法:使用一个ViewGroup,在ViewGroup中添加一个ImageView和一个TextView组合来达到这种效果。第二种方式使用Textview的drawableLeft,drawableTop,drawableRight,drawableRight来达到这种效果,但是这又有一个问题,就是_安卓按钮drawableright太靠右

随便推点

circos- Session 1 Lesson 3 Changing ideogram scale-程序员宅基地

scale adjustment is defined in the circos.conf using the chromosomes_scale parameter. The syntax of the value for this parameter is : chromosomes_scale = chr1 = 0,2 , chr2 =2 , chr3 = 10 . which ..._ideogram scale

关于修改openwrt 的界面,优化ui内存进度条_openwrt界面美化-程序员宅基地

原始的openwrt 画面不怎么完美, 所以尝试着修改了下, 练练手, 这次修改下内存的进度条:我是用radialindicator.js 修改的进度条, 这个插件的好处就是修改方便, 额且拓展性很强:首先先贴一个在自己本地的htm实现这个效果 radialIndicator.defaults.initVal_openwrt界面美化

服务端渲染和客户端渲染的一些理解-程序员宅基地

服务端渲染 (SSR)  服务端在返回 html 之前,在特定的区域,符号里用数据填充,再给客户端,客户端只负责解析 HTML 。客户端渲染(CSR)  html 仅仅作为静态文件,客户端端在请求时,服务端不做任何处理,直接以原文件的形式返回给客户端客户端,然后根据 html 上的 JavaScript,生成 DOM 插入 html。两者本质区别  客户端渲染和服务..._服务器渲染为什么不写.html客户端渲染写.html

单调队列(例题:滑动窗口)_xl文件名单调横例-程序员宅基地

单调队列: 什么是单调队列呢? 单调队列,即单调递减或单调递增的队列,也就是说该队列的最大值或最小值位于队首当我们插入一个元素时(红色)(以最大值为例)队列中的元素不是变成下面这种情况而是变成这样(从队尾开始不断弹出比要插入元素小的数,知道队尾元素大于要插入的元素,把要插入的元素插入队尾)同时在单调队列的应用过程中,通常会给单调队列会处于一个滑动的区间上,这时我们要不断更新队首来保..._xl文件名单调横例

奥赛一本通2069:【例2.12 】糖果游戏_幼儿园及有五个小朋友,他们按编号1,2,3-程序员宅基地

2069:【例2.12 】糖果游戏时间限制: 1000 ms 内存限制: 65536 KB提交数: 13213 通过数: 6519【题目描述】某幼儿园里,有5个小朋友编号为1、2、3、4、5,他们按自己的编号顺序围坐在一张圆桌旁。他们身上都有若干个糖果(键盘输入),现在他们做一个分糖果游戏。从1号小朋友开始,将自己的糖果均分三份(如果有多余的糖果,则立即吃掉),自己留一份,其余两份分给他的相邻的两个小朋友。接着2号、3号、4号、5号小朋友同样这么做。问一轮后,每个小..._幼儿园及有五个小朋友,他们按编号1,2,3

PHP有关去空格的正则表达式_php正则表达式 空格-程序员宅基地

1.去后导空格(包括半角空格和全角空格)的正则表达式先用正则表达式$str=ereg_replace("( | )*$","",$str)将字符串结尾处的半角空格和全角空格用半角空格替换,然后再用函数trim($str)即可2.去前导空格(包括半角空格和全角空格)的正则表达式先用正则表达式$str=ereg_replace("^( | )*|","",$str)将字符串前面的半角空格和全角_php正则表达式 空格