| (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.youkuaiyun.com/o0__0/article/details/54291394--> | |
| <!--http://www.bubuko.com/infodetail-2083202.html--> | |
| <!--https://blog.youkuaiyun.com/dkr380205984/article/details/80116024--> | |
| * | |
| * */ | |
| })() |
Vue.extend和Vue.component的联系与差异
最新推荐文章于 2025-07-19 15:11:26 发布
本文详细探讨了Vue.js中组件的多种使用方式,包括Vue.extend的功能及其与Vue.component的区别,展示了如何利用Vue.extend进行组件的动态插入和特殊需求实现。
2055

被折叠的 条评论
为什么被折叠?



