Vue.extend、Vue.component、new Vue以及动态编译Vue.compile
先说说Vue.extend(vue扩展构造器)、Vue.component(vue全局组件注册)、new Vue(创建vue根实例)三者之间的关系。
野路子理解:
1、Vue.extend(options):
1、根据官方文档的描述是用来创建Vue“子类”的api,也就是创建一个新的构造函数。
2、该构造函数里面包含了对Vue初始化函数的调用,另外Vue.extend里通过Object.create()以Vue的原型对象为原型创建了新的对象当做该构造函数的原型,这样做的好处是更改原型属性时,避免对Vue的原型造成污染同时又继承了Vue的原型属性。
3、options是共有的选项数据,也就是只要由该构造函数创建的实例都会有这些选项,和mixin一毛一样。另外实例初始化时还可以传递实例单独的options选项。
4、因为生成的构造函数在new调用时,函数里调用了Vue的初始化方法,所以生成的是一个正了八经的Vue实例对象。
2、Vue.component(options):
1、用来注册全局组件,官网上有三种用法:
// 1、注册组件,传入一个扩展过的构造器
Vue.component(‘my-component’, Vue.extend({ /* … */ }))
// 2、注册组件,传入一个选项对象 (自动调用 Vue.extend)
Vue.component(‘my-component’, { /* … */ })
// 3、获取注册的组件 (始终返回构造器)
var MyComponent = Vue.component(‘my-component’)
1、根据第1、2用法再加上options参数和Vue.extend的options可以一毛一样,由此得出注册组件就是根据Vue.extend的选项options创建一个新的构造函数,和注册时填写的id名称一一对应。
2、可以这么理解:每一次组件实例化,其实都是根据这个新的构造函数来创建。当然实际要考虑的更多。
3、new Vue()
官方文档中经常见到:
通过 new Vue 创建的根 Vue 实例
刚开始以为new Vue()才是根实例,后来看了源码发现,这只是代表了一个组件树结构的根组件。不信可以测一下 Vue.extend返回的构造函数创建的实例也可以是根实例。
不过通常应用中的根实例都是通过new Vue()创建的:
1、spa应用的根实例只有一个。
2、稍微老点的系统可能一个页面一个根实例。
4、Vue.compile
这个api不常用,但是用起来也挺爽。根据一次实际应用来介绍它。
需求:
根据配置页面的模板字符串动态改变页面显示内容。
比如模板字符串可能配成以下几种:
this.templateStr=
1、“item.name”;
2、“getName(item.id)”;
3、“‘我的名字是’+getName(item.id)”;
上面三种都是vue中的模板表达式,由于都是字符串形式,所以这里就可以用Vue.compile来编译,具体如下:
// 组合要编译的字符串
const templateStr = `<span>{{this.templateStr}}</span>`;
// 调用Vue.compile获取render函数
const templateRes = Vue.compile(templateStr);
// render函数执行需要Vue实例,否则报错,并且,模板中的各种属性、方法都会去这个实例里面找,所以。。。实例可以随便搞了
// 这样
const node1 = templateRes.render.call(this);
// 这样
const Ctor = Vue.extend();
const vueInstance = new Ctor({
data: function() {
return {
item: {
name: 'zhangsan',
id: '1'
}
}
},
methods: {
getName(id){
return 'zhangsan' + id;
}
}
});
const node2 = templateRes.render.call(vueInstance);
代码中node1、node2就是vnode实例。
提示:render函数执行需要Vue实例,否则报错,并且,模板中的各种属性、方法都会去这个实例里面找。