vue的全局API : vue.extend(component)

vue.extend(component)

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

 

vue.extend()的官方定义:

vue.extend(options)

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

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

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

    // 创建构造器
    var Profile = Vue.extend({
      template: '

    { {firstName}} { {lastName}} aka { {alias}}

    ', data: function () { return { firstName: 'Walter', lastName: 'White', alias: 'Heisenberg' } } }) // 创建 Profile 实例,并挂载到一个元素上。 new Profile().$mount('#mount-point')

    结果如下:

    Walter White aka Heisenberg

    注:可以看到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组件:





 

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

 

你可能感兴趣的:(vue.js,vue.extend,render)