(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--> | |
* | |
* */ | |
})() |
Vue.extend和Vue.component的联系与差异
最新推荐文章于 2024-07-06 11:29:44 发布