分析vuejs官網(wǎng)上一個(gè)表格組件的實(shí)現(xiàn)過程颁独。
原址:https://cn.vuejs.org/v2/examples/grid-component.html
1掏湾、新建一個(gè)demo和vue實(shí)例
<!--html-->
<div id="demo"></div>
//js
var demo=new Vue({
el:"#demo"
});
2锡垄、新建一個(gè)Vue實(shí)例静稻,并用data聲明一個(gè)數(shù)據(jù)對象睹耐,定義表格所需的數(shù)據(jù)
var demo=new Vue({
el:"#demo",
data:{
//表格的頭部部分?jǐn)?shù)據(jù)
gridColumns: ['name', 'power'],
//表格的主體部分?jǐn)?shù)據(jù)
gridData: [
{ name: 'Chuck Norris', power: Infinity },
{ name: 'Bruce Lee', power: 9000 },
{ name: 'Jackie Chan', power: 7000 },
{ name: 'Jet Li', power: 8000 }
],
//input組件中v-model雙向綁定的數(shù)據(jù)值
searchQuery : ''
}
});
3糊探、注冊一個(gè)子組件組件demo-grid挎狸,并在父實(shí)例的模塊中以自定義元素<demo-grid></demo-grid>的形式使用
要讓子組件使用父組件的數(shù)據(jù)扣汪,我們需要通過props選項(xiàng)。子組件要顯式的用props選項(xiàng)聲明它期待獲得的數(shù)據(jù)
<!--html-->
<div id="demo">
<!--搜索框-->
<form id="search">
<!--用v-model實(shí)現(xiàn)了input輸入框數(shù)據(jù)的雙向綁定-->
Search <input name="query" v-model="searchQuery">
</form>
<!--表格-->
<demo-grid
<!--這里是綁定了幾個(gè)自定義屬性伟叛,屬性值為Vue實(shí)例data中的數(shù)據(jù)值-->
:data="gridData"
:columns="gridColumns"
:filter-key="searchQuery"
></demo-grid>
</div>
//js 創(chuàng)建一個(gè)子組件
Vue.component("demo-grid",{
template:"#grid-template",
props: {
//獲得父組件的數(shù)據(jù)并定義了數(shù)據(jù)類型
data: Array,
columns: Array,
filterKey: String
},
});
4私痹、X-template
定義模版的方式:在 JavaScript 標(biāo)簽里使用 text/x-template 類型,并且指定一個(gè) id="grid-template"统刮,所定義的就相當(dāng)于上文子組件中template的內(nèi)容
<!--html-->
<!--X-template定義的模板放到html標(biāo)簽中-->
<script type="text/x-template" id="grid-template">
<table>
<thead>
<tr>
<th
<!--遍歷columns數(shù)組(即:["name","power"])紊遵,取出每一項(xiàng)-->
v-for="key in columns"
<!--注冊一個(gè)click事件,事件函數(shù)為sortBy并將點(diǎn)擊的相應(yīng)的鍵值傳參到函數(shù)里面去-->
@click="sortBy(key)"
<!--如果兩者相等侥蒙,則應(yīng)用active樣式-->
:class="{ active: sortKey == key }"
>
<!--使用capitalize過濾值-->
{{ key | capitalize }}
<!--箭頭符號樣式-->
<span class="arrow" :class="sortOrders[key] > 0 ? 'asc' : 'dsc'"></span>
</th>
</tr>
</thead>
<tbody>
<!--遍歷計(jì)算屬性中filteredData計(jì)算后返回的data值-->
<tr v-for="entry in filteredData">
<td v-for="key in columns">
{{entry[key]}}
</td>
</tr>
</tbody
</table>
</script>
5暗膜、為子組件(demo-grid)繼續(xù)添加選項(xiàng)對象
①data
定義子組件內(nèi)部的數(shù)據(jù)對象。
子組件這里的data必須是一個(gè)函數(shù)鞭衩。
data: function () {
//定義一個(gè)sortOrders空對象
var sortOrders = {};
//遍歷columns值(也就是父組件中的數(shù)據(jù)值['name', 'power']),將每一項(xiàng)的值設(shè)為1学搜,即:{name:1,power:1}
this.columns.forEach(function (key) {
sortOrders[key] = 1
});
//返回一個(gè)空字符串值sortKey(下文會講作用)和sortOrders對象
return {
sortKey: '',
sortOrders: sortOrders
};
},
②methods方法
methods: {
//當(dāng)在父組件tr那里點(diǎn)擊了click事件,就會調(diào)用這個(gè)函數(shù)
sortBy: function (key) {
this.sortKey = key
this.sortOrders[key] = this.sortOrders[key] * -1
}
}
③computed計(jì)算屬性
computed: {
filteredData: function () {
var sortKey = this.sortKey
var filterKey = this.filterKey && this.filterKey.toLowerCase()
var order = this.sortOrders[sortKey] || 1
var data = this.data
if (filterKey) {
/*原本的data數(shù)據(jù)值
* data:[
* { name: 'Chuck Norris', power: Infinity },
* { name: 'Bruce Lee', power: 9000 },
* { name: 'Jackie Chan', power: 7000 },
* { name: 'Jet Li', power: 8000 }
* ]
*/
//filter函數(shù)方法會篩選出data數(shù)組中為true的項(xiàng)
data = data.filter(function (row) {
//然后將里面的每一項(xiàng)(也就是對象)中的鍵值進(jìn)行與輸入的filterKey值進(jìn)行匹配搜索论衍,
//大于-1則將該項(xiàng)返回組成新的data
return Object.keys(row).some(function (key) {
return String(row[key]).toLowerCase().indexOf(filterKey) > -1
})
})
}
if (sortKey) {
//復(fù)制一份data數(shù)據(jù)瑞佩,然后進(jìn)行sort排序,組成新的表格排序
data = data.slice().sort(function (a, b) {
a = a[sortKey]
b = b[sortKey]
return (a === b ? 0 : a > b ? 1 : -1) * order
})
}
return data
}
},
④filters
filters: {
capitalize: function (str) {
return str.charAt(0).toUpperCase() + str.slice(1)
}
}
6坯台、最后子組件就是這樣:
Vue.component('demo-grid', {
template: '#grid-template',
props: {
data: Array,
columns: Array,
filterKey: String
},
data: function () {
var sortOrders = {}
this.columns.forEach(function (key) {
sortOrders[key] = 1
})
return {
sortKey: '',
sortOrders: sortOrders
}
},
computed: {
filteredData: function () {
var sortKey = this.sortKey
var filterKey = this.filterKey && this.filterKey.toLowerCase()
var order = this.sortOrders[sortKey] || 1
var data = this.data
if (filterKey) {
data = data.filter(function (row) {
return Object.keys(row).some(function (key) {
return String(row[key]).toLowerCase().indexOf(filterKey) > -1
})
})
}
if (sortKey) {
data = data.slice().sort(function (a, b) {
a = a[sortKey]
b = b[sortKey]
return (a === b ? 0 : a > b ? 1 : -1) * order
})
}
return data
}
},
filters: {
capitalize: function (str) {
return str.charAt(0).toUpperCase() + str.slice(1)
}
},
methods: {
sortBy: function (key) {
this.sortKey = key
this.sortOrders[key] = this.sortOrders[key] * -1
}
}
})