前言
组件(Component)是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码。在较高层面上,组件是自定义元素,Vue.js 的编译器为它添加特殊功能。在有些情况下,组件也可以是原生 HTML 元素的形式,以 is 特性扩展。
组件开发的基础
组件可以扩展 HTML 元素,封装可重用的代码。我理解为功能模块的模板吧。
对于vue来说,组件是这个样子的,我们在html里面写
<div id="example"> <my-component></my-component> </div>edx</div>
然后就出来
<div id="example"> <div>A custom component!</div> </div></div>
代码 <div>A custom component!</div>我们只要写一遍就行了 。
所以我们需要定义它,把 my-component的标签和代码关联起来,所以我们要定义它
// 定义
var MyComponent = Vue.extend({
 template: '<div>A custom component!</div>'
})
</div>
定义了之后,我们要让页面能够渲染它,让Vue知道它的存在
// 注册
 Vue.component('my-component', MyComponent)
// 创建根实例
new Vue({
 el: '#example'
})
</div>
以上,是官网一个非常简单的例子 ,其实觉得和一个function的封装也差不多,定义,引入,然后执行。
然后一个组件可以引用别的组件的东西,有点像函数的互相调用啊。
var Child = Vue.extend({ /* ... */ })
var Parent = Vue.extend({
 template: '...',
 components: {
 // <my-component> 只能用在父组件模板内
 'my-component': Child
 }
})
</div>
一个表格组件的实例
这是官网的例子

这个是一个可以排序的表格的例子。我们从头开始来制作一个可以排序的表格。
基本结构
首先分成两个部分,一个是搜索框,一个是表格本身,我们可以得到这样的结构
<div id="demo"> <form id="search"> Search <input name="query"> </form> <table> <thead> <tr> <th>name</th> <th>power</th> </tr> </thead> <tbody> <tr> <td>Jack Chan</td> <td>7000</td> </tr> </tbody> </table> </div></div>
显示效果

加上基本的css
body {
 font-family: Helvetica Neue, Arial, sans-serif;
 font-size: 14px;
 color: #444;
}
table {
 border: 2px solid #42b983;
 border-radius: 3px;
 background-color: #fff;
}
th {
 background-color: #42b983;
 color: rgba(255,255,255,0.66);
 cursor: pointer;
 -webkit-user-select: none;
 -moz-user-select: none;
 -user-select: none;
}
td {
 background-color: #f9f9f9;
}
th, td {
 min-width: 120px;
 padding: 10px 20px;
}
#search {
 margin-bottom: 10px;
}
</div>
显示效果如下,

提取组件
我们是想要让表格成为单独的组件,所以我们定义一个叫做 demo-grid的组件,用它来生成表格
<div id="demo"> <form id="search"> Search <input name="query" > </form> <demo-grid> </demo-grid> </div></div>
代码里面关于表格的那部分给放到组件模板里面,我们定义组件。也就是用script来定义,
<script type="text/x-template" id="grid-template"> <table> <thead> <tr> <th>name</th> <th>power</th> </tr> </thead> <tbody> <tr> <td>Jack Chan</td> <td>7000</td> </tr> </tbody> </table> </script></div>
定义完了之后我们要在给Vue注册组件模块,然后进行Vue的渲染
 Vue.component('demo-grid',{
 template:"#grid-template",
 });
 var demo = new Vue({
 el:'#demo'
 })
</div>
然后最后的效果是一样的,这个时候并没有数据流。
组件数据流
我们要让表格知道表格的头部和表格的内容,也就是有一个gridColumns和gridData,这个数据最开始放在Vue的Data里面
 // bootstrap the demo
 var demo = new Vue({
 el: '#demo',
 data: {
  gridColumns: ['name', 'power'],
  gridData: [
  { name: 'Chuck Norris', power: Infinity },
  { name: 'Bruce Lee', power: 9000 },
  { name: 'Jackie Chan', power: 7000 },
  { name: 'Jet Li', power: 8000 }
  ]
 }
 })
</div>
然后我们的组件也要接受这个数据,这里我们通过类似属性的形式给组件模板传入数据,
<demo-grid :data="gridData" :columns="gridColumns"> </demo-grid></div>
然后我们在组件里面把相应的数据继承下来。
 Vue.component('demo-grid',{
 template:"#grid-template",
 props: {
  data: Array,
  columns: Array
 }
 });
</div>
然后在模板里面替换掉
<script type="text/x-template" id="grid-template">
 <table>
 <thead>
 <tr>
  <th v-for="key in columns">{{key}}</th>
 </tr>
 </thead>
 <tbody>
 <tr v-for="entry in data">
  <td v-for="key in columns">{{entry[key]}}</td>
 </tr>
 </tbody>
 </table>
</script>
</div>
效果如下

搜索功能增加
这个时候,我们想加入一个交互,也就是在搜索框增加关键词的时候,表格能够相应地变化。
首先我们要绑定搜索框的模型,也就是用searchQuery来绑定Input
<form id="search"> Search <input name="query" v-model="searchQuery"> </form></div>
在Vue里面增加data的初始化
 var demo = new Vue({
 el: '#demo',
 data: {
  searchQuery: '',
  ...
 })
</div>
同时,在组件模板里面也进行参数传入
<demo-grid :data="gridData" :columns="gridColumns" :filter-key="searchQuery"> </demo-grid></div>
组件的定义里面要继承模板的数据,也就是在模板里面是filter-key,注意要转化驼峰写法
 Vue.component('demo-grid', {
 template: '#grid-template',
 props: {
  data: Array,
  columns: Array,
  filterKey: String
 }
})
</div>
这个时候,我们的模板里面要过滤符合filterKey的数据,这里就用到了过滤器,vue提供了一个叫做filterBy的过滤器。|与过滤器,第一个为过滤器的名字,后面的是参数

