从结构上看,组件之于实例,就比如轮子之于汽车。从属性和方法来看,组件有实例的大部分方法,若是Vue实例是孙悟空,组件就比如实例的一个毫毛,变化无穷却为Vue实例所用。javascript
目录:html
组件的注册vue
is的做用java
event,props,soltsnode
动态组件git
有两种方式注册Vue组件:全局注册和局部注册,就好像欧元和英镑的区别,前者能够在各Vue实例中使用,后者只能在注册他的Vue实例或者父组件中使用。若是在组件中使用组件,就造成了组件的嵌套,若是组件里嵌套的组件是本身,就造成组件的递归。es6
总之:组件由两部分构成,github
一部分是须要自定义的tag-name,如下面为例,tagname是<my-component>,数组
另外一部分是options对象,里面包含了该组件的模板,方法,props,data等细节浏览器
全局注册:
Vue.component('my-component', { // 选项 })
局部注册:
var options={template:....}//组件的选项对象 new Vue({ el:'#man', components:{ 'my-component',options } });
将组件挂载到已存在元素上时,遇到某些元素,会发生尴尬的事情:如<ul> , <ol>
, <table>
,<select>这些标签,他们只认识<li>,<tr>,<option>这些标签,想把<my-component>插进去,人家不认识,这时就要is发挥做用了:
<ul> <my-component></my-component> </ul>
上面这样浏览器不给面子,须要变成这样:
<ul> <li is='my-component'></li> </ul>
当使用单文件组件时,就当上面是废话,也就是说<ul>中能够有组件了。(见这里)动态组件也有一个is属性,用来切换不一样的组件,咱们下面再说
下面说说我以为组件中的三个重点:prop,events和slots。当我看到组件这部分时,以前没有接触过mvvm类型的框架,因此到这里感受是极限了,这时,找到熟悉的事物做类比是一个好办法。若是把组件比成一间房子,上面的三只就是房子用来和外界通讯的门窗。
在开始以前:应该记住一张图和一句话:
这张图对应的意思是:父组件经过 props 向下传递数据给子组件,子组件经过 events 给父组件发送消息。
想象一个场景。2048游戏里面,两个子组件中的数据合并了,产生一个addscore事件,须要通知父组件容器,这时,就能够用自定义事件了:
//父组件中 <father v-on:addscore="addscore"></father> function addscore(){ this.score++; } //子组件中 this.$emit('addscore');
注意 ,在子组件中,子组件只负责触发这个自定义事件,经过$emit方法来触发,而在父组件中则定义事件触发以后的回调函数。好吧,其实vue官方教程的两个button触发add事件看起来是个更好的例子。。。。
再想象一个场景,2048中,父组件中的data中有一个定义了全部card的值的数组,如今要把这些值传到每个card中,这时就用到props:
//爹组件 //在模板中,为子组件写一个自定义属性card,用来把cardNum传给子组件 <children :card="card_num"></children> data:{card_num:8} //****子组件中****** <div>{{card}}</div> 在组件的props字段中加入子组件的自定义属性 { data:.... computed:.... props:{card:null} }
其实理解起来很简单,vue的子组件对父组件来讲被包装成为一个相似于<children></children>的标签,正如你在父组件中看到的那样。可是vue为咱们留了一个props属性,就像上帝给人类五官用来感觉世界同样,组件用props和自定义事件用来和父组件传递消息。
这也是一种封装,对父组件隐藏了内部的实现,只留下了props做为接口。接口在现实世界也很常见,好比显示器对主机的接口,你没必要管显示器的内部实现,只要知道接上主机就能显示信息了就行。
若是你了解过es6的模板字符串,那么理解起这个来将绝不费劲。我当时但是被这个slots搞得稀里糊涂的。。。固然当时不知道模板引擎,也不知道模板字符串。slots就是在组件中插入内容的机制。
在<p>等原生的标签里插入内容很简单,就直接写就好了(说了一句废话),而在组件中写入内容就有讲究了,好比<children>我仍是个宝宝</children>,因为组件的模板通常是一堆原生标签一块儿构成的,那么上面这么写,究竟应该把内容插到那个元素中就成了问题。因而就有了<slot></slot>元素。
solt元素就是用来接受父组件放到子组件的内容的。不知为何,到了这里我会想起学习机上插游戏卡的例子。。。举个例子:
//学习机组件 <div> <h2>小霸王学习机</h2> <slot> 内置魂斗罗 </slot> </div>
//小朋友父组件 <div> <h1>我要玩游戏</h1> <xue-xi-ji> <p>插入双截龙游戏卡</p>//插入的内容 </xue-xi-ji> </div>
最后获得的就是小学生愉快的玩双截龙了
<div> <h1>我要玩游戏</h1> -------------------------------组件区域—————————————— <h2>小霸王学习机</h2> ————————slot区域—————————————— <p>插入双截龙游戏卡</p>//插入的内容 </div>
当父组件不往子组件标签中添加任何字符时,子组件会显示默认内容,若是有的话,也就是说魂斗罗。。
具名slot是说组件中有大于一个地方须要插值时,须要给slot取个名字。就像电脑的接口,有usb的,也有接投影的HDMI接口,为的是将多条内容放到正确的地方。
咱们知道,在组件内部,this指向组件本身,那么组件的slot内容能够经过this.$slots得到被插入的vnode节点。
动态组件就是为了适应页面的局部刷新而生的,举个我用过的例子:todolist在线小demo
当我点击写日记button时,页面会变成一个markdown编辑器界面。这就是动态组件。实现的代码以下
<keep-alive> <compoment v-bind:is='currentview'></compoment> </keep-alive>
methods: { toggleview: function() { this.currentview = (this.currentview == 'todolist') ? 'write' : 'todolist'; } },
当我点击上面的button时,触发toggleview方法,致使is绑定的组件名发生变化,若是当前是write组件,那么变成todolist组件。
那么<keep-alive>标签又有什么用呢?标签字面意思是活着。。就是当todolist组件由显示变成隐藏时,组件的数据状态会被保存下来而不是被彻底destory,当组件由隐藏再次变为显示时,当前的状态得以保留。比方你在write组件中写一段md文档,而后切换回todolist组件,若是没有keep-alive组件,再切换回write组件时,以前编辑的东西就会丢失。