Vue.extend和Vue.component的联系与差异

(function(){
 //Vue.extend()会得到一个VueComponent类,VueComponent类是Vue类的子类
 var options={
 //el:document.createElement('div'), //不能有el选项
 template:"<div>测试{{Math.random()}}</div>"
 }
 var apple = Vue.extend(options);//得到VueComponent类
  
 //通过Vue.extend得到一个VueComponent类,有三种用法
 //用法一
 var $vm=new apple({//得到Vue实例,因为VueComponent类是Vue类的子类
 //el:document.createElement('div')
 //el:"#app" //直接添加到id为app的元素所在位置,替换#app(即id为app的元素会被删除)
 });
 //$vm.$mount("#app");//添加到页面,不需要el参数,替换#app//等于$vm.$mount({el:"#app"});
  
 $vm.$mount();//编译VNode虚拟节点变成真实dom,并将dom节点添加到$el属性上
 document.body.appendChild($vm.$el);//不需要el参数
  
 //document.body.appendChild($vm.$el);//添加到页面,需要el参数el:document.createElement('div'),替换创建的div
  
 //用法二
 new apple({//或new Vue
 el:"#app",
 render:function(createElement){
 console.log(createElement(apple));
 return createElement(apple) //通过createElement创建得到VNode虚拟dom对象
 }
 })
  
 //用法三
 Vue.component("apple",apple);//全局注册组件,返回值依然是VueComponent类
  
 //用法四
 new Vue({
 components:{
 apple:apple //局部注册组件,可以用于任何组件参数components内
 }
 })
  
 //Vue.component 你可以创建 ,也可以取组件
 var VueComponentFn=Vue.component("apple11",apple);//全局注册组件,返回值依然是VueComponent类
 Vue.component("apple11");//获取组件,得到的是VueComponent类
 console.log(VueComponentFn===Vue.component("apple11"))//true
  
  
 //$vm.createElement
 // @returns {VNode}
 function createElement(){}
 createElement(
 // {String | Object | Function}
 // 一个 HTML 标签字符串,组件选项对象,或者
 // 解析上述任何一种的一个 async 异步函数。必需参数。
 'div',
  
 // {Object}
 // 一个包含模板相关属性的数据对象
 // 你可以在 template 中使用这些特性。可选参数。
 {
 // 和`v-bind:class`一样的 API
 // 接收一个字符串、对象或字符串和对象组成的数组
 'class': {
 foo: true,
 bar: false
 },
 // 和`v-bind:style`一样的 API
 // 接收一个字符串、对象或对象组成的数组
 style: {
 color: 'red',
 fontSize: '14px'
 },
 // 普通的 HTML 特性
 attrs: {
 id: 'foo'
 },
 // 组件 props
 props: {
 myProp: 'bar'
 },
 // DOM 属性
 domProps: {
 innerHTML: 'baz'
 },
 // 事件监听器基于 `on`
 // 所以不再支持如 `v-on:keyup.enter` 修饰器
 // 需要手动匹配 keyCode。
 on: {
 click: this.clickHandler
 },
 // 仅用于组件,用于监听原生事件,而不是组件内部使用
 // `vm.$emit` 触发的事件。
 nativeOn: {
 click: this.nativeClickHandler
 },
 // 自定义指令。注意,你无法对 `binding` 中的 `oldValue`
 // 赋值,因为 Vue 已经自动为你进行了同步。
 directives: [
 {
 name: 'my-custom-directive',
 value: '2',
 expression: '1 + 1',
 arg: 'foo',
 modifiers: {
 bar: true
 }
 }
 ],
 // 作用域插槽格式
 // { name: props => VNode | Array<VNode> }
 scopedSlots: {
 default: function(props){createElement('span', props.text)}
 },
 // 如果组件是其他组件的子组件,需为插槽指定名称
 slot: 'name-of-slot',
 // 其他特殊顶层属性
 key: 'myKey',
 ref: 'myRef',
 // 如果你在渲染函数中向多个元素都应用了相同的 ref 名,
 // 那么 `$refs.myRef` 会变成一个数组。
 refInFor: true
 }
  
 // {String | Array}
 // 子虚拟节点 (VNodes),由 `createElement()` 构建而成,
 // 也可以使用字符串来生成“文本虚拟节点”。可选参数。
 [
 '先写一些文字',
 createElement('h1', '一则头条'),
 createElement(apple, {
 props: {
 omeProp: 'foobar'
 }
 })
 ]
 );
 //console.log($vm.$createElement)
 function vueCreate(opt){
 var arr=Object.prototype.toString.call(opt)=="[object Array]"?opt:[opt];
 var $vm1=new apple({
 render:function(h){
 console.log(arr.length==1?arr[0]:arr);
 console.log(h(arr));
 console.log("%c<--------->","color:red");
 return h.apply(this,arr);
 }
 }).$mount();
 document.body.appendChild($vm1.$el);
 }
 var arr=[options,apple,VueComponentFn,"apple11"];
 arr=arr.concat([
 ["div","测试X"],
 ["div",{'class':"test"},"测试Y"],
 [function(resolve,reject){//延迟加载组件
 setTimeout(function(){
 resolve(apple);
 },3000)
 }]
 ]);
 for(var a in arr){
 vueCreate(arr[a]);
 }
 console.log("%c循环结束","color:red");
  
 console.log($vm.$createElement(options));//可以直接根据Vue参数对象创建
 console.log($vm.$createElement(apple));
 console.log($vm.$createElement(VueComponentFn));
 console.log($vm.$createElement("apple11"));//根据Vue组件名称创建
  
 console.log($vm.$createElement("div","测试X"));
 console.log($vm.$createElement("div",{'class':"test"},"测试Y"));
 console.log($vm.$createElement(function(resolve,reject){//延迟加载组件
 setTimeout(function(){
 resolve(apple);
 },3000)
 }))
  
 //总结:component是extend的亲民版,但在实现某些特殊需求的时候,就需要用到extend,
 //如alert组件,你肯定希望alert可以动态插入到body中,而不需要在dom文档流中放一个莫名其妙的alert,大部分时间他还是隐藏的。
 //(你能用component实现我服你,除非全局注册组件之后得到VueComponent类再实例化添加到页面,那也是多此一举)
  
 /*
 * <!--参考文章:https://blog.csdn.net/o0__0/article/details/54291394-->
  
 <!--http://www.bubuko.com/infodetail-2083202.html-->
  
 <!--https://blog.csdn.net/dkr380205984/article/details/80116024-->
 *
 * */
 })()
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值